diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2018-08-09 17:17:40 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2018-08-13 19:02:49 +0300 |
commit | a5aeca4a64dfd2ec6d0d68acf2fd9e4a9498558d (patch) | |
tree | 22a4b37f06121e36ee35c14046835f08ba702d81 /source/blender/depsgraph | |
parent | ff6bd57873ec11f7748bc74bf3d628b3cbe38f70 (diff) |
Fix dependency graph for constraints depending on B-Bone shape.
Some constraints have an option to take the final bezier shape of
the target B-Bone into account. This shape usually depends on two
other bones in addition to the target itself, so the graph should
include the relevant dependencies.
Reviewers: sergey
Differential Revision: https://developer.blender.org/D3591
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_relations.cc | 83 |
1 files changed, 52 insertions, 31 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 147e80cc794..2efe14557a6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -185,6 +185,23 @@ static bool check_id_has_anim_component(ID *id) (!BLI_listbase_is_empty(&adt->nla_tracks)); } +static eDepsOperation_Code bone_target_opcode(ID *target, const char *subtarget, ID *id, const char *component_subdata, RootPChanMap *root_map) +{ + /* same armature */ + if (target == id) { + /* Using "done" here breaks in-chain deps, while using + * "ready" here breaks most production rigs instead. + * So, we do a compromise here, and only do this when an + * IK chain conflict may occur. + */ + if (root_map->has_common_root(component_subdata, subtarget)) { + return DEG_OPCODE_BONE_READY; + } + } + + return DEG_OPCODE_BONE_DONE; +} + /* **** General purpose functions **** */ DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain, @@ -907,38 +924,42 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, add_relation(target_transform_key, constraint_op_key, cti->name); } else if ((ct->tar->type == OB_ARMATURE) && (ct->subtarget[0])) { - /* bone */ - if (&ct->tar->id == id) { - /* same armature */ - eDepsOperation_Code target_key_opcode; - /* Using "done" here breaks in-chain deps, while using - * "ready" here breaks most production rigs instead. - * So, we do a compromise here, and only do this when an - * IK chain conflict may occur. - */ - if (root_map->has_common_root(component_subdata, - ct->subtarget)) - { - target_key_opcode = DEG_OPCODE_BONE_READY; - } - else { - target_key_opcode = DEG_OPCODE_BONE_DONE; + eDepsOperation_Code opcode; + /* relation to bone */ + opcode = bone_target_opcode(&ct->tar->id, ct->subtarget, + id, component_subdata, root_map); + OperationKey target_key(&ct->tar->id, + DEG_NODE_TYPE_BONE, + ct->subtarget, + opcode); + add_relation(target_key, constraint_op_key, cti->name); + /* if needs bbone shape, also reference handles */ + if (con->flag & CONSTRAINT_BBONE_SHAPE) { + bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget); + /* actually a bbone */ + if (pchan && pchan->bone && pchan->bone->segments > 1) { + bPoseChannel *prev, *next; + BKE_pchan_get_bbone_handles(pchan, &prev, &next); + /* add handle links */ + if (prev) { + opcode = bone_target_opcode(&ct->tar->id, prev->name, + id, component_subdata, root_map); + OperationKey prev_key(&ct->tar->id, + DEG_NODE_TYPE_BONE, + prev->name, + opcode); + add_relation(prev_key, constraint_op_key, cti->name); + } + if (next) { + opcode = bone_target_opcode(&ct->tar->id, next->name, + id, component_subdata, root_map); + OperationKey next_key(&ct->tar->id, + DEG_NODE_TYPE_BONE, + next->name, + opcode); + add_relation(next_key, constraint_op_key, cti->name); + } } - OperationKey target_key(&ct->tar->id, - DEG_NODE_TYPE_BONE, - ct->subtarget, - target_key_opcode); - add_relation(target_key, constraint_op_key, cti->name); - } - else { - /* Different armature - we can safely use the result - * of that. - */ - OperationKey target_key(&ct->tar->id, - DEG_NODE_TYPE_BONE, - ct->subtarget, - DEG_OPCODE_BONE_DONE); - add_relation(target_key, constraint_op_key, cti->name); } } else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && |