Depsgraph: Fix cycle with rigid body and Weight Proximity
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 20 Mar 2019 15:35:23 +0000 (16:35 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 20 Mar 2019 15:37:15 +0000 (16:37 +0100)
The issue is a feedback loop with point cache reset operation.

Solved by introducing extra node which ensures object's transformation
is ready for simulator input. Allows to route relations without causing
a fake dependency cycle now.

source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/node/deg_node_operation.cc
source/blender/depsgraph/intern/node/deg_node_operation.h

index 09a79db..39806d2 100644 (file)
@@ -1072,8 +1072,11 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
                        if (object->type != OB_MESH) {
                                continue;
                        }
-                       /* 2) create operation for flushing results */
-                       /* object's transform component - where the rigidbody operation
+                       add_operation_node(&object->id,
+                                          NodeType::TRANSFORM,
+                                          OperationCode::TRANSFORM_SIMULATION_INIT);
+                       /* Create operation for flushing results. */
+                       /* Object's transform component - where the rigidbody operation
                         * lives. */
                        add_operation_node(&object->id,
                                           NodeType::TRANSFORM,
index b10736c..d4bd63f 100644 (file)
@@ -934,9 +934,10 @@ void DepsgraphRelationBuilder::build_object_pointcache(Object *object)
                int flag = -1;
                if (ptcache_id->type == PTCACHE_TYPE_RIGIDBODY) {
                        flag = FLAG_TRANSFORM;
-                       OperationKey transform_key(&object->id,
-                                                  NodeType::TRANSFORM,
-                                                  OperationCode::TRANSFORM_LOCAL);
+                       OperationKey transform_key(
+                               &object->id,
+                               NodeType::TRANSFORM,
+                               OperationCode::TRANSFORM_SIMULATION_INIT);
                        add_relation(point_cache_key,
                                     transform_key,
                                     "Point Cache -> Rigid Body");
@@ -1731,11 +1732,19 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
                                     "Rigidbody Sim Eval -> RBO Sync");
                        /* Simulation uses object transformation after parenting and solving
                         * contraints. */
+                       OperationKey object_transform_simulation_init_key(
+                               &object->id,
+                               NodeType::TRANSFORM,
+                               OperationCode::TRANSFORM_SIMULATION_INIT);
                        OperationKey object_transform_eval_key(
                                &object->id,
                                NodeType::TRANSFORM,
                                OperationCode::TRANSFORM_EVAL);
+
                        add_relation(object_transform_eval_key,
+                                    object_transform_simulation_init_key,
+                                    "Object Transform -> Simulation Init");
+                       add_relation(object_transform_simulation_init_key,
                                     rb_simulate_key,
                                     "Object Transform -> Rigidbody Sim Eval");
                        /* Geometry must be known to create the rigid body. RBO_MESH_BASE
index 893c108..b0b47f8 100644 (file)
@@ -61,6 +61,8 @@ const char *operationCodeAsString(OperationCode opcode)
                        return "TRANSFORM_CONSTRAINTS";
                case OperationCode::TRANSFORM_FINAL: return "TRANSFORM_FINAL";
                case OperationCode::TRANSFORM_EVAL: return "TRANSFORM_EVAL";
+               case OperationCode::TRANSFORM_SIMULATION_INIT:
+                       return "TRANSFORM_SIMULATION_INIT";
                /* Rigid body. */
                case OperationCode::RIGIDBODY_REBUILD: return "RIGIDBODY_REBUILD";
                case OperationCode::RIGIDBODY_SIM: return "RIGIDBODY_SIM";
index c6db7b0..56207b0 100644 (file)
@@ -76,6 +76,10 @@ enum class OperationCode {
        TRANSFORM_CONSTRAINTS,
        /* Handle object-level updates, mainly proxies hacks and recalc flags.  */
        TRANSFORM_EVAL,
+       /* Initializes transformation for simulation.
+        * For example, ensures point cache is properly reset before doing rigid
+        * body simulation. */
+       TRANSFORM_SIMULATION_INIT,
        /* Transform exit point */
        TRANSFORM_FINAL,