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:
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
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue