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
This commit is contained in:
Sybren A. Stüvel 2020-01-28 14:10:43 +01:00
parent 5a570be9f5
commit 87b551e836
Notes: blender-bot 2023-02-13 23:44:23 +01:00
Referenced by issue #73051, Multiple IK chains influencing the same bone don't work
5 changed files with 37 additions and 3 deletions

View File

@ -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) {

View File

@ -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:

View File

@ -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);

View File

@ -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);

View File

@ -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 */