From 87b551e8365954d03d1c27303b9776deefd4e4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 28 Jan 2020 14:10:43 +0100 Subject: Fix T73051: Multiple IK chains influencing the same bone don't work This patch fixes {T73051}. The cause of the issue was the absence of relations in the depsgraph between IK solvers of overlapping IK chains. Reviewed By: sergey, brecht Differential Revision: https://developer.blender.org/D6700 --- .../intern/builder/deg_builder_pchanmap.cc | 2 +- .../intern/builder/deg_builder_pchanmap.h | 2 +- .../intern/builder/deg_builder_relations.cc | 2 +- .../intern/builder/deg_builder_relations.h | 4 +++ .../intern/builder/deg_builder_relations_rig.cc | 30 ++++++++++++++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) (limited to 'source/blender/depsgraph') diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc index 95c50c4f44e..23402c68698 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc @@ -91,7 +91,7 @@ void RootPChanMap::add_bone(const char *bone, const char *root) } /* Check if there's a common root bone between two bones. */ -bool RootPChanMap::has_common_root(const char *bone1, const char *bone2) +bool RootPChanMap::has_common_root(const char *bone1, const char *bone2) const { /* Ensure that both are in the map... */ if (BLI_ghash_haskey(map_, bone1) == false) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h index 0c1d22f9345..1442f547b08 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h @@ -39,7 +39,7 @@ struct RootPChanMap { void add_bone(const char *bone, const char *root); /* Check if there's a common root bone between two bones. */ - bool has_common_root(const char *bone1, const char *bone2); + bool has_common_root(const char *bone1, const char *bone2) const; protected: /* The actual map: diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 582176a852d..d01e8d8eddd 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -203,7 +203,7 @@ bool check_id_has_anim_component(ID *id) bool check_id_has_driver_component(ID *id) { AnimData *adt = BKE_animdata_from_id(id); - if (adt == nullptr) { + if (adt == NULL) { return false; } return !BLI_listbase_is_empty(&adt->drivers); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 81bc82c036a..5c543ce9c23 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -257,6 +257,10 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { bPoseChannel *pchan, bConstraint *con, RootPChanMap *root_map); + virtual void build_inter_ik_chains(Object *object, + const OperationKey &solver_key, + const bPoseChannel *rootchan, + const RootPChanMap *root_map); virtual void build_rig(Object *object); virtual void build_proxy_rig(Object *object); virtual void build_shapekeys(Key *key); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index e254f8df0d2..4a86b16627c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -192,6 +192,9 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object, } OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE); add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link"); + + /* Add relation when the root of this IK chain is influenced by another IK chain. */ + build_inter_ik_chains(object, solver_key, rootchan, root_map); } /* Spline IK Eval Steps */ @@ -244,6 +247,33 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object, } OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE); add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link"); + + /* Add relation when the root of this IK chain is influenced by another IK chain. */ + build_inter_ik_chains(object, solver_key, rootchan, root_map); +} + +void DepsgraphRelationBuilder::build_inter_ik_chains(Object *object, + const OperationKey &solver_key, + const bPoseChannel *rootchan, + const RootPChanMap *root_map) +{ + bPoseChannel *deepest_root = NULL; + const char *root_name = rootchan->name; + + /* Find shared IK chain root. */ + for (bPoseChannel *parchan = rootchan->parent; parchan; parchan = parchan->parent) { + if (!root_map->has_common_root(root_name, parchan->name)) { + break; + } + deepest_root = parchan; + } + if (deepest_root == NULL) { + return; + } + + OperationKey other_bone_key( + &object->id, NodeType::BONE, deepest_root->name, OperationCode::BONE_DONE); + add_relation(other_bone_key, solver_key, "IK Chain Overlap"); } /* Pose/Armature Bones Graph */ -- cgit v1.2.3