74 SOCKET_NODE(geometry,
"Geometry", Geometry::get_node_base_type());
82 SOCKET_BOOLEAN(hide_on_missing_motion,
"Hide on Missing Motion",
false);
86 SOCKET_FLOAT(shadow_terminator_shading_offset,
"Shadow Terminator Shading Offset", 0.0f);
87 SOCKET_FLOAT(shadow_terminator_geometry_offset,
"Shadow Terminator Geometry Offset", 0.1f);
93 SOCKET_BOOLEAN(is_caustics_receiver,
"Receive Shadow Caustics",
false);
97 SOCKET_NODE(particle_system,
"Particle System", ParticleSystem::get_node_type());
103 SOCKET_UINT(receiver_light_set,
"Light Set Index", 0);
105 SOCKET_UINT(blocker_shadow_set,
"Shadow Set Index", 0);
113 particle_system =
nullptr;
128 bool have_motion =
false;
130 for (
size_t i = 0;
i < motion.size();
i++) {
132 if (hide_on_missing_motion) {
146 have_motion = have_motion || motion[
i] != tfm;
157 const BoundBox mbounds = geometry->bounds;
168 for (
float t = 0.0f; t < 1.0f; t += (1.0f / 128.0f)) {
177 if (geometry->transform_applied) {
192 geometry->apply_transform(tfm, apply_to_motion);
197 geometry->transform_negative_scaled =
true;
201 geometry->compute_bounds();
216 if (use_holdout_is_modified()) {
220 if (is_shadow_catcher_is_modified()) {
227 if (tfm_is_modified() || motion_is_modified()) {
229 if (geometry->has_volume) {
234 if (visibility_is_modified()) {
238 for (
Node *node : geometry->get_used_shaders()) {
246 scene->
camera->need_flags_update =
true;
252 return (motion.size() > 1);
257 return (
use_motion()) ? 2.0f *
step / (motion.size() - 1) - 1.0f : 0.0f;
276 if (geometry->is_light()) {
294 if (geometry->is_light()) {
297 for (
const Node *node : geometry->get_used_shaders()) {
298 const Shader *shader =
static_cast<const Shader *
>(node);
300 return shader->get_volume_step_rate();
307 if (!geometry->is_mesh() && !geometry->is_volume()) {
311 Mesh *mesh =
static_cast<Mesh *
>(geometry);
320 for (
Node *node : mesh->get_used_shaders()) {
324 step_rate =
fminf(shader->get_volume_step_rate(), step_rate);
336 if (geometry->is_volume()) {
348 float voxel_step_size = volume->get_step_size();
350 if (voxel_step_size == 0.0f) {
359 else if (volume->get_object_space()) {
365 if (voxel_step_size > 0.0f) {
366 step_size =
fminf(voxel_step_size, step_size);
378 step_size *= step_rate;
399 if (!(get_visibility() &
409 for (
Node *node : geom->get_used_shaders()) {
420 if (get_receiver_light_set()) {
433 if (get_blocker_shadow_set()) {
458 if (
static_cast<Volume *
>(geom)->get_object_space()) {
470 geom->
is_hair() ?
static_cast<Hair *
>(geom)->get_curve_keys().size() :
491 const float pass_id = ob->pass_id;
492 const float random_number = (
float)ob->random_id * (1.0f / (
float)0xFFFFFFFF);
494 ob->particle_index +
state->particle_offset[ob->particle_system] :
500 kobject.
color[0] = color.
x;
501 kobject.
color[1] = color.
y;
502 kobject.
color[2] = color.
z;
503 kobject.
alpha = ob->alpha;
511 ob->receiver_light_set;
515 ob->blocker_shadow_set;
518 if (geom->get_use_motion_blur()) {
519 state->have_motion =
true;
533 Mesh *mesh =
static_cast<Mesh *
>(geom);
558 tfm_pre = ob->motion[0];
559 tfm_post = ob->motion[ob->motion.size() - 1];
570 tfm_pre = tfm_pre * itfm;
571 tfm_post = tfm_post * itfm;
575 object_motion_pass[motion_pass_offset + 0] = tfm_pre;
576 object_motion_pass[motion_pass_offset + 1] = tfm_post;
583 if (ob->tfm_is_modified() || ob->motion_is_modified() || update_all) {
589 state->have_motion =
true;
597 kobject.
dupli_uv[0] = ob->dupli_uv[0];
598 kobject.
dupli_uv[1] = ob->dupli_uv[1];
604 if (ob->asset_name_is_modified() || update_all) {
607 ob->asset_name.c_str(), ob->asset_name.length(), 0);
620 if (ob->is_caustics_caster) {
623 if (ob->is_caustics_receiver) {
628 if (ob->use_holdout) {
635 state->have_curves =
true;
638 state->have_points =
true;
641 state->have_volumes =
true;
656 if (!scene->
integrator->get_use_light_tree()) {
670 uint32_t prim_offset = 0;
671 if (
Geometry *
const geom = ob->geometry) {
672 if (geom->is_hair()) {
673 prim_offset = ((
Hair *
const)geom)->curve_segment_offset;
676 prim_offset = geom->prim_offset;
680 object_prim_offset[obj_index] = prim_offset;
691 state.have_motion =
false;
692 state.have_curves =
false;
693 state.have_points =
false;
694 state.have_volumes =
false;
696 state.queue_start_object = 0;
700 state.object_motion =
nullptr;
701 state.object_motion_pass =
nullptr;
710 uint motion_offset = 0;
713 *motion_offsets = motion_offset;
718 motion_offset += ob->motion.size();
727 int numparticles = 1;
729 state.particle_offset[psys] = numparticles;
738 static const int OBJECTS_PER_TASK = 32;
739 parallel_for(blocked_range<size_t>(0, scene->
objects.
size(), OBJECTS_PER_TASK),
740 [&](
const blocked_range<size_t> &r) {
741 for (size_t i = r.begin(); i != r.end(); i++) {
742 Object *ob = state.scene->objects[i];
743 device_update_object_transform(&state, ob, update_all, scene);
747 if (progress.get_cancel()) {
751 dscene->objects.copy_to_device_if_modified();
753 dscene->object_motion_pass.copy_to_device();
756 dscene->object_motion.copy_to_device();
759 dscene->data.bvh.have_motion =
state.have_motion;
760 dscene->data.bvh.have_curves =
state.have_curves;
761 dscene->data.bvh.have_points =
state.have_points;
762 dscene->data.bvh.have_volumes =
state.have_volumes;
764 dscene->objects.clear_modified();
765 dscene->object_motion_pass.clear_modified();
766 dscene->object_motion.clear_modified();
810 scene->
update_stats->object.times.add_entry({
"device_update (assign index)", time});
816 object->index = index++;
829 if (!object->get_geometry()->is_light()) {
833 const Light *light =
static_cast<const Light *
>(
object->get_geometry());
835 dscene->
data.background.object_index =
object->index;
845 {
"device_update (copy objects to device)", time});
849 progress.
set_status(
"Updating Objects",
"Copying Transformations to device");
854 object->clear_modified();
870 scene->
update_stats->object.times.add_entry({
"device_update_flags", time});
893 bool has_volume_objects =
false;
895 if (object->geometry->has_volume) {
900 volume_objects.push_back(
object);
902 has_volume_objects =
true;
907 if (object->geometry->has_volume) {
921 if (object->is_shadow_catcher) {
929 object->intersects_volume =
false;
930 for (
Object *volume_object : volume_objects) {
931 if (
object == volume_object) {
936 object->intersects_volume =
true;
941 else if (has_volume_objects) {
972 if (attr_map_offset == 0) {
1010 map<Geometry *, int> geometry_users;
1017 const map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
1019 if (it == geometry_users.end()) {
1020 geometry_users[
object->geometry] = 1;
1045 Mesh *mesh =
static_cast<Mesh *
>(geom);
1056 if (!(motion_blur && object->
use_motion())) {
1058 object->apply_transform(apply_to_motion);
1076 update_flags |=
flag;
1114 string manifest =
"{";
1116 unordered_set<ustring> objects;
1118 if (objects.count(object->
name)) {
1121 objects.insert(object->
name);
1125 manifest[manifest.size() - 1] =
'}';
1131 string manifest =
"{";
1132 unordered_set<ustring> assets;
1134 if (assets.count(ob->asset_name)) {
1137 assets.insert(ob->asset_name);
1139 ob->asset_name.c_str(), ob->asset_name.length(), 0);
1140 manifest +=
string_printf(
"\"%s\":\"%08x\",", ob->asset_name.c_str(), hash_asset);
1142 manifest[manifest.size() - 1] =
'}';
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
list< Attribute > attributes
Attribute * find(ustring name) const
device_vector< DecomposedTransform > object_motion
device_vector< Transform > object_motion_pass
device_vector< float > volume_step_size
device_vector< uint > object_prim_offset
device_vector< uint > object_flag
device_vector< KernelObject > objects
virtual BVHLayoutMask get_bvh_layout_mask(const uint kernel_features) const =0
bool has_true_displacement() const
bool is_pointcloud() const
virtual PrimitiveType primitive_type() const =0
void tag_update(Scene *scene, const uint32_t flag)
void tag_update(Scene *scene, const uint32_t flag)
string get_cryptomatte_objects(Scene *scene)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_object_transform(UpdateObjectTransformState *state, Object *ob, bool update_all, const Scene *scene)
void device_free(Device *device, DeviceScene *dscene, bool force_free)
string get_cryptomatte_assets(Scene *scene)
void device_update_geom_offsets(Device *device, DeviceScene *dscene, Scene *scene)
void device_update_prim_offsets(Device *device, DeviceScene *dscene, Scene *scene)
void device_update_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress, bool bounds_valid=true)
void set_status(const string &status_, const string &substatus_="")
bool has_volume_attribute_dependency
EmissionSampling emission_sampling
bool has_volume_spatial_varying
T * alloc(const size_t width, const size_t height=0)
void free_if_need_realloc(bool force_free)
#define LIGHT_LINK_SET_MAX
#define OBJECT_MOTION_PASS_SIZE
#define LIGHT_LINK_MASK_ALL
#define SHADOW_CATCHER_OBJECT_VISIBILITY(is_shadow_catcher, visibility)
#define CCL_NAMESPACE_END
#define assert(assertion)
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
ccl_device_inline float object_volume_density(KernelGlobals kg, const int object)
ccl_device_inline uint particle_index(KernelGlobals kg, const int particle)
@ ATTR_STD_VOLUME_VELOCITY
@ ATTR_STD_MOTION_VERTEX_POSITION
@ PATH_RAY_VOLUME_SCATTER
@ PATH_RAY_ALL_VISIBILITY
@ SD_OBJECT_HAS_VOLUME_ATTRIBUTES
@ SD_OBJECT_INTERSECTS_VOLUME
@ SD_OBJECT_NEGATIVE_SCALE
@ SD_OBJECT_HAS_VOLUME_MOTION
@ SD_OBJECT_CAUSTICS_RECEIVER
@ SD_OBJECT_SHADOW_CATCHER
@ SD_OBJECT_TRANSFORM_APPLIED
@ SD_OBJECT_HAS_VERTEX_MOTION
@ SD_OBJECT_CAUSTICS_CASTER
@ BVH_LAYOUT_MULTI_HIPRT_EMBREE
@ BVH_LAYOUT_MULTI_METAL_EMBREE
CCL_NAMESPACE_BEGIN ccl_device_inline float2 zero_float2()
ccl_device_inline float reduce_min(const float2 a)
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 one_float3()
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
uint32_t util_murmur_hash3(const void *key, const int len, const uint32_t seed)
float util_hash_to_float(const uint32_t hash)
static void update(bNodeTree *ntree)
#define SOCKET_POINT(name, ui_name, default_value,...)
#define SOCKET_FLOAT(name, ui_name, default_value,...)
#define SOCKET_INT(name, ui_name, default_value,...)
#define SOCKET_NODE(name, ui_name, node_type,...)
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
#define SOCKET_UINT(name, ui_name, default_value,...)
#define NODE_DEFINE(structname)
#define SOCKET_COLOR(name, ui_name, default_value,...)
#define SOCKET_TRANSFORM_ARRAY(name, ui_name, default_value,...)
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
#define SOCKET_POINT2(name, ui_name, default_value,...)
#define SOCKET_STRING(name, ui_name, default_value,...)
#define SOCKET_UINT64(name, ui_name, default_value,...)
static float object_volume_density(const Transform &tfm, Geometry *geom)
static int object_num_motion_verts(Geometry *geom)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
ImageHandle & data_voxel()
BoundBox transformed(const Transform *tfm) const
__forceinline bool intersects(const BoundBox &other)
uint64_t shadow_set_membership
float shadow_terminator_geometry_offset
uint attribute_map_offset
uint64_t light_set_membership
float shadow_terminator_shading_offset
AttributeSet subd_attributes
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
Node(const NodeType *type, ustring name=ustring())
void compute_bounds(bool motion_blur)
NODE_DECLARE BoundBox bounds
bool usable_as_light() const
float shadow_terminator_shading_offset
vector< ParamValue > attributes
int get_device_index() const
int motion_step(const float time) const
void apply_transform(bool apply_to_motion)
float compute_volume_step_size() const
bool has_light_linking() const
float shadow_terminator_geometry_offset
bool is_traceable() const
uint visibility_for_tracing() const
void tag_update(Scene *scene)
float motion_time(const int step) const
bool has_shadow_linking() const
struct LightgroupMembership * lightgroup
unique_ptr< ObjectManager > object_manager
MotionType need_motion() const
unique_ptr< LightManager > light_manager
unique_ptr< SceneUpdateStats > update_stats
void tag_shadow_catcher_modified()
unique_ptr_vector< ParticleSystem > particle_systems
unique_ptr< GeometryManager > geometry_manager
unique_ptr_vector< Object > objects
map< ustring, int > lightgroups
unique_ptr< VolumeManager > volume_manager