Blender  V2.93
object.cpp
Go to the documentation of this file.
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/object.h"
18 #include "device/device.h"
19 #include "render/camera.h"
20 #include "render/curves.h"
21 #include "render/hair.h"
22 #include "render/integrator.h"
23 #include "render/light.h"
24 #include "render/mesh.h"
25 #include "render/particles.h"
26 #include "render/scene.h"
27 #include "render/stats.h"
28 #include "render/volume.h"
29 
30 #include "util/util_foreach.h"
31 #include "util/util_logging.h"
32 #include "util/util_map.h"
33 #include "util/util_murmurhash.h"
34 #include "util/util_progress.h"
35 #include "util/util_set.h"
36 #include "util/util_task.h"
37 #include "util/util_vector.h"
38 
39 #include "subd/subd_patch_table.h"
40 
42 
43 /* Global state of object transform update. */
44 
46  /* Global state used by device_update_object_transform().
47  * Common for both threaded and non-threaded update.
48  */
49 
50  /* Type of the motion required by the scene settings. */
52 
53  /* Mapping from particle system to a index in packed particle array.
54  * Only used for read.
55  */
56  map<ParticleSystem *, int> particle_offset;
57 
58  /* Motion offsets for each object. */
60 
61  /* Packed object arrays. Those will be filled in. */
67 
68  /* Flags which will be synchronized to Integrator. */
71 
72  /* ** Scheduling queue. ** */
74 
75  /* First unused object index in the queue. */
77 };
78 
79 /* Object */
80 
82 {
83  NodeType *type = NodeType::add("object", create);
84 
85  SOCKET_NODE(geometry, "Geometry", Geometry::get_node_base_type());
86  SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
87  SOCKET_UINT(visibility, "Visibility", ~0);
88  SOCKET_COLOR(color, "Color", zero_float3());
89  SOCKET_UINT(random_id, "Random ID", 0);
90  SOCKET_INT(pass_id, "Pass ID", 0);
91  SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
92  SOCKET_BOOLEAN(hide_on_missing_motion, "Hide on Missing Motion", false);
93  SOCKET_POINT(dupli_generated, "Dupli Generated", zero_float3());
94  SOCKET_POINT2(dupli_uv, "Dupli UV", zero_float2());
95  SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
96  SOCKET_FLOAT(shadow_terminator_offset, "Terminator Offset", 0.0f);
97  SOCKET_STRING(asset_name, "Asset Name", ustring());
98 
99  SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false);
100 
101  SOCKET_NODE(particle_system, "Particle System", ParticleSystem::get_node_type());
102  SOCKET_INT(particle_index, "Particle Index", 0);
103 
104  return type;
105 }
106 
107 Object::Object() : Node(get_node_type())
108 {
109  particle_system = NULL;
110  particle_index = 0;
111  attr_map_offset = 0;
113 }
114 
116 {
117 }
118 
120 {
121  if (!use_motion()) {
122  return;
123  }
124 
125  bool have_motion = false;
126 
127  for (size_t i = 0; i < motion.size(); i++) {
128  if (motion[i] == transform_empty()) {
129  if (hide_on_missing_motion) {
130  /* Hide objects that have no valid previous or next
131  * transform, for example particle that stop existing. It
132  * would be better to handle this in the kernel and make
133  * objects invisible outside certain motion steps. */
134  tfm = transform_empty();
135  motion.clear();
136  return;
137  }
138  else {
139  /* Otherwise just copy center motion. */
140  motion[i] = tfm;
141  }
142  }
143 
144  /* Test if any of the transforms are actually different. */
145  have_motion = have_motion || motion[i] != tfm;
146  }
147 
148  /* Clear motion array if there is no actual motion. */
149  if (!have_motion) {
150  motion.clear();
151  }
152 }
153 
154 void Object::compute_bounds(bool motion_blur)
155 {
156  BoundBox mbounds = geometry->bounds;
157 
158  if (motion_blur && use_motion()) {
159  array<DecomposedTransform> decomp(motion.size());
160  transform_motion_decompose(decomp.data(), motion.data(), motion.size());
161 
163 
164  /* TODO: this is really terrible. according to PBRT there is a better
165  * way to find this iteratively, but did not find implementation yet
166  * or try to implement myself */
167  for (float t = 0.0f; t < 1.0f; t += (1.0f / 128.0f)) {
168  Transform ttfm;
169 
170  transform_motion_array_interpolate(&ttfm, decomp.data(), motion.size(), t);
171  bounds.grow(mbounds.transformed(&ttfm));
172  }
173  }
174  else {
175  /* No motion blur case. */
176  if (geometry->transform_applied) {
177  bounds = mbounds;
178  }
179  else {
180  bounds = mbounds.transformed(&tfm);
181  }
182  }
183 }
184 
185 void Object::apply_transform(bool apply_to_motion)
186 {
187  if (!geometry || tfm == transform_identity())
188  return;
189 
190  geometry->apply_transform(tfm, apply_to_motion);
191 
192  /* we keep normals pointing in same direction on negative scale, notify
193  * geometry about this in it (re)calculates normals */
194  if (transform_negative_scale(tfm))
195  geometry->transform_negative_scaled = true;
196 
197  if (bounds.valid()) {
198  geometry->compute_bounds();
199  compute_bounds(false);
200  }
201 
202  /* tfm is not reset to identity, all code that uses it needs to check the
203  * transform_applied boolean */
204 }
205 
207 {
209 
210  if (is_modified()) {
212 
213  if (use_holdout_is_modified()) {
215  }
216  }
217 
218  if (geometry) {
219  if (tfm_is_modified()) {
221  }
222 
223  if (visibility_is_modified()) {
225  }
226 
227  foreach (Node *node, geometry->get_used_shaders()) {
228  Shader *shader = static_cast<Shader *>(node);
229  if (shader->get_use_mis() && shader->has_surface_emission)
231  }
232  }
233 
234  scene->camera->need_flags_update = true;
236 }
237 
238 bool Object::use_motion() const
239 {
240  return (motion.size() > 1);
241 }
242 
243 float Object::motion_time(int step) const
244 {
245  return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
246 }
247 
248 int Object::motion_step(float time) const
249 {
250  if (use_motion()) {
251  for (size_t step = 0; step < motion.size(); step++) {
252  if (time == motion_time(step)) {
253  return step;
254  }
255  }
256  }
257 
258  return -1;
259 }
260 
262 {
263  /* Mesh itself can be empty,can skip all such objects. */
264  if (!bounds.valid() || bounds.size() == zero_float3()) {
265  return false;
266  }
267  /* TODO(sergey): Check for mesh vertices/curves. visibility flags. */
268  return true;
269 }
270 
272 {
273  uint trace_visibility = visibility;
274  if (is_shadow_catcher) {
275  trace_visibility &= ~PATH_RAY_SHADOW_NON_CATCHER;
276  }
277  else {
278  trace_visibility &= ~PATH_RAY_SHADOW_CATCHER;
279  }
280  return trace_visibility;
281 }
282 
284 {
285  if (geometry->geometry_type != Geometry::MESH && geometry->geometry_type != Geometry::VOLUME) {
286  return FLT_MAX;
287  }
288 
289  Mesh *mesh = static_cast<Mesh *>(geometry);
290 
291  if (!mesh->has_volume) {
292  return FLT_MAX;
293  }
294 
295  /* Compute step rate from shaders. */
296  float step_rate = FLT_MAX;
297 
298  foreach (Node *node, mesh->get_used_shaders()) {
299  Shader *shader = static_cast<Shader *>(node);
300  if (shader->has_volume) {
301  if ((shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) ||
302  (shader->has_volume_attribute_dependency)) {
303  step_rate = fminf(shader->get_volume_step_rate(), step_rate);
304  }
305  }
306  }
307 
308  if (step_rate == FLT_MAX) {
309  return FLT_MAX;
310  }
311 
312  /* Compute step size from voxel grids. */
313  float step_size = FLT_MAX;
314 
315  if (geometry->geometry_type == Geometry::VOLUME) {
316  Volume *volume = static_cast<Volume *>(geometry);
317 
318  foreach (Attribute &attr, volume->attributes.attributes) {
319  if (attr.element == ATTR_ELEMENT_VOXEL) {
320  ImageHandle &handle = attr.data_voxel();
321  const ImageMetaData &metadata = handle.metadata();
322  if (metadata.width == 0 || metadata.height == 0 || metadata.depth == 0) {
323  continue;
324  }
325 
326  /* User specified step size. */
327  float voxel_step_size = volume->get_step_size();
328 
329  if (voxel_step_size == 0.0f) {
330  /* Auto detect step size. */
331  float3 size = one_float3();
332 #ifdef WITH_NANOVDB
333  /* Dimensions were not applied to image transform with NanOVDB (see image_vdb.cpp) */
334  if (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT &&
336 #endif
337  size /= make_float3(metadata.width, metadata.height, metadata.depth);
338 
339  /* Step size is transformed from voxel to world space. */
340  Transform voxel_tfm = tfm;
341  if (metadata.use_transform_3d) {
342  voxel_tfm = tfm * transform_inverse(metadata.transform_3d);
343  }
344  voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size)));
345  }
346  else if (volume->get_object_space()) {
347  /* User specified step size in object space. */
348  float3 size = make_float3(voxel_step_size, voxel_step_size, voxel_step_size);
349  voxel_step_size = min3(fabs(transform_direction(&tfm, size)));
350  }
351 
352  if (voxel_step_size > 0.0f) {
353  step_size = fminf(voxel_step_size, step_size);
354  }
355  }
356  }
357  }
358 
359  if (step_size == FLT_MAX) {
360  /* Fall back to 1/10th of bounds for procedural volumes. */
361  step_size = 0.1f * average(bounds.size());
362  }
363 
364  step_size *= step_rate;
365 
366  return step_size;
367 }
368 
370 {
371  return index;
372 }
373 
374 /* Object Manager */
375 
377 {
378  update_flags = UPDATE_ALL;
379  need_flags_update = true;
380 }
381 
383 {
384 }
385 
386 static float object_volume_density(const Transform &tfm, Geometry *geom)
387 {
388  if (geom->geometry_type == Geometry::VOLUME) {
389  /* Volume density automatically adjust to object scale. */
390  if (static_cast<Volume *>(geom)->get_object_space()) {
391  const float3 unit = normalize(one_float3());
392  return 1.0f / len(transform_direction(&tfm, unit));
393  }
394  }
395 
396  return 1.0f;
397 }
398 
400  Object *ob,
401  bool update_all)
402 {
403  KernelObject &kobject = state->objects[ob->index];
404  Transform *object_motion_pass = state->object_motion_pass;
405 
406  Geometry *geom = ob->geometry;
407  uint flag = 0;
408 
409  /* Compute transformations. */
410  Transform tfm = ob->tfm;
411  Transform itfm = transform_inverse(tfm);
412 
413  float3 color = ob->color;
414  float pass_id = ob->pass_id;
415  float random_number = (float)ob->random_id * (1.0f / (float)0xFFFFFFFF);
416  int particle_index = (ob->particle_system) ?
417  ob->particle_index + state->particle_offset[ob->particle_system] :
418  0;
419 
420  kobject.tfm = tfm;
421  kobject.itfm = itfm;
422  kobject.volume_density = object_volume_density(tfm, geom);
423  kobject.color[0] = color.x;
424  kobject.color[1] = color.y;
425  kobject.color[2] = color.z;
426  kobject.pass_id = pass_id;
427  kobject.random_number = random_number;
428  kobject.particle_index = particle_index;
429  kobject.motion_offset = 0;
430 
431  if (geom->get_use_motion_blur()) {
432  state->have_motion = true;
433  }
434 
435  if (geom->geometry_type == Geometry::MESH) {
436  /* TODO: why only mesh? */
437  Mesh *mesh = static_cast<Mesh *>(geom);
440  }
441  }
442 
443  if (state->need_motion == Scene::MOTION_PASS) {
444  /* Clear motion array if there is no actual motion. */
445  ob->update_motion();
446 
447  /* Compute motion transforms. */
448  Transform tfm_pre, tfm_post;
449  if (ob->use_motion()) {
450  tfm_pre = ob->motion[0];
451  tfm_post = ob->motion[ob->motion.size() - 1];
452  }
453  else {
454  tfm_pre = tfm;
455  tfm_post = tfm;
456  }
457 
458  /* Motion transformations, is world/object space depending if mesh
459  * comes with deformed position in object space, or if we transform
460  * the shading point in world space. */
461  if (!(flag & SD_OBJECT_HAS_VERTEX_MOTION)) {
462  tfm_pre = tfm_pre * itfm;
463  tfm_post = tfm_post * itfm;
464  }
465 
466  int motion_pass_offset = ob->index * OBJECT_MOTION_PASS_SIZE;
467  object_motion_pass[motion_pass_offset + 0] = tfm_pre;
468  object_motion_pass[motion_pass_offset + 1] = tfm_post;
469  }
470  else if (state->need_motion == Scene::MOTION_BLUR) {
471  if (ob->use_motion()) {
472  kobject.motion_offset = state->motion_offset[ob->index];
473 
474  /* Decompose transforms for interpolation. */
475  if (ob->tfm_is_modified() || update_all) {
476  DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
477  transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
478  }
479 
480  flag |= SD_OBJECT_MOTION;
481  state->have_motion = true;
482  }
483  }
484 
485  /* Dupli object coords and motion info. */
486  kobject.dupli_generated[0] = ob->dupli_generated[0];
487  kobject.dupli_generated[1] = ob->dupli_generated[1];
488  kobject.dupli_generated[2] = ob->dupli_generated[2];
489  kobject.numkeys = (geom->geometry_type == Geometry::HAIR) ?
490  static_cast<Hair *>(geom)->get_curve_keys().size() :
491  0;
492  kobject.dupli_uv[0] = ob->dupli_uv[0];
493  kobject.dupli_uv[1] = ob->dupli_uv[1];
494  int totalsteps = geom->get_motion_steps();
495  kobject.numsteps = (totalsteps - 1) / 2;
496  kobject.numverts = (geom->geometry_type == Geometry::MESH ||
497  geom->geometry_type == Geometry::VOLUME) ?
498  static_cast<Mesh *>(geom)->get_verts().size() :
499  0;
500  kobject.patch_map_offset = 0;
501  kobject.attribute_map_offset = 0;
502 
503  if (ob->asset_name_is_modified() || update_all) {
504  uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
505  uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
506  kobject.cryptomatte_object = util_hash_to_float(hash_name);
507  kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
508  }
509 
510  kobject.shadow_terminator_offset = 1.0f / (1.0f - 0.5f * ob->shadow_terminator_offset);
511 
512  /* Object flag. */
513  if (ob->use_holdout) {
514  flag |= SD_OBJECT_HOLDOUT_MASK;
515  }
516  state->object_flag[ob->index] = flag;
517  state->object_volume_step[ob->index] = FLT_MAX;
518 
519  /* Have curves. */
520  if (geom->geometry_type == Geometry::HAIR) {
521  state->have_curves = true;
522  }
523 }
524 
526 {
528  state.need_motion = scene->need_motion();
529  state.have_motion = false;
530  state.have_curves = false;
531  state.scene = scene;
532  state.queue_start_object = 0;
533 
534  state.objects = dscene->objects.alloc(scene->objects.size());
535  state.object_flag = dscene->object_flag.alloc(scene->objects.size());
536  state.object_volume_step = dscene->object_volume_step.alloc(scene->objects.size());
537  state.object_motion = NULL;
538  state.object_motion_pass = NULL;
539 
540  if (state.need_motion == Scene::MOTION_PASS) {
541  state.object_motion_pass = dscene->object_motion_pass.alloc(OBJECT_MOTION_PASS_SIZE *
542  scene->objects.size());
543  }
544  else if (state.need_motion == Scene::MOTION_BLUR) {
545  /* Set object offsets into global object motion array. */
546  uint *motion_offsets = state.motion_offset.resize(scene->objects.size());
547  uint motion_offset = 0;
548 
549  foreach (Object *ob, scene->objects) {
550  *motion_offsets = motion_offset;
551  motion_offsets++;
552 
553  /* Clear motion array if there is no actual motion. */
554  ob->update_motion();
555  motion_offset += ob->motion.size();
556  }
557 
558  state.object_motion = dscene->object_motion.alloc(motion_offset);
559  }
560 
561  /* Particle system device offsets
562  * 0 is dummy particle, index starts at 1.
563  */
564  int numparticles = 1;
565  foreach (ParticleSystem *psys, scene->particle_systems) {
566  state.particle_offset[psys] = numparticles;
567  numparticles += psys->particles.size();
568  }
569 
570  /* as all the arrays are the same size, checking only dscene.objects is sufficient */
571  const bool update_all = dscene->objects.need_realloc();
572 
573  /* Parallel object update, with grain size to avoid too much threading overhead
574  * for individual objects. */
575  static const int OBJECTS_PER_TASK = 32;
576  parallel_for(blocked_range<size_t>(0, scene->objects.size(), OBJECTS_PER_TASK),
577  [&](const blocked_range<size_t> &r) {
578  for (size_t i = r.begin(); i != r.end(); i++) {
579  Object *ob = state.scene->objects[i];
580  device_update_object_transform(&state, ob, update_all);
581  }
582  });
583 
584  if (progress.get_cancel()) {
585  return;
586  }
587 
588  dscene->objects.copy_to_device_if_modified();
589  if (state.need_motion == Scene::MOTION_PASS) {
590  dscene->object_motion_pass.copy_to_device();
591  }
592  else if (state.need_motion == Scene::MOTION_BLUR) {
593  dscene->object_motion.copy_to_device();
594  }
595 
596  dscene->data.bvh.have_motion = state.have_motion;
597  dscene->data.bvh.have_curves = state.have_curves;
598 
599  dscene->objects.clear_modified();
600  dscene->object_motion_pass.clear_modified();
601  dscene->object_motion.clear_modified();
602 }
603 
605  DeviceScene *dscene,
606  Scene *scene,
607  Progress &progress)
608 {
609  if (!need_update())
610  return;
611 
612  if (update_flags & (OBJECT_ADDED | OBJECT_REMOVED)) {
613  dscene->objects.tag_realloc();
615  dscene->object_motion.tag_realloc();
616  dscene->object_flag.tag_realloc();
618  }
619 
620  if (update_flags & HOLDOUT_MODIFIED) {
621  dscene->object_flag.tag_modified();
622  }
623 
624  if (update_flags & PARTICLE_MODIFIED) {
625  dscene->objects.tag_modified();
626  }
627 
628  VLOG(1) << "Total " << scene->objects.size() << " objects.";
629 
630  device_free(device, dscene, false);
631 
632  if (scene->objects.size() == 0)
633  return;
634 
635  {
636  /* Assign object IDs. */
637  scoped_callback_timer timer([scene](double time) {
638  if (scene->update_stats) {
639  scene->update_stats->object.times.add_entry({"device_update (assign index)", time});
640  }
641  });
642 
643  int index = 0;
644  foreach (Object *object, scene->objects) {
645  object->index = index++;
646 
647  /* this is a bit too broad, however a bigger refactor might be needed to properly separate
648  * update each type of data (transform, flags, etc.) */
649  if (object->is_modified()) {
650  dscene->objects.tag_modified();
652  dscene->object_motion.tag_modified();
653  dscene->object_flag.tag_modified();
655  }
656  }
657  }
658 
659  {
660  /* set object transform matrices, before applying static transforms */
661  scoped_callback_timer timer([scene](double time) {
662  if (scene->update_stats) {
663  scene->update_stats->object.times.add_entry(
664  {"device_update (copy objects to device)", time});
665  }
666  });
667 
668  progress.set_status("Updating Objects", "Copying Transformations to device");
669  device_update_transforms(dscene, scene, progress);
670  }
671 
672  if (progress.get_cancel())
673  return;
674 
675  /* prepare for static BVH building */
676  /* todo: do before to support getting object level coords? */
678  scoped_callback_timer timer([scene](double time) {
679  if (scene->update_stats) {
680  scene->update_stats->object.times.add_entry(
681  {"device_update (apply static transforms)", time});
682  }
683  });
684 
685  progress.set_status("Updating Objects", "Applying Static Transformations");
686  apply_static_transforms(dscene, scene, progress);
687  }
688 
689  foreach (Object *object, scene->objects) {
690  object->clear_modified();
691  }
692 }
693 
695  Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
696 {
697  if (!need_update() && !need_flags_update)
698  return;
699 
700  scoped_callback_timer timer([scene](double time) {
701  if (scene->update_stats) {
702  scene->update_stats->object.times.add_entry({"device_update_flags", time});
703  }
704  });
705 
706  update_flags = UPDATE_NONE;
707  need_flags_update = false;
708 
709  if (scene->objects.size() == 0)
710  return;
711 
712  /* Object info flag. */
713  uint *object_flag = dscene->object_flag.data();
714  float *object_volume_step = dscene->object_volume_step.data();
715 
716  /* Object volume intersection. */
717  vector<Object *> volume_objects;
718  bool has_volume_objects = false;
719  foreach (Object *object, scene->objects) {
720  if (object->geometry->has_volume) {
721  if (bounds_valid) {
722  volume_objects.push_back(object);
723  }
724  has_volume_objects = true;
725  object_volume_step[object->index] = object->compute_volume_step_size();
726  }
727  else {
728  object_volume_step[object->index] = FLT_MAX;
729  }
730  }
731 
732  foreach (Object *object, scene->objects) {
733  if (object->geometry->has_volume) {
734  object_flag[object->index] |= SD_OBJECT_HAS_VOLUME;
735  object_flag[object->index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
736 
737  foreach (Attribute &attr, object->geometry->attributes.attributes) {
738  if (attr.element == ATTR_ELEMENT_VOXEL) {
739  object_flag[object->index] |= SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
740  }
741  }
742  }
743  else {
744  object_flag[object->index] &= ~(SD_OBJECT_HAS_VOLUME | SD_OBJECT_HAS_VOLUME_ATTRIBUTES);
745  }
746 
747  if (object->is_shadow_catcher) {
748  object_flag[object->index] |= SD_OBJECT_SHADOW_CATCHER;
749  }
750  else {
751  object_flag[object->index] &= ~SD_OBJECT_SHADOW_CATCHER;
752  }
753 
754  if (bounds_valid) {
755  foreach (Object *volume_object, volume_objects) {
756  if (object == volume_object) {
757  continue;
758  }
759  if (object->bounds.intersects(volume_object->bounds)) {
760  object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
761  break;
762  }
763  }
764  }
765  else if (has_volume_objects) {
766  /* Not really valid, but can't make more reliable in the case
767  * of bounds not being up to date.
768  */
769  object_flag[object->index] |= SD_OBJECT_INTERSECTS_VOLUME;
770  }
771  }
772 
773  /* Copy object flag. */
774  dscene->object_flag.copy_to_device();
775  dscene->object_volume_step.copy_to_device();
776 
777  dscene->object_flag.clear_modified();
778  dscene->object_volume_step.clear_modified();
779 }
780 
782 {
783  if (dscene->objects.size() == 0) {
784  return;
785  }
786 
787  KernelObject *kobjects = dscene->objects.data();
788 
789  bool update = false;
790 
791  foreach (Object *object, scene->objects) {
792  Geometry *geom = object->geometry;
793 
794  if (geom->geometry_type == Geometry::MESH) {
795  Mesh *mesh = static_cast<Mesh *>(geom);
796  if (mesh->patch_table) {
797  uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() -
798  mesh->patch_table->num_nodes * PATCH_NODE_SIZE) -
799  mesh->patch_offset;
800 
801  if (kobjects[object->index].patch_map_offset != patch_map_offset) {
802  kobjects[object->index].patch_map_offset = patch_map_offset;
803  update = true;
804  }
805  }
806  }
807 
808  size_t attr_map_offset = object->attr_map_offset;
809 
810  /* An object attribute map cannot have a zero offset because mesh maps come first. */
811  if (attr_map_offset == 0) {
812  attr_map_offset = geom->attr_map_offset;
813  }
814 
815  if (kobjects[object->index].attribute_map_offset != attr_map_offset) {
816  kobjects[object->index].attribute_map_offset = attr_map_offset;
817  update = true;
818  }
819  }
820 
821  if (update) {
822  dscene->objects.copy_to_device();
823  }
824 }
825 
826 void ObjectManager::device_free(Device *, DeviceScene *dscene, bool force_free)
827 {
828  dscene->objects.free_if_need_realloc(force_free);
829  dscene->object_motion_pass.free_if_need_realloc(force_free);
830  dscene->object_motion.free_if_need_realloc(force_free);
831  dscene->object_flag.free_if_need_realloc(force_free);
832  dscene->object_volume_step.free_if_need_realloc(force_free);
833 }
834 
836 {
837  /* todo: normals and displacement should be done before applying transform! */
838  /* todo: create objects/geometry in right order! */
839 
840  /* counter geometry users */
841  map<Geometry *, int> geometry_users;
842  Scene::MotionType need_motion = scene->need_motion();
843  bool motion_blur = need_motion == Scene::MOTION_BLUR;
844  bool apply_to_motion = need_motion != Scene::MOTION_PASS;
845  int i = 0;
846 
847  foreach (Object *object, scene->objects) {
848  map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
849 
850  if (it == geometry_users.end())
851  geometry_users[object->geometry] = 1;
852  else
853  it->second++;
854  }
855 
856  if (progress.get_cancel())
857  return;
858 
859  uint *object_flag = dscene->object_flag.data();
860 
861  /* apply transforms for objects with single user geometry */
862  foreach (Object *object, scene->objects) {
863  /* Annoying feedback loop here: we can't use is_instanced() because
864  * it'll use uninitialized transform_applied flag.
865  *
866  * Could be solved by moving reference counter to Geometry.
867  */
868  Geometry *geom = object->geometry;
869  bool apply = (geometry_users[geom] == 1) && !geom->has_surface_bssrdf &&
870  !geom->has_true_displacement();
871 
872  if (geom->geometry_type == Geometry::MESH) {
873  Mesh *mesh = static_cast<Mesh *>(geom);
874  apply = apply && mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE;
875  }
876  else if (geom->geometry_type == Geometry::HAIR) {
877  /* Can't apply non-uniform scale to curves, this can't be represented by
878  * control points and radius alone. */
879  float scale;
880  apply = apply && transform_uniform_scale(object->tfm, scale);
881  }
882 
883  if (apply) {
884  if (!(motion_blur && object->use_motion())) {
885  if (!geom->transform_applied) {
886  object->apply_transform(apply_to_motion);
887  geom->transform_applied = true;
888 
889  if (progress.get_cancel())
890  return;
891  }
892 
893  object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
894  if (geom->transform_negative_scaled)
895  object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
896  }
897  }
898 
899  i++;
900  }
901 }
902 
904 {
905  update_flags |= flag;
906 
907  /* avoid infinite loops if the geometry manager tagged us for an update */
908  if ((flag & GEOMETRY_MANAGER) == 0) {
910 
911  /* Also notify in case added or removed objects were instances, as no Geometry might have been
912  * added or removed, but the BVH still needs to updated. */
913  if ((flag & (OBJECT_ADDED | OBJECT_REMOVED)) != 0) {
915  }
916 
917  if ((flag & TRANSFORM_MODIFIED) != 0) {
918  geometry_flag |= GeometryManager::TRANSFORM_MODIFIED;
919  }
920 
921  if ((flag & VISIBILITY_MODIFIED) != 0) {
922  geometry_flag |= GeometryManager::VISIBILITY_MODIFIED;
923  }
924 
925  scene->geometry_manager->tag_update(scene, geometry_flag);
926  }
927 
929 }
930 
932 {
933  return update_flags != UPDATE_NONE;
934 }
935 
937 {
938  string manifest = "{";
939 
940  unordered_set<ustring, ustringHash> objects;
941  foreach (Object *object, scene->objects) {
942  if (objects.count(object->name)) {
943  continue;
944  }
945  objects.insert(object->name);
946  uint32_t hash_name = util_murmur_hash3(object->name.c_str(), object->name.length(), 0);
947  manifest += string_printf("\"%s\":\"%08x\",", object->name.c_str(), hash_name);
948  }
949  manifest[manifest.size() - 1] = '}';
950  return manifest;
951 }
952 
954 {
955  string manifest = "{";
956  unordered_set<ustring, ustringHash> assets;
957  foreach (Object *ob, scene->objects) {
958  if (assets.count(ob->asset_name)) {
959  continue;
960  }
961  assets.insert(ob->asset_name);
962  uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
963  manifest += string_printf("\"%s\":\"%08x\",", ob->asset_name.c_str(), hash_asset);
964  }
965  manifest[manifest.size() - 1] = '}';
966  return manifest;
967 }
968 
typedef float(TangentPoint)[2]
unsigned int uint
Definition: BLI_sys_types.h:83
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
list< Attribute > attributes
Definition: attribute.h:181
Attribute * find(ustring name) const
Definition: attribute.cpp:447
ImageHandle & data_voxel()
Definition: attribute.h:113
AttributeElement element
Definition: attribute.h:54
device_vector< DecomposedTransform > object_motion
Definition: scene.h:100
device_vector< Transform > object_motion_pass
Definition: scene.h:99
device_vector< float > object_volume_step
Definition: scene.h:102
device_vector< uint > object_flag
Definition: scene.h:101
device_vector< KernelObject > objects
Definition: scene.h:98
Definition: device.h:293
void tag_update(Scene *scene, uint32_t flag)
Definition: geometry.cpp:2127
Type geometry_type
Definition: geometry.h:78
@ MESH
Definition: geometry.h:73
@ VOLUME
Definition: geometry.h:75
@ HAIR
Definition: geometry.h:74
bool transform_applied
Definition: geometry.h:88
bool has_volume
Definition: geometry.h:106
bool has_true_displacement() const
Definition: geometry.cpp:187
bool has_surface_bssrdf
Definition: geometry.h:107
size_t attr_map_offset
Definition: geometry.h:101
AttributeSet attributes
Definition: geometry.h:81
bool transform_negative_scaled
Definition: geometry.h:89
ImageMetaData metadata()
Definition: image.cpp:143
ImageDataType type
Transform transform_3d
@ OBJECT_MANAGER
Definition: light.h:101
@ EMISSIVE_MESH_MODIFIED
Definition: light.h:97
void tag_update(Scene *scene, uint32_t flag)
Definition: light.cpp:1036
string get_cryptomatte_objects(Scene *scene)
Definition: object.cpp:936
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: object.cpp:604
void tag_update(Scene *scene, uint32_t flag)
Definition: object.cpp:903
@ GEOMETRY_MANAGER
Definition: object.h:130
@ TRANSFORM_MODIFIED
Definition: object.h:136
@ OBJECT_ADDED
Definition: object.h:132
@ OBJECT_REMOVED
Definition: object.h:133
@ PARTICLE_MODIFIED
Definition: object.h:129
@ OBJECT_MODIFIED
Definition: object.h:134
@ HOLDOUT_MODIFIED
Definition: object.h:135
@ VISIBILITY_MODIFIED
Definition: object.h:137
void device_free(Device *device, DeviceScene *dscene, bool force_free)
Definition: object.cpp:826
string get_cryptomatte_assets(Scene *scene)
Definition: object.cpp:953
bool need_update() const
Definition: object.cpp:931
void device_update_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: object.cpp:525
void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: object.cpp:835
bool need_flags_update
Definition: object.h:145
void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress, bool bounds_valid=true)
Definition: object.cpp:694
void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene)
Definition: object.cpp:781
void device_update_object_transform(UpdateObjectTransformState *state, Object *ob, bool update_all)
Definition: object.cpp:399
bool get_cancel()
@ BVH_STATIC
Definition: scene.h:161
BVHType bvh_type
Definition: scene.h:175
Definition: shader.h:80
T * data()
Definition: util_array.h:208
T * alloc(size_t width, size_t height=0, size_t depth=0)
size_t size() const
void tag_modified()
bool need_realloc()
void copy_to_device()
void tag_realloc()
void free_if_need_realloc(bool force_free)
OperationNode * node
double time
Scene scene
ccl_device_inline uint particle_index(KernelGlobals *kg, int particle)
Definition: geom_object.h:363
#define CCL_NAMESPACE_END
#define fminf(x, y)
#define make_float3(x, y, z)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel_types.h:756
@ PATH_RAY_SHADOW_NON_CATCHER
Definition: kernel_types.h:282
@ PATH_RAY_SHADOW_CATCHER
Definition: kernel_types.h:306
#define OBJECT_MOTION_PASS_SIZE
Definition: kernel_types.h:44
@ SD_OBJECT_MOTION
Definition: kernel_types.h:906
@ SD_OBJECT_HAS_VOLUME_ATTRIBUTES
Definition: kernel_types.h:920
@ SD_OBJECT_HAS_VOLUME
Definition: kernel_types.h:912
@ SD_OBJECT_INTERSECTS_VOLUME
Definition: kernel_types.h:914
@ SD_OBJECT_HOLDOUT_MASK
Definition: kernel_types.h:904
@ SD_OBJECT_SHADOW_CATCHER
Definition: kernel_types.h:918
@ SD_OBJECT_TRANSFORM_APPLIED
Definition: kernel_types.h:908
@ SD_OBJECT_HAS_VERTEX_MOTION
Definition: kernel_types.h:916
@ SD_OBJECT_NEGATIVE_SCALE_APPLIED
Definition: kernel_types.h:910
@ ATTR_ELEMENT_VOXEL
Definition: kernel_types.h:741
static ulong state[N]
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:62
static void update(bNodeTree *ntree)
#define SOCKET_POINT(name, ui_name, default_value,...)
Definition: node_type.h:210
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition: node_type.h:204
#define SOCKET_INT(name, ui_name, default_value,...)
Definition: node_type.h:200
#define SOCKET_NODE(name, ui_name, node_type,...)
Definition: node_type.h:233
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
Definition: node_type.h:218
#define SOCKET_UINT(name, ui_name, default_value,...)
Definition: node_type.h:202
#define SOCKET_COLOR(name, ui_name, default_value,...)
Definition: node_type.h:206
#define SOCKET_TRANSFORM_ARRAY(name, ui_name, default_value,...)
Definition: node_type.h:273
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:198
#define SOCKET_POINT2(name, ui_name, default_value,...)
Definition: node_type.h:214
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition: node_type.h:216
NODE_DEFINE(Object)
Definition: object.cpp:81
static float object_volume_density(const Transform &tfm, Geometry *geom)
Definition: object.cpp:386
unsigned int uint32_t
Definition: stdint.h:83
BoundBox transformed(const Transform *tfm) const
__forceinline bool valid() const
__forceinline float3 size() const
__forceinline bool intersects(const BoundBox &other)
__forceinline void grow(const float3 &pt)
Definition: util_boundbox.h:55
Transform tfm
float shadow_terminator_offset
Transform itfm
float dupli_uv[2]
float volume_density
float random_number
float cryptomatte_asset
float color[3]
uint attribute_map_offset
uint patch_map_offset
float dupli_generated[3]
float cryptomatte_object
float size[3]
@ SUBDIVISION_NONE
Definition: mesh.h:133
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
Definition: node.h:98
bool is_modified()
Definition: node.cpp:781
ustring name
Definition: node.h:174
void compute_bounds(bool motion_blur)
Definition: object.cpp:154
int motion_step(float time) const
Definition: object.cpp:248
bool use_motion() const
Definition: object.cpp:238
NODE_DECLARE BoundBox bounds
Definition: object.h:56
size_t attr_map_offset
Definition: object.h:116
Object()
Definition: object.cpp:107
vector< ParamValue > attributes
Definition: object.h:61
void update_motion()
Definition: object.cpp:119
int get_device_index() const
Definition: object.cpp:369
void apply_transform(bool apply_to_motion)
Definition: object.cpp:185
float compute_volume_step_size() const
Definition: object.cpp:283
bool is_traceable() const
Definition: object.cpp:261
uint visibility_for_tracing() const
Definition: object.cpp:271
void tag_update(Scene *scene)
Definition: object.cpp:206
float color[4]
float motion_time(int step) const
Definition: object.cpp:243
~Object()
Definition: object.cpp:115
void * data
ParticleData * particles
SceneParams params
Definition: scene.h:264
vector< ParticleSystem * > particle_systems
Definition: scene.h:238
vector< Object * > objects
Definition: scene.h:234
MotionType need_motion()
Definition: scene.cpp:358
ObjectManager * object_manager
Definition: scene.h:247
MotionType
Definition: scene.h:280
@ MOTION_PASS
Definition: scene.h:280
@ MOTION_BLUR
Definition: scene.h:280
LightManager * light_manager
Definition: scene.h:244
struct Object * camera
SceneUpdateStats * update_stats
Definition: scene.h:270
GeometryManager * geometry_manager
Definition: scene.h:246
array< uint > motion_offset
Definition: object.cpp:59
KernelObject * objects
Definition: object.cpp:63
map< ParticleSystem *, int > particle_offset
Definition: object.cpp:56
Transform * object_motion_pass
Definition: object.cpp:64
DecomposedTransform * object_motion
Definition: object.cpp:65
Scene::MotionType need_motion
Definition: object.cpp:51
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
#define PATCH_NODE_SIZE
#define VLOG(severity)
Definition: util_logging.h:50
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float2 zero_float2()
ccl_device_inline float average(const float2 &a)
ccl_device_inline float2 fabs(const float2 &a)
ccl_device_inline float3 one_float3()
ccl_device_inline float min3(float3 a)
ccl_device_inline float3 zero_float3()
float util_hash_to_float(uint32_t hash)
uint32_t util_murmur_hash3(const void *key, int len, uint32_t seed)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: util_string.cpp:32
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT
Definition: util_texture.h:60
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT3
Definition: util_texture.h:61
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size)
Transform transform_inverse(const Transform &tfm)
ccl_device_inline Transform transform_identity()
ccl_device_inline float3 transform_direction(const Transform *t, const float3 a)
ccl_device_inline Transform transform_empty()
ccl_device_inline bool transform_negative_scale(const Transform &tfm)
ccl_device_inline bool transform_uniform_scale(const Transform &tfm, float &scale)
ccl_device void transform_motion_array_interpolate(Transform *tfm, const ccl_global DecomposedTransform *motion, uint numsteps, float time)
uint len