diff options
Diffstat (limited to 'source/blender/depsgraph/intern')
7 files changed, 138 insertions, 23 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 4cbb2ce7060..b6b835bbeec 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -99,6 +99,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" +#include "MOD_nodes.h" + #include "SEQ_iterator.h" #include "SEQ_sequencer.h" @@ -342,6 +344,19 @@ ID *DepsgraphNodeBuilder::ensure_cow_id(ID *id_orig) return id_node->id_cow; } +void DepsgraphNodeBuilder::ensure_modifier_to_geometry_cache_nodes(const NodeHandle *handle) +{ + ID *id = handle->id; + Scene *scene_cow = get_cow_datablock(scene_); + Object *object_cow = get_cow_datablock((Object *)id); + add_operation_node(id, + NodeType::GEOMETRY, + OperationCode::GEOMETRY_WRITE_CACHE, + [scene_cow, object_cow](::Depsgraph *depsgraph) { + BKE_object_write_geometry_cache(depsgraph, scene_cow, object_cow); + }); +} + /* **** Build functions for entity nodes **** */ void DepsgraphNodeBuilder::begin_build() @@ -772,6 +787,18 @@ void DepsgraphNodeBuilder::build_object(int base_index, BuilderWalkUserData data; data.builder = this; BKE_modifiers_foreach_ID_link(object, modifier_walk, &data); + + ModifierUpdateDepsgraphNodesContext ctx = {}; + ctx.scene = scene_; + ctx.object = object; + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); + if (mti->ensureDepsgraphNodes) { + NodeHandle handle{this, &object->id}; + ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle); + mti->ensureDepsgraphNodes(md, &ctx); + } + } } /* Grease Pencil Modifiers. */ if (object->greasepencil_modifiers.first != nullptr) { @@ -1294,27 +1321,34 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) if (rbw->group != nullptr) { build_collection(nullptr, rbw->group); FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) { - if (object->type != OB_MESH) { - continue; - } - if (object->rigidbody_object == nullptr) { - continue; + bool needs_transform_copy = false; + if (object->rigidbody_object && object->type == OB_MESH && + object->rigidbody_object->type != RBO_TYPE_PASSIVE) { + needs_transform_copy = true; } - if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) { - continue; + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + if (md->type == eModifierType_Nodes) { + NodesModifierData *nmd = (NodesModifierData *)md; + if (MOD_nodes_needs_rigid_body_sim(object, nmd)) { + needs_transform_copy = true; + } + } } - /* Create operation for flushing results. */ - /* Object's transform component - where the rigidbody operation - * lives. */ - Object *object_cow = get_cow_datablock(object); - add_operation_node(&object->id, - NodeType::TRANSFORM, - OperationCode::RIGIDBODY_TRANSFORM_COPY, - [scene_cow, object_cow](::Depsgraph *depsgraph) { - BKE_rigidbody_object_sync_transforms(depsgraph, scene_cow, object_cow); - }); + if (needs_transform_copy) { + /* Create operation for flushing results. */ + /* Object's transform component - where the rigidbody operation + * lives. */ + Object *object_cow = get_cow_datablock(object); + add_operation_node(&object->id, + NodeType::TRANSFORM, + OperationCode::RIGIDBODY_TRANSFORM_COPY, + [scene_cow, object_cow](::Depsgraph *depsgraph) { + BKE_rigidbody_object_sync_transforms( + depsgraph, scene_cow, object_cow); + }); + } } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } @@ -1462,12 +1496,13 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object) op_node = add_operation_node(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); op_node->set_as_entry(); /* Geometry evaluation. */ - op_node = add_operation_node(&object->id, - NodeType::GEOMETRY, - OperationCode::GEOMETRY_EVAL, - [scene_cow, object_cow](::Depsgraph *depsgraph) { - BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow); - }); + add_operation_node(&object->id, + NodeType::GEOMETRY, + OperationCode::GEOMETRY_EVAL, + [scene_cow, object_cow](::Depsgraph *depsgraph) { + BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow); + }); + op_node = add_operation_node(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE); op_node->set_as_exit(); /* Materials. */ build_materials(object->mat, object->totcol); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 18e28311132..b3fada2547d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -18,6 +18,7 @@ struct CacheFile; struct Camera; struct Collection; +struct DepsNodeHandle; struct FCurve; struct FreestyleLineSet; struct FreestyleLineStyle; @@ -61,6 +62,16 @@ struct TimeSourceNode; class DepsgraphNodeBuilder : public DepsgraphBuilder { public: + struct NodeHandle { + NodeHandle(DepsgraphNodeBuilder *node_builder, ID *id) : node_builder(node_builder), id(id) + { + BLI_assert(id != nullptr); + } + + DepsgraphNodeBuilder *node_builder; + ID *id; + }; + DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache); ~DepsgraphNodeBuilder(); @@ -70,6 +81,8 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { * one. */ ID *ensure_cow_id(ID *id_orig); + void ensure_modifier_to_geometry_cache_nodes(const NodeHandle *handle); + /* Helper wrapper function which wraps get_cow_id with a needed type cast. */ template<typename T> T *get_cow_datablock(const T *orig) const { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index f36d94c7563..09d9d7448f9 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -308,6 +308,37 @@ void DepsgraphRelationBuilder::add_modifier_to_transform_relation(const DepsNode add_depends_on_transform_relation(id, geometry_key, description); } +void DepsgraphRelationBuilder::add_modifier_to_geometry_cache_relation( + const DepsNodeHandle *handle, const char *description) +{ + IDNode *id_node = handle->node->owner->owner; + ID *id = id_node->id_orig; + ComponentKey geometry_key(id, NodeType::GEOMETRY); + OperationKey write_cache_key(id, NodeType::GEOMETRY, OperationCode::GEOMETRY_WRITE_CACHE); + handle->builder->add_relation(geometry_key, write_cache_key, "Object Geometry Write Cache"); +} + +void DepsgraphRelationBuilder::add_modifier_to_rigid_body_sim_relation( + const DepsNodeHandle *handle, const char *description) +{ + IDNode *id_node = handle->node->owner->owner; + ID *id = id_node->id_orig; + OperationKey geometry_eval_key(id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + OperationKey geometry_done_key(id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE); + OperationKey write_cache_key(id, NodeType::GEOMETRY, OperationCode::GEOMETRY_WRITE_CACHE); + OperationKey rb_simulate_key(&scene_->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_SIM); + OperationKey rb_transform_copy_key( + id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); + /* Simulation only after evaluating nodes. */ + add_relation(geometry_eval_key, rb_simulate_key, description); + /* Rigid body synchronization depends on the actual simulation. */ + add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync"); + /* Wait for simulation results to be copied before writing to cache. */ + add_relation(rb_transform_copy_key, write_cache_key, description); + /* Consider geometry valid only after copying rigidbody results. */ + add_relation(rb_transform_copy_key, geometry_done_key, description, RELATION_FLAG_NO_FLUSH); +} + void DepsgraphRelationBuilder::add_customdata_mask(Object *object, const DEGCustomDataMeshMasks &customdata_masks) { @@ -2194,6 +2225,9 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) /* Link components to each other. */ add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data"); OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + OperationKey obdata_evaldone_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE); + /* Exit dependency */ + add_relation(obdata_ubereval_key, obdata_evaldone_key, "Object Eval Done"); /* Special case: modifiers evaluation queries scene for various things like * data mask to be used. We add relation here to ensure object is never * evaluated prior to Scene's CoW is ready. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 0cb0b60dfb0..65d06fc4c23 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -177,6 +177,9 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { * Takes care of checking for possible physics solvers modifying position * of this object. */ void add_modifier_to_transform_relation(const DepsNodeHandle *handle, const char *description); + void add_modifier_to_geometry_cache_relation(const DepsNodeHandle *handle, const char *description); + void add_modifier_to_rigid_body_sim_relation(const DepsNodeHandle *handle, + const char *description); void add_customdata_mask(Object *object, const DEGCustomDataMeshMasks &customdata_masks); void add_special_eval_flag(ID *id, uint32_t flag); diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index a207c13d646..8dc84809516 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -30,6 +30,7 @@ #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_debug.h" +#include "builder/deg_builder_nodes.h" #include "builder/deg_builder_relations.h" #include "builder/pipeline_all_objects.h" #include "builder/pipeline_compositor.h" @@ -67,6 +68,11 @@ static deg::NodeType deg_build_scene_component_type(eDepsSceneComponentType comp return deg::NodeType::UNDEFINED; } +static deg::DepsgraphNodeBuilder::NodeHandle *get_node_builder_handle(DepsNodeHandle *node_handle) +{ + return reinterpret_cast<deg::DepsgraphNodeBuilder::NodeHandle *>(node_handle); +} + static deg::DepsNodeHandle *get_node_handle(DepsNodeHandle *node_handle) { return reinterpret_cast<deg::DepsNodeHandle *>(node_handle); @@ -206,6 +212,26 @@ void DEG_add_modifier_to_transform_relation(struct DepsNodeHandle *node_handle, deg_node_handle->builder->add_modifier_to_transform_relation(deg_node_handle, description); } +void DEG_ensure_modifier_to_geometry_cache_nodes(struct DepsNodeHandle *node_handle) +{ + deg::DepsgraphNodeBuilder::NodeHandle *deg_node_handle = get_node_builder_handle(node_handle); + deg_node_handle->node_builder->ensure_modifier_to_geometry_cache_nodes(deg_node_handle); +} + +void DEG_add_modifier_to_geometry_cache_relation(struct DepsNodeHandle *node_handle, + const char *description) +{ + deg::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle); + deg_node_handle->builder->add_modifier_to_geometry_cache_relation(deg_node_handle, description); +} + +void DEG_add_modifier_to_rigid_body_sim_relation(struct DepsNodeHandle *node_handle, + const char *description) +{ + deg::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle); + deg_node_handle->builder->add_modifier_to_rigid_body_sim_relation(deg_node_handle, description); +} + void DEG_add_special_eval_flag(struct DepsNodeHandle *node_handle, ID *id, uint32_t flag) { deg::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle); diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index 3029379d141..e7d6cbe487e 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -90,6 +90,8 @@ const char *operationCodeAsString(OperationCode opcode) return "GEOMETRY_EVAL_DONE"; case OperationCode::GEOMETRY_SHAPEKEY: return "GEOMETRY_SHAPEKEY"; + case OperationCode::GEOMETRY_WRITE_CACHE: + return "GEOMETRY_WRITE_CACHE"; /* Object data. */ case OperationCode::LIGHT_PROBE_EVAL: return "LIGHT_PROBE_EVAL"; diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 656b27550f6..07116e85bc0 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -91,6 +91,8 @@ enum class OperationCode { /* Evaluation of a shape key. * NOTE: Currently only for object data data-blocks. */ GEOMETRY_SHAPEKEY, + /* Write geometry output into the runtime cache. */ + GEOMETRY_WRITE_CACHE, /* Object data. --------------------------------------------------------- */ LIGHT_PROBE_EVAL, |