Merge branch 'master' into blender2.8
[blender.git] / intern / cycles / render / object.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "render/camera.h"
18 #include "device/device.h"
19 #include "render/light.h"
20 #include "render/mesh.h"
21 #include "render/curves.h"
22 #include "render/object.h"
23 #include "render/particles.h"
24 #include "render/scene.h"
25
26 #include "util/util_foreach.h"
27 #include "util/util_logging.h"
28 #include "util/util_map.h"
29 #include "util/util_progress.h"
30 #include "util/util_set.h"
31 #include "util/util_vector.h"
32 #include "util/util_murmurhash.h"
33
34 #include "subd/subd_patch_table.h"
35
36 CCL_NAMESPACE_BEGIN
37
38 /* Global state of object transform update. */
39
40 struct UpdateObjectTransformState {
41         /* Global state used by device_update_object_transform().
42          * Common for both threaded and non-threaded update.
43          */
44
45         /* Type of the motion required by the scene settings. */
46         Scene::MotionType need_motion;
47
48         /* Mapping from particle system to a index in packed particle array.
49          * Only used for read.
50          */
51         map<ParticleSystem*, int> particle_offset;
52
53         /* Mesh area.
54          * Used to avoid calculation of mesh area multiple times. Used for both
55          * read and write. Acquire surface_area_lock to keep it all thread safe.
56          */
57         map<Mesh*, float> surface_area_map;
58
59         /* Motion offsets for each object. */
60         array<uint> motion_offset;
61
62         /* Packed object arrays. Those will be filled in. */
63         uint *object_flag;
64         KernelObject *objects;
65         Transform *object_motion_pass;
66         DecomposedTransform *object_motion;
67
68         /* Flags which will be synchronized to Integrator. */
69         bool have_motion;
70         bool have_curves;
71
72         /* ** Scheduling queue. ** */
73
74         Scene *scene;
75
76         /* Some locks to keep everything thread-safe. */
77         thread_spin_lock queue_lock;
78         thread_spin_lock surface_area_lock;
79
80         /* First unused object index in the queue. */
81         int queue_start_object;
82 };
83
84 /* Object */
85
86 NODE_DEFINE(Object)
87 {
88         NodeType* type = NodeType::add("object", create);
89
90         SOCKET_NODE(mesh, "Mesh", &Mesh::node_type);
91         SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
92         SOCKET_UINT(visibility, "Visibility", ~0);
93         SOCKET_UINT(random_id, "Random ID", 0);
94         SOCKET_INT(pass_id, "Pass ID", 0);
95         SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
96         SOCKET_BOOLEAN(hide_on_missing_motion, "Hide on Missing Motion", false);
97         SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f));
98         SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f));
99         SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
100
101         SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false);
102
103         return type;
104 }
105
106 Object::Object()
107 : Node(node_type)
108 {
109         particle_system = NULL;
110         particle_index = 0;
111         bounds = BoundBox::empty;
112 }
113
114 Object::~Object()
115 {
116 }
117
118 void Object::update_motion()
119 {
120         if(!use_motion()) {
121                 return;
122         }
123
124         bool have_motion = false;
125
126         for(size_t i = 0; i < motion.size(); i++) {
127                 if(motion[i] == transform_empty()) {
128                         if(hide_on_missing_motion) {
129                                 /* Hide objects that have no valid previous or next
130                                  * transform, for example particle that stop existing. It
131                                  * would be better to handle this in the kernel and make
132                                  * objects invisible outside certain motion steps. */
133                                 tfm = transform_empty();
134                                 motion.clear();
135                                 return;
136                         }
137                         else {
138                                 /* Otherwise just copy center motion. */
139                                 motion[i] = tfm;
140                         }
141                 }
142
143                 /* Test if any of the transforms are actually different. */
144                 have_motion = have_motion || motion[i] != tfm;
145         }
146
147         /* Clear motion array if there is no actual motion. */
148         if(!have_motion) {
149                 motion.clear();
150         }
151 }
152
153 void Object::compute_bounds(bool motion_blur)
154 {
155         BoundBox mbounds = mesh->bounds;
156
157         if(motion_blur && use_motion()) {
158                 array<DecomposedTransform> decomp(motion.size());
159                 transform_motion_decompose(decomp.data(), motion.data(), motion.size());
160
161                 bounds = BoundBox::empty;
162
163                 /* todo: this is really terrible. according to pbrt there is a better
164                  * way to find this iteratively, but did not find implementation yet
165                  * or try to implement myself */
166                 for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
167                         Transform ttfm;
168
169                         transform_motion_array_interpolate(&ttfm, decomp.data(), motion.size(), t);
170                         bounds.grow(mbounds.transformed(&ttfm));
171                 }
172         }
173         else {
174                 /* No motion blur case. */
175                 if(mesh->transform_applied) {
176                         bounds = mbounds;
177                 }
178                 else {
179                         bounds = mbounds.transformed(&tfm);
180                 }
181         }
182 }
183
184 void Object::apply_transform(bool apply_to_motion)
185 {
186         if(!mesh || tfm == transform_identity())
187                 return;
188
189         /* triangles */
190         if(mesh->verts.size()) {
191                 /* store matrix to transform later. when accessing these as attributes we
192                  * do not want the transform to be applied for consistency between static
193                  * and dynamic BVH, so we do it on packing. */
194                 mesh->transform_normal = transform_transposed_inverse(tfm);
195
196                 /* apply to mesh vertices */
197                 for(size_t i = 0; i < mesh->verts.size(); i++)
198                         mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
199
200                 if(apply_to_motion) {
201                         Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
202
203                         if(attr) {
204                                 size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
205                                 float3 *vert_steps = attr->data_float3();
206
207                                 for(size_t i = 0; i < steps_size; i++)
208                                         vert_steps[i] = transform_point(&tfm, vert_steps[i]);
209                         }
210
211                         Attribute *attr_N = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
212
213                         if(attr_N) {
214                                 Transform ntfm = mesh->transform_normal;
215                                 size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
216                                 float3 *normal_steps = attr_N->data_float3();
217
218                                 for(size_t i = 0; i < steps_size; i++)
219                                         normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
220                         }
221                 }
222         }
223
224         /* curves */
225         if(mesh->curve_keys.size()) {
226                 /* compute uniform scale */
227                 float3 c0 = transform_get_column(&tfm, 0);
228                 float3 c1 = transform_get_column(&tfm, 1);
229                 float3 c2 = transform_get_column(&tfm, 2);
230                 float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f/3.0f);
231
232                 /* apply transform to curve keys */
233                 for(size_t i = 0; i < mesh->curve_keys.size(); i++) {
234                         float3 co = transform_point(&tfm, mesh->curve_keys[i]);
235                         float radius = mesh->curve_radius[i] * scalar;
236
237                         /* scale for curve radius is only correct for uniform scale */
238                         mesh->curve_keys[i] = co;
239                         mesh->curve_radius[i] = radius;
240                 }
241
242                 if(apply_to_motion) {
243                         Attribute *curve_attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
244
245                         if(curve_attr) {
246                                 /* apply transform to motion curve keys */
247                                 size_t steps_size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
248                                 float4 *key_steps = curve_attr->data_float4();
249
250                                 for(size_t i = 0; i < steps_size; i++) {
251                                         float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
252                                         float radius = key_steps[i].w * scalar;
253
254                                         /* scale for curve radius is only correct for uniform scale */
255                                         key_steps[i] = float3_to_float4(co);
256                                         key_steps[i].w = radius;
257                                 }
258                         }
259                 }
260         }
261
262         /* we keep normals pointing in same direction on negative scale, notify
263          * mesh about this in it (re)calculates normals */
264         if(transform_negative_scale(tfm))
265                 mesh->transform_negative_scaled = true;
266
267         if(bounds.valid()) {
268                 mesh->compute_bounds();
269                 compute_bounds(false);
270         }
271
272         /* tfm is not reset to identity, all code that uses it needs to check the
273          * transform_applied boolean */
274 }
275
276 void Object::tag_update(Scene *scene)
277 {
278         if(mesh) {
279                 if(mesh->transform_applied)
280                         mesh->need_update = true;
281
282                 foreach(Shader *shader, mesh->used_shaders) {
283                         if(shader->use_mis && shader->has_surface_emission)
284                                 scene->light_manager->need_update = true;
285                 }
286         }
287
288         scene->camera->need_flags_update = true;
289         scene->curve_system_manager->need_update = true;
290         scene->mesh_manager->need_update = true;
291         scene->object_manager->need_update = true;
292 }
293
294 bool Object::use_motion() const
295 {
296         return (motion.size() > 1);
297 }
298
299 float Object::motion_time(int step) const
300 {
301         return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
302 }
303
304 int Object::motion_step(float time) const
305 {
306         if(use_motion()) {
307                 for(size_t step = 0; step < motion.size(); step++) {
308                         if(time == motion_time(step)) {
309                                 return step;
310                         }
311                 }
312         }
313
314         return -1;
315 }
316
317 bool Object::is_traceable() const
318 {
319         /* Mesh itself can be empty,can skip all such objects. */
320         if(!bounds.valid() || bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) {
321                 return false;
322         }
323         /* TODO(sergey): Check for mesh vertices/curves. visibility flags. */
324         return true;
325 }
326
327 uint Object::visibility_for_tracing() const {
328         uint trace_visibility = visibility;
329         if(is_shadow_catcher) {
330                 trace_visibility &= ~PATH_RAY_SHADOW_NON_CATCHER;
331         }
332         else {
333                 trace_visibility &= ~PATH_RAY_SHADOW_CATCHER;
334         }
335         return trace_visibility;
336 }
337
338 int Object::get_device_index() const
339 {
340         return index;
341 }
342
343 /* Object Manager */
344
345 ObjectManager::ObjectManager()
346 {
347         need_update = true;
348         need_flags_update = true;
349 }
350
351 ObjectManager::~ObjectManager()
352 {
353 }
354
355 void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state,
356                                                    Object *ob)
357 {
358         KernelObject& kobject = state->objects[ob->index];
359         Transform *object_motion_pass = state->object_motion_pass;
360
361         Mesh *mesh = ob->mesh;
362         uint flag = 0;
363
364         /* Compute transformations. */
365         Transform tfm = ob->tfm;
366         Transform itfm = transform_inverse(tfm);
367
368         /* Compute surface area. for uniform scale we can do avoid the many
369          * transform calls and share computation for instances.
370          *
371          * TODO(brecht): Correct for displacement, and move to a better place.
372          */
373         float uniform_scale;
374         float surface_area = 0.0f;
375         float pass_id = ob->pass_id;
376         float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF);
377         int particle_index = (ob->particle_system)
378                 ? ob->particle_index + state->particle_offset[ob->particle_system]
379                 : 0;
380
381         if(transform_uniform_scale(tfm, uniform_scale)) {
382                 map<Mesh*, float>::iterator it;
383
384                 /* NOTE: This isn't fully optimal and could in theory lead to multiple
385                  * threads calculating area of the same mesh in parallel. However, this
386                  * also prevents suspending all the threads when some mesh's area is
387                  * not yet known.
388                  */
389                 state->surface_area_lock.lock();
390                 it = state->surface_area_map.find(mesh);
391                 state->surface_area_lock.unlock();
392
393                 if(it == state->surface_area_map.end()) {
394                         size_t num_triangles = mesh->num_triangles();
395                         for(size_t j = 0; j < num_triangles; j++) {
396                                 Mesh::Triangle t = mesh->get_triangle(j);
397                                 float3 p1 = mesh->verts[t.v[0]];
398                                 float3 p2 = mesh->verts[t.v[1]];
399                                 float3 p3 = mesh->verts[t.v[2]];
400
401                                 surface_area += triangle_area(p1, p2, p3);
402                         }
403
404                         state->surface_area_lock.lock();
405                         state->surface_area_map[mesh] = surface_area;
406                         state->surface_area_lock.unlock();
407                 }
408                 else {
409                         surface_area = it->second;
410                 }
411
412                 surface_area *= uniform_scale;
413         }
414         else {
415                 size_t num_triangles = mesh->num_triangles();
416                 for(size_t j = 0; j < num_triangles; j++) {
417                         Mesh::Triangle t = mesh->get_triangle(j);
418                         float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]);
419                         float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]);
420                         float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]);
421
422                         surface_area += triangle_area(p1, p2, p3);
423                 }
424         }
425
426         kobject.tfm = tfm;
427         kobject.itfm = itfm;
428         kobject.surface_area = surface_area;
429         kobject.pass_id = pass_id;
430         kobject.random_number = random_number;
431         kobject.particle_index = particle_index;
432         kobject.motion_offset = 0;
433
434         if(mesh->use_motion_blur) {
435                 state->have_motion = true;
436         }
437         if(mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
438                 flag |= SD_OBJECT_HAS_VERTEX_MOTION;
439         }
440
441         if(state->need_motion == Scene::MOTION_PASS) {
442                 /* Clear motion array if there is no actual motion. */
443                 ob->update_motion();
444
445                 /* Compute motion transforms. */
446                 Transform tfm_pre, tfm_post;
447                 if(ob->use_motion()) {
448                         tfm_pre = ob->motion[0];
449                         tfm_post = ob->motion[ob->motion.size() - 1];
450                 }
451                 else {
452                         tfm_pre = tfm;
453                         tfm_post = tfm;
454                 }
455
456                 /* Motion transformations, is world/object space depending if mesh
457                  * comes with deformed position in object space, or if we transform
458                  * the shading point in world space. */
459                 if(!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
460                         tfm_pre = tfm_pre * itfm;
461                         tfm_post = tfm_post * itfm;
462                 }
463
464                 int motion_pass_offset = ob->index*OBJECT_MOTION_PASS_SIZE;
465                 object_motion_pass[motion_pass_offset + 0] = tfm_pre;
466                 object_motion_pass[motion_pass_offset + 1] = tfm_post;
467         }
468         else if(state->need_motion == Scene::MOTION_BLUR) {
469                 if(ob->use_motion()) {
470                         kobject.motion_offset = state->motion_offset[ob->index];
471
472                         /* Decompose transforms for interpolation. */
473                         DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
474                         transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
475                         flag |= SD_OBJECT_MOTION;
476                         state->have_motion = true;
477                 }
478         }
479
480         /* Dupli object coords and motion info. */
481         kobject.dupli_generated[0] = ob->dupli_generated[0];
482         kobject.dupli_generated[1] = ob->dupli_generated[1];
483         kobject.dupli_generated[2] = ob->dupli_generated[2];
484         kobject.numkeys = mesh->curve_keys.size();
485         kobject.dupli_uv[0] = ob->dupli_uv[0];
486         kobject.dupli_uv[1] = ob->dupli_uv[1];
487         int totalsteps = mesh->motion_steps;
488         kobject.numsteps = (totalsteps - 1)/2;
489         kobject.numverts = mesh->verts.size();
490         kobject.patch_map_offset = 0;
491         kobject.attribute_map_offset = 0;
492         uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
493         uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
494         kobject.cryptomatte_object = util_hash_to_float(hash_name);
495         kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
496
497         /* Object flag. */
498         if(ob->use_holdout) {
499                 flag |= SD_OBJECT_HOLDOUT_MASK;
500         }
501         state->object_flag[ob->index] = flag;
502
503         /* Have curves. */
504         if(mesh->num_curves()) {
505                 state->have_curves = true;
506         }
507 }
508
509 bool ObjectManager::device_update_object_transform_pop_work(
510         UpdateObjectTransformState *state,
511         int *start_index,
512         int *num_objects)
513 {
514         /* Tweakable parameter, number of objects per chunk.
515          * Too small value will cause some extra overhead due to spin lock,
516          * too big value might not use all threads nicely.
517          */
518         static const int OBJECTS_PER_TASK = 32;
519         bool have_work = false;
520         state->queue_lock.lock();
521         int num_scene_objects = state->scene->objects.size();
522         if(state->queue_start_object < num_scene_objects) {
523                 int count = min(OBJECTS_PER_TASK,
524                                 num_scene_objects - state->queue_start_object);
525                 *start_index = state->queue_start_object;
526                 *num_objects = count;
527                 state->queue_start_object += count;
528                 have_work = true;
529         }
530         state->queue_lock.unlock();
531         return have_work;
532 }
533
534 void ObjectManager::device_update_object_transform_task(
535         UpdateObjectTransformState *state)
536 {
537         int start_index, num_objects;
538         while(device_update_object_transform_pop_work(state,
539                                                       &start_index,
540                                                       &num_objects))
541         {
542                 for(int i = 0; i < num_objects; ++i) {
543                         const int object_index = start_index + i;
544                         Object *ob = state->scene->objects[object_index];
545                         device_update_object_transform(state, ob);
546                 }
547         }
548 }
549
550 void ObjectManager::device_update_transforms(DeviceScene *dscene,
551                                              Scene *scene,
552                                              Progress& progress)
553 {
554         UpdateObjectTransformState state;
555         state.need_motion = scene->need_motion();
556         state.have_motion = false;
557         state.have_curves = false;
558         state.scene = scene;
559         state.queue_start_object = 0;
560
561         state.objects = dscene->objects.alloc(scene->objects.size());
562         state.object_flag = dscene->object_flag.alloc(scene->objects.size());
563         state.object_motion = NULL;
564         state.object_motion_pass = NULL;
565
566         if(state.need_motion == Scene::MOTION_PASS) {
567                 state.object_motion_pass = dscene->object_motion_pass.alloc(OBJECT_MOTION_PASS_SIZE*scene->objects.size());
568         }
569         else if(state.need_motion == Scene::MOTION_BLUR) {
570                 /* Set object offsets into global object motion array. */
571                 uint *motion_offsets = state.motion_offset.resize(scene->objects.size());
572                 uint motion_offset = 0;
573
574                 foreach(Object *ob, scene->objects) {
575                         *motion_offsets = motion_offset;
576                         motion_offsets++;
577
578                         /* Clear motion array if there is no actual motion. */
579                         ob->update_motion();
580                         motion_offset += ob->motion.size();
581                 }
582
583                 state.object_motion = dscene->object_motion.alloc(motion_offset);
584         }
585
586         /* Particle system device offsets
587          * 0 is dummy particle, index starts at 1.
588          */
589         int numparticles = 1;
590         foreach(ParticleSystem *psys, scene->particle_systems) {
591                 state.particle_offset[psys] = numparticles;
592                 numparticles += psys->particles.size();
593         }
594
595         /* NOTE: If it's just a handful of objects we deal with them in a single
596          * thread to avoid threading overhead. However, this threshold is might
597          * need some tweaks to make mid-complex scenes optimal.
598          */
599         if(scene->objects.size() < 64) {
600                 foreach(Object *ob, scene->objects) {
601                         device_update_object_transform(&state, ob);
602                         if(progress.get_cancel()) {
603                                 return;
604                         }
605                 }
606         }
607         else {
608                 const int num_threads = TaskScheduler::num_threads();
609                 TaskPool pool;
610                 for(int i = 0; i < num_threads; ++i) {
611                         pool.push(function_bind(
612                                 &ObjectManager::device_update_object_transform_task,
613                                 this,
614                                 &state));
615                 }
616                 pool.wait_work();
617                 if(progress.get_cancel()) {
618                         return;
619                 }
620         }
621
622         dscene->objects.copy_to_device();
623         if(state.need_motion == Scene::MOTION_PASS) {
624                 dscene->object_motion_pass.copy_to_device();
625         }
626         else if(state.need_motion == Scene::MOTION_BLUR) {
627                 dscene->object_motion.copy_to_device();
628         }
629
630         dscene->data.bvh.have_motion = state.have_motion;
631         dscene->data.bvh.have_curves = state.have_curves;
632         dscene->data.bvh.have_instancing = true;
633 }
634
635 void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
636 {
637         if(!need_update)
638                 return;
639
640         VLOG(1) << "Total " << scene->objects.size() << " objects.";
641
642         device_free(device, dscene);
643
644         if(scene->objects.size() == 0)
645                 return;
646
647         /* Assign object IDs. */
648         int index = 0;
649         foreach(Object *object, scene->objects) {
650                 object->index = index++;
651         }
652
653         /* set object transform matrices, before applying static transforms */
654         progress.set_status("Updating Objects", "Copying Transformations to device");
655         device_update_transforms(dscene, scene, progress);
656
657         if(progress.get_cancel()) return;
658
659         /* prepare for static BVH building */
660         /* todo: do before to support getting object level coords? */
661         if(scene->params.bvh_type == SceneParams::BVH_STATIC) {
662                 progress.set_status("Updating Objects", "Applying Static Transformations");
663                 apply_static_transforms(dscene, scene, progress);
664         }
665 }
666
667 void ObjectManager::device_update_flags(Device *,
668                                         DeviceScene *dscene,
669                                         Scene *scene,
670                                         Progress& /*progress*/,
671                                         bool bounds_valid)
672 {
673         if(!need_update && !need_flags_update)
674                 return;
675
676         need_update = false;
677         need_flags_update = false;
678
679         if(scene->objects.size() == 0)
680                 return;
681
682         /* Object info flag. */
683         uint *object_flag = dscene->object_flag.data();
684
685         /* Object volume intersection. */
686         vector<Object *> volume_objects;
687         bool has_volume_objects = false;
688         foreach(Object *object, scene->objects) {
689                 if(object->mesh->has_volume) {
690                         if(bounds_valid) {
691                                 volume_objects.push_back(object);
692                         }
693                         has_volume_objects = true;
694                 }
695         }
696
697         foreach(Object *object, scene->objects) {
698                 if(object->mesh->has_volume) {
699                         object_flag[object->index] |= SD_OBJECT_HAS_VOLUME;
700                         object_flag[object->index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
701
702                         foreach(Attribute& attr, object->mesh->attributes.attributes) {
703                                 if(attr.element == ATTR_ELEMENT_VOXEL) {
704                                         object_flag[object->index] |= SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
705                                 }
706                         }
707                 }
708                 else {
709                         object_flag[object->index] &= ~(SD_OBJECT_HAS_VOLUME|SD_OBJECT_HAS_VOLUME_ATTRIBUTES);
710                 }
711                 if(object->is_shadow_catcher) {
712                         object_flag[object->index] |= SD_OBJECT_SHADOW_CATCHER;
713                 }
714                 else {
715                         object_flag[object->index] &= ~SD_OBJECT_SHADOW_CATCHER;
716                 }
717
718                 if(bounds_valid) {
719                         foreach(Object *volume_object, volume_objects) {
720                                 if(object == volume_object) {
721                                         continue;
722                                 }
723                                 if(object->bounds.intersects(volume_object->bounds)) {
724                                         object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
725                                         break;
726                                 }
727                         }
728                 }
729                 else if(has_volume_objects) {
730                         /* Not really valid, but can't make more reliable in the case
731                          * of bounds not being up to date.
732                          */
733                         object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
734                 }
735         }
736
737         /* Copy object flag. */
738         dscene->object_flag.copy_to_device();
739 }
740
741 void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene)
742 {
743         if(dscene->objects.size() == 0) {
744                 return;
745         }
746
747         KernelObject *kobjects = dscene->objects.data();
748
749         bool update = false;
750
751         foreach(Object *object, scene->objects) {
752                 Mesh* mesh = object->mesh;
753
754                 if(mesh->patch_table) {
755                         uint patch_map_offset = 2*(mesh->patch_table_offset + mesh->patch_table->total_size() -
756                                                    mesh->patch_table->num_nodes * PATCH_NODE_SIZE) - mesh->patch_offset;
757
758                         if(kobjects[object->index].patch_map_offset != patch_map_offset) {
759                                 kobjects[object->index].patch_map_offset = patch_map_offset;
760                                 update = true;
761                         }
762                 }
763
764                 if(kobjects[object->index].attribute_map_offset != mesh->attr_map_offset) {
765                         kobjects[object->index].attribute_map_offset = mesh->attr_map_offset;
766                         update = true;
767                 }
768         }
769
770         if(update) {
771                 dscene->objects.copy_to_device();
772         }
773 }
774
775 void ObjectManager::device_free(Device *, DeviceScene *dscene)
776 {
777         dscene->objects.free();
778         dscene->object_motion_pass.free();
779         dscene->object_motion.free();
780         dscene->object_flag.free();
781 }
782
783 void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress& progress)
784 {
785         /* todo: normals and displacement should be done before applying transform! */
786         /* todo: create objects/meshes in right order! */
787
788         /* counter mesh users */
789         map<Mesh*, int> mesh_users;
790         Scene::MotionType need_motion = scene->need_motion();
791         bool motion_blur = need_motion == Scene::MOTION_BLUR;
792         bool apply_to_motion = need_motion != Scene::MOTION_PASS;
793         int i = 0;
794         bool have_instancing = false;
795
796         foreach(Object *object, scene->objects) {
797                 map<Mesh*, int>::iterator it = mesh_users.find(object->mesh);
798
799                 if(it == mesh_users.end())
800                         mesh_users[object->mesh] = 1;
801                 else
802                         it->second++;
803         }
804
805         if(progress.get_cancel()) return;
806
807         uint *object_flag = dscene->object_flag.data();
808
809         /* apply transforms for objects with single user meshes */
810         foreach(Object *object, scene->objects) {
811                 /* Annoying feedback loop here: we can't use is_instanced() because
812                  * it'll use uninitialized transform_applied flag.
813                  *
814                  * Could be solved by moving reference counter to Mesh.
815                  */
816                 if((mesh_users[object->mesh] == 1 && !object->mesh->has_surface_bssrdf) &&
817                    !object->mesh->has_true_displacement() && object->mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
818                 {
819                         if(!(motion_blur && object->use_motion())) {
820                                 if(!object->mesh->transform_applied) {
821                                         object->apply_transform(apply_to_motion);
822                                         object->mesh->transform_applied = true;
823
824                                         if(progress.get_cancel()) return;
825                                 }
826
827                                 object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
828                                 if(object->mesh->transform_negative_scaled)
829                                         object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
830                         }
831                         else
832                                 have_instancing = true;
833                 }
834                 else
835                         have_instancing = true;
836
837                 i++;
838         }
839
840         dscene->data.bvh.have_instancing = have_instancing;
841 }
842
843 void ObjectManager::tag_update(Scene *scene)
844 {
845         need_update = true;
846         scene->curve_system_manager->need_update = true;
847         scene->mesh_manager->need_update = true;
848         scene->light_manager->need_update = true;
849 }
850
851 string ObjectManager::get_cryptomatte_objects(Scene *scene)
852 {
853         string manifest = "{";
854
855         unordered_set<ustring, ustringHash> objects;
856         foreach(Object *object, scene->objects) {
857                 if(objects.count(object->name)) {
858                         continue;
859                 }
860                 objects.insert(object->name);
861                 uint32_t hash_name = util_murmur_hash3(object->name.c_str(), object->name.length(), 0);
862                 manifest += string_printf("\"%s\":\"%08x\",", object->name.c_str(), hash_name);
863         }
864         manifest[manifest.size()-1] = '}';
865         return manifest;
866 }
867
868 string ObjectManager::get_cryptomatte_assets(Scene *scene)
869 {
870         string manifest = "{";
871         unordered_set<ustring, ustringHash> assets;
872         foreach(Object *ob, scene->objects) {
873                 if(assets.count(ob->asset_name)) {
874                         continue;
875                 }
876                 assets.insert(ob->asset_name);
877                 uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
878                 manifest += string_printf("\"%s\":\"%08x\",", ob->asset_name.c_str(), hash_asset);
879         }
880         manifest[manifest.size()-1] = '}';
881         return manifest;
882 }
883
884 CCL_NAMESPACE_END