diff options
author | Sebastian Parborg <darkdefende@gmail.com> | 2020-08-28 15:51:54 +0300 |
---|---|---|
committer | Sebastian Parborg <darkdefende@gmail.com> | 2020-08-28 15:55:59 +0300 |
commit | 8726354d465ae0930adcab9ba818414681cee077 (patch) | |
tree | c0849a36eec6bd0d39f5b0e9331cb56bd34ec04b /source | |
parent | 0852ecd844f8dda21623774d3aa7dc372e81be2f (diff) |
Fix Rigidbody depsgraph passive and constraint transform relations.
We need to have transforms from passive objects if they are animated or
driven by parent relations. This is not immediately obvious as the
object transform matrix will still be available, it is just one frame
behind in some cases.
Fixed dependency cycles if there is a constraint between two rigid
bodies. Because bullet keeps track of its simulated bodies, we do not
need to supply objects transforms as bullet should already have them.
I need combine these two fixes because otherwise we will get depsgraph
warnings that nodes are missing that it expects to be there.
Reviewed By: Sergey, Jacques
Differential Revision: http://developer.blender.org/D8732
Diffstat (limited to 'source')
4 files changed, 39 insertions, 51 deletions
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index c2059144388..ae1e437cd60 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -143,6 +143,7 @@ void BKE_rigidbody_aftertrans_update(struct Object *ob, float rotAngle); void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime); bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime); +bool BKE_rigidbody_is_affected_by_simulation(struct Object *ob); void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw); void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, struct Scene *scene, float ctime); void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, struct Scene *scene, float ctime); diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index ece7d0f9136..13c791ffa85 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1901,21 +1901,33 @@ bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->shared->pointcache->startframe); } -/* Sync rigid body and object transformations */ -void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) +bool BKE_rigidbody_is_affected_by_simulation(Object *ob) { - RigidBodyOb *rbo = ob->rigidbody_object; + /* Check if the object will have its transform changed by the rigidbody simulation. */ /* True if the shape of this object's parent is of type compound */ bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL && ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND); - /* keep original transform for kinematic and passive objects */ - if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE || + RigidBodyOb *rbo = ob->rigidbody_object; + if (rbo == NULL || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE || obCompoundParent) { + return false; + } + + return true; +} + +/* Sync rigid body and object transformations */ +void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) +{ + if (!BKE_rigidbody_is_affected_by_simulation(ob)) { + /* Don't sync transforms for objects that are not affected/changed by the simulation. */ return; } + RigidBodyOb *rbo = ob->rigidbody_object; + /* use rigid body transform after cache start frame if objects is not being transformed */ if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->base_flag & BASE_SELECTED && G.moving & G_TRANSFORM_OBJ)) { @@ -1941,8 +1953,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) void BKE_rigidbody_aftertrans_update( Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) { + bool correct_delta = BKE_rigidbody_is_affected_by_simulation(ob); RigidBodyOb *rbo = ob->rigidbody_object; - bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE); /* return rigid body and object to their initial states */ copy_v3_v3(rbo->pos, ob->loc); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 2669de87bc4..670827dc4d8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -1129,9 +1129,11 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) if (object->rigidbody_object == nullptr) { continue; } - if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) { + + if (!BKE_rigidbody_is_affected_by_simulation(object)) { continue; } + /* Create operation for flushing results. */ /* Object's transform component - where the rigidbody operation * lives. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 6feebe6f542..5f637a92069 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1703,9 +1703,6 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) if (object->rigidbody_object == nullptr) { continue; } - if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) { - continue; - } if (object->parent != nullptr && object->parent->rigidbody_object != nullptr && object->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) { @@ -1716,10 +1713,6 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) continue; } - OperationKey rb_transform_copy_key( - &object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - /* Rigid body synchronization depends on the actual simulation. */ - add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync"); /* Simulation uses object transformation after parenting and solving constraints. */ OperationKey object_transform_simulation_init_key( &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); @@ -1737,47 +1730,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY); add_relation(object_geometry_key, rb_simulate_key, - "Object Geom Eval -> Rigidbody Rebuild", + "Object Geom Eval -> Rigidbody Sim Eval", RELATION_FLAG_GODMODE); } + /* Final transform is whetever solver gave to us. */ - OperationKey object_transform_final_key( - &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL); - add_relation( - rb_transform_copy_key, object_transform_final_key, "Rigidbody Sync -> Transform Final"); - } - FOREACH_COLLECTION_OBJECT_RECURSIVE_END; - } - /* Constraints. */ - if (rbw->constraints != nullptr) { - FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { - RigidBodyCon *rbc = object->rigidbody_constraint; - if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) { - /* When either ob1 or ob2 is nullptr, the constraint doesn't - * work. */ - continue; - } - /* Make sure indirectly linked objects are fully built. */ - build_object(object); - build_object(rbc->ob1); - build_object(rbc->ob2); - /* final result of the constraint object's transform controls how - * the constraint affects the physics sim for these objects. */ - ComponentKey trans_key(&object->id, NodeType::TRANSFORM); - if (rbc->ob1->rigidbody_object->type == RBO_TYPE_ACTIVE) { - OperationKey ob1_key( - &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - /* Constrained-objects sync depends on the constraint-holder. */ - add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1"); - } - if (rbc->ob2->rigidbody_object->type == RBO_TYPE_ACTIVE) { - OperationKey ob2_key( - &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - /* Constrained-objects sync depends on the constraint-holder. */ - add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2"); + if (BKE_rigidbody_is_affected_by_simulation(object)) { + /* We do not have to update the objects final transform after the simulation if it is + * passive or controlled by the animation system in blender. + * (Bullet doesn't move the object at all in these cases) + */ + OperationKey rb_transform_copy_key( + &object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); + /* Rigid body synchronization depends on the actual simulation. */ + add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync"); + + OperationKey object_transform_final_key( + &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL); + add_relation(rb_transform_copy_key, + object_transform_final_key, + "Rigidbody Sync -> Transform Final"); } - /* Ensure that sim depends on this constraint's transform. */ - add_relation(trans_key, rb_simulate_key, "RigidBodyConstraint Transform -> RB Simulation"); } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } |