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