Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2020-02-02 14:04:19 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2020-02-07 14:18:15 +0300
commitd9c5f0d25fc91b069158ae1ab4fddc21bfd85846 (patch)
tree18f55163c5b06385d055d5a79a4c653d3da6e595 /intern/cycles/render/object.cpp
parent46c9872afaa8053f8b2894c038402b1beb3ac66c (diff)
Cleanup: split Cycles Hair and Mesh classes, with Geometry base class
Diffstat (limited to 'intern/cycles/render/object.cpp')
-rw-r--r--intern/cycles/render/object.cpp240
1 files changed, 99 insertions, 141 deletions
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 849329a086d..4987b6089d7 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -16,6 +16,7 @@
#include "render/camera.h"
#include "device/device.h"
+#include "render/hair.h"
#include "render/light.h"
#include "render/mesh.h"
#include "render/curves.h"
@@ -87,7 +88,7 @@ NODE_DEFINE(Object)
{
NodeType *type = NodeType::add("object", create);
- SOCKET_NODE(mesh, "Mesh", &Mesh::node_type);
+ SOCKET_NODE(geometry, "Geometry", &Geometry::node_base_type);
SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
SOCKET_UINT(visibility, "Visibility", ~0);
SOCKET_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
@@ -152,7 +153,7 @@ void Object::update_motion()
void Object::compute_bounds(bool motion_blur)
{
- BoundBox mbounds = mesh->bounds;
+ BoundBox mbounds = geometry->bounds;
if (motion_blur && use_motion()) {
array<DecomposedTransform> decomp(motion.size());
@@ -172,7 +173,7 @@ void Object::compute_bounds(bool motion_blur)
}
else {
/* No motion blur case. */
- if (mesh->transform_applied) {
+ if (geometry->transform_applied) {
bounds = mbounds;
}
else {
@@ -183,89 +184,18 @@ void Object::compute_bounds(bool motion_blur)
void Object::apply_transform(bool apply_to_motion)
{
- if (!mesh || tfm == transform_identity())
+ if (!geometry || tfm == transform_identity())
return;
- /* triangles */
- if (mesh->verts.size()) {
- /* store matrix to transform later. when accessing these as attributes we
- * do not want the transform to be applied for consistency between static
- * and dynamic BVH, so we do it on packing. */
- mesh->transform_normal = transform_transposed_inverse(tfm);
-
- /* apply to mesh vertices */
- for (size_t i = 0; i < mesh->verts.size(); i++)
- mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
-
- if (apply_to_motion) {
- Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if (attr) {
- size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
- float3 *vert_steps = attr->data_float3();
-
- for (size_t i = 0; i < steps_size; i++)
- vert_steps[i] = transform_point(&tfm, vert_steps[i]);
- }
-
- Attribute *attr_N = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
-
- if (attr_N) {
- Transform ntfm = mesh->transform_normal;
- size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
- float3 *normal_steps = attr_N->data_float3();
-
- for (size_t i = 0; i < steps_size; i++)
- normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
- }
- }
- }
-
- /* curves */
- if (mesh->curve_keys.size()) {
- /* compute uniform scale */
- float3 c0 = transform_get_column(&tfm, 0);
- float3 c1 = transform_get_column(&tfm, 1);
- float3 c2 = transform_get_column(&tfm, 2);
- float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f / 3.0f);
-
- /* apply transform to curve keys */
- for (size_t i = 0; i < mesh->curve_keys.size(); i++) {
- float3 co = transform_point(&tfm, mesh->curve_keys[i]);
- float radius = mesh->curve_radius[i] * scalar;
-
- /* scale for curve radius is only correct for uniform scale */
- mesh->curve_keys[i] = co;
- mesh->curve_radius[i] = radius;
- }
-
- if (apply_to_motion) {
- Attribute *curve_attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if (curve_attr) {
- /* apply transform to motion curve keys */
- size_t steps_size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
- float4 *key_steps = curve_attr->data_float4();
-
- for (size_t i = 0; i < steps_size; i++) {
- float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
- float radius = key_steps[i].w * scalar;
-
- /* scale for curve radius is only correct for uniform scale */
- key_steps[i] = float3_to_float4(co);
- key_steps[i].w = radius;
- }
- }
- }
- }
+ geometry->apply_transform(tfm, apply_to_motion);
/* we keep normals pointing in same direction on negative scale, notify
- * mesh about this in it (re)calculates normals */
+ * geometry about this in it (re)calculates normals */
if (transform_negative_scale(tfm))
- mesh->transform_negative_scaled = true;
+ geometry->transform_negative_scaled = true;
if (bounds.valid()) {
- mesh->compute_bounds();
+ geometry->compute_bounds();
compute_bounds(false);
}
@@ -275,11 +205,11 @@ void Object::apply_transform(bool apply_to_motion)
void Object::tag_update(Scene *scene)
{
- if (mesh) {
- if (mesh->transform_applied)
- mesh->need_update = true;
+ if (geometry) {
+ if (geometry->transform_applied)
+ geometry->need_update = true;
- foreach (Shader *shader, mesh->used_shaders) {
+ foreach (Shader *shader, geometry->used_shaders) {
if (shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
}
@@ -287,7 +217,7 @@ void Object::tag_update(Scene *scene)
scene->camera->need_flags_update = true;
scene->curve_system_manager->need_update = true;
- scene->mesh_manager->need_update = true;
+ scene->geometry_manager->need_update = true;
scene->object_manager->need_update = true;
}
@@ -353,32 +283,22 @@ ObjectManager::~ObjectManager()
{
}
-void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
+static float object_surface_area(UpdateObjectTransformState *state,
+ const Transform &tfm,
+ Geometry *geom)
{
- KernelObject &kobject = state->objects[ob->index];
- Transform *object_motion_pass = state->object_motion_pass;
-
- Mesh *mesh = ob->mesh;
- uint flag = 0;
-
- /* Compute transformations. */
- Transform tfm = ob->tfm;
- Transform itfm = transform_inverse(tfm);
+ if (geom->type != Geometry::MESH) {
+ return 0.0f;
+ }
/* Compute surface area. for uniform scale we can do avoid the many
* transform calls and share computation for instances.
*
* TODO(brecht): Correct for displacement, and move to a better place.
*/
- float uniform_scale;
+ Mesh *mesh = static_cast<Mesh *>(geom);
float surface_area = 0.0f;
- float3 color = ob->color;
- float pass_id = ob->pass_id;
- float random_number = (float)ob->random_id * (1.0f / (float)0xFFFFFFFF);
- int particle_index = (ob->particle_system) ?
- ob->particle_index + state->particle_offset[ob->particle_system] :
- 0;
-
+ float uniform_scale;
if (transform_uniform_scale(tfm, uniform_scale)) {
map<Mesh *, float>::iterator it;
@@ -424,9 +344,31 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
}
}
+ return surface_area;
+}
+
+void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
+{
+ KernelObject &kobject = state->objects[ob->index];
+ Transform *object_motion_pass = state->object_motion_pass;
+
+ Geometry *geom = ob->geometry;
+ uint flag = 0;
+
+ /* Compute transformations. */
+ Transform tfm = ob->tfm;
+ Transform itfm = transform_inverse(tfm);
+
+ float3 color = ob->color;
+ float pass_id = ob->pass_id;
+ float random_number = (float)ob->random_id * (1.0f / (float)0xFFFFFFFF);
+ int particle_index = (ob->particle_system) ?
+ ob->particle_index + state->particle_offset[ob->particle_system] :
+ 0;
+
kobject.tfm = tfm;
kobject.itfm = itfm;
- kobject.surface_area = surface_area;
+ kobject.surface_area = object_surface_area(state, tfm, geom);
kobject.color[0] = color.x;
kobject.color[1] = color.y;
kobject.color[2] = color.z;
@@ -435,11 +377,16 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.particle_index = particle_index;
kobject.motion_offset = 0;
- if (mesh->use_motion_blur) {
+ if (geom->use_motion_blur) {
state->have_motion = true;
}
- if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
- flag |= SD_OBJECT_HAS_VERTEX_MOTION;
+
+ if (geom->type == Geometry::MESH) {
+ /* TODO: why only mesh? */
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
+ flag |= SD_OBJECT_HAS_VERTEX_MOTION;
+ }
}
if (state->need_motion == Scene::MOTION_PASS) {
@@ -460,7 +407,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
/* Motion transformations, is world/object space depending if mesh
* comes with deformed position in object space, or if we transform
* the shading point in world space. */
- if (!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
+ if (!(flag & SD_OBJECT_HAS_VERTEX_MOTION)) {
tfm_pre = tfm_pre * itfm;
tfm_post = tfm_post * itfm;
}
@@ -485,12 +432,13 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.dupli_generated[0] = ob->dupli_generated[0];
kobject.dupli_generated[1] = ob->dupli_generated[1];
kobject.dupli_generated[2] = ob->dupli_generated[2];
- kobject.numkeys = mesh->curve_keys.size();
+ kobject.numkeys = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom)->curve_keys.size() :
+ 0;
kobject.dupli_uv[0] = ob->dupli_uv[0];
kobject.dupli_uv[1] = ob->dupli_uv[1];
- int totalsteps = mesh->motion_steps;
+ int totalsteps = geom->motion_steps;
kobject.numsteps = (totalsteps - 1) / 2;
- kobject.numverts = mesh->verts.size();
+ kobject.numverts = (geom->type == Geometry::MESH) ? static_cast<Mesh *>(geom)->verts.size() : 0;
kobject.patch_map_offset = 0;
kobject.attribute_map_offset = 0;
uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
@@ -505,7 +453,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
state->object_flag[ob->index] = flag;
/* Have curves. */
- if (mesh->num_curves()) {
+ if (geom->type == Geometry::HAIR) {
state->have_curves = true;
}
}
@@ -681,7 +629,7 @@ void ObjectManager::device_update_flags(
vector<Object *> volume_objects;
bool has_volume_objects = false;
foreach (Object *object, scene->objects) {
- if (object->mesh->has_volume) {
+ if (object->geometry->has_volume) {
if (bounds_valid) {
volume_objects.push_back(object);
}
@@ -690,11 +638,11 @@ void ObjectManager::device_update_flags(
}
foreach (Object *object, scene->objects) {
- if (object->mesh->has_volume) {
+ if (object->geometry->has_volume) {
object_flag[object->index] |= SD_OBJECT_HAS_VOLUME;
object_flag[object->index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
- foreach (Attribute &attr, object->mesh->attributes.attributes) {
+ foreach (Attribute &attr, object->geometry->attributes.attributes) {
if (attr.element == ATTR_ELEMENT_VOXEL) {
object_flag[object->index] |= SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
}
@@ -744,21 +692,24 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc
bool update = false;
foreach (Object *object, scene->objects) {
- Mesh *mesh = object->mesh;
-
- if (mesh->patch_table) {
- uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() -
- mesh->patch_table->num_nodes * PATCH_NODE_SIZE) -
- mesh->patch_offset;
-
- if (kobjects[object->index].patch_map_offset != patch_map_offset) {
- kobjects[object->index].patch_map_offset = patch_map_offset;
- update = true;
+ Geometry *geom = object->geometry;
+
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ if (mesh->patch_table) {
+ uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() -
+ mesh->patch_table->num_nodes * PATCH_NODE_SIZE) -
+ mesh->patch_offset;
+
+ if (kobjects[object->index].patch_map_offset != patch_map_offset) {
+ kobjects[object->index].patch_map_offset = patch_map_offset;
+ update = true;
+ }
}
}
- if (kobjects[object->index].attribute_map_offset != mesh->attr_map_offset) {
- kobjects[object->index].attribute_map_offset = mesh->attr_map_offset;
+ if (kobjects[object->index].attribute_map_offset != geom->attr_map_offset) {
+ kobjects[object->index].attribute_map_offset = geom->attr_map_offset;
update = true;
}
}
@@ -779,10 +730,10 @@ void ObjectManager::device_free(Device *, DeviceScene *dscene)
void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
{
/* todo: normals and displacement should be done before applying transform! */
- /* todo: create objects/meshes in right order! */
+ /* todo: create objects/geometry in right order! */
- /* counter mesh users */
- map<Mesh *, int> mesh_users;
+ /* counter geometry users */
+ map<Geometry *, int> geometry_users;
Scene::MotionType need_motion = scene->need_motion();
bool motion_blur = need_motion == Scene::MOTION_BLUR;
bool apply_to_motion = need_motion != Scene::MOTION_PASS;
@@ -790,10 +741,10 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
bool have_instancing = false;
foreach (Object *object, scene->objects) {
- map<Mesh *, int>::iterator it = mesh_users.find(object->mesh);
+ map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
- if (it == mesh_users.end())
- mesh_users[object->mesh] = 1;
+ if (it == geometry_users.end())
+ geometry_users[object->geometry] = 1;
else
it->second++;
}
@@ -803,27 +754,34 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
uint *object_flag = dscene->object_flag.data();
- /* apply transforms for objects with single user meshes */
+ /* apply transforms for objects with single user geometry */
foreach (Object *object, scene->objects) {
/* Annoying feedback loop here: we can't use is_instanced() because
* it'll use uninitialized transform_applied flag.
*
- * Could be solved by moving reference counter to Mesh.
+ * Could be solved by moving reference counter to Geometry.
*/
- if ((mesh_users[object->mesh] == 1 && !object->mesh->has_surface_bssrdf) &&
- !object->mesh->has_true_displacement() &&
- object->mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
+ Geometry *geom = object->geometry;
+ bool apply = (geometry_users[geom] == 1) && !geom->has_surface_bssrdf &&
+ !geom->has_true_displacement();
+
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ apply = apply && mesh->subdivision_type == Mesh::SUBDIVISION_NONE;
+ }
+
+ if (apply) {
if (!(motion_blur && object->use_motion())) {
- if (!object->mesh->transform_applied) {
+ if (!geom->transform_applied) {
object->apply_transform(apply_to_motion);
- object->mesh->transform_applied = true;
+ geom->transform_applied = true;
if (progress.get_cancel())
return;
}
object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
- if (object->mesh->transform_negative_scaled)
+ if (geom->transform_negative_scaled)
object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
}
else
@@ -842,7 +800,7 @@ void ObjectManager::tag_update(Scene *scene)
{
need_update = true;
scene->curve_system_manager->need_update = true;
- scene->mesh_manager->need_update = true;
+ scene->geometry_manager->need_update = true;
scene->light_manager->need_update = true;
}