diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-04-14 13:44:12 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-04-14 18:59:27 +0300 |
commit | 6a59e123649105a07316c87ac4dcc78a87fed532 (patch) | |
tree | ab2eb7cdefd190ecbfc14b685afa7b4f932e8f57 /source/blender/depsgraph | |
parent | 3380fb364677ed4695be74272777fd676520d721 (diff) |
Fix T59622: dependency problems with Spline IK.
The bug is caused by problems in the dependency graph. Unfortunately,
fixing is not just a matter of fixing the graph, because correct
dependencies would cause a cycle here and in other reasonable use
cases. The real fix thus requires refactoring Spline IK to require
curve data only in the actual evaluation phase, and not in POSE_INIT_IK.
In addition, this separates the normal bone evaluation loop from
Spline IK computations for two reasons:
- That still needs to be done even if spline IK can't evaluate
due to missing curve data.
- It should reduce issues with induced shearing, as Spline IK now
controls how parent-child relations are handled in the chain, and
can take care to only carry over rotation and location.
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc | 46 |
1 files changed, 17 insertions, 29 deletions
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 ed1ae5631ad..9fd4a8dc802 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -261,8 +261,10 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object, RELATION_FLAG_GODMODE); /* Attach path dependency to solver. */ if (data->tar != NULL) { - ComponentKey target_key(&data->tar->id, NodeType::GEOMETRY); - add_relation(target_key, init_ik_key, "Curve.Path -> Spline IK"); + ComponentKey target_geometry_key(&data->tar->id, NodeType::GEOMETRY); + add_relation(target_geometry_key, solver_key, "Curve.Path -> Spline IK"); + ComponentKey target_transform_key(&data->tar->id, NodeType::TRANSFORM); + add_relation(target_transform_key, solver_key, "Curve.Transform -> Spline IK"); add_special_eval_flag(&data->tar->id, DAG_EVAL_NEED_CURVE_PATH); } pchan->flag |= POSE_DONE; @@ -271,41 +273,27 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object, add_relation(solver_key, final_transforms_key, "Spline IK Result"); root_map->add_bone(pchan->name, rootchan->name); /* Walk to the chain's root/ */ - int segcount = 0; + int segcount = 1; for (bPoseChannel *parchan = pchan->parent; - parchan != NULL; - parchan = parchan->parent) + parchan != NULL && segcount < data->chainlen; + parchan = parchan->parent, segcount++) { /* Make Spline IK solver dependent on this bone's result, since it can * only run after the standard results of the bone are know. Validate * links step on the bone will ensure that users of this bone only grab * the result with IK solver results. */ - if (parchan != pchan) { - OperationKey parent_key(&object->id, - NodeType::BONE, - parchan->name, - OperationCode::BONE_READY); - add_relation(parent_key, solver_key, "Spline IK Solver Update"); - OperationKey bone_done_key(&object->id, - NodeType::BONE, - parchan->name, - OperationCode::BONE_DONE); - add_relation(solver_key, bone_done_key, "IK Chain Result"); - } + OperationKey parent_key(&object->id, + NodeType::BONE, + parchan->name, + OperationCode::BONE_READY); + add_relation(parent_key, solver_key, "Spline IK Solver Update"); + OperationKey bone_done_key(&object->id, + NodeType::BONE, + parchan->name, + OperationCode::BONE_DONE); + add_relation(solver_key, bone_done_key, "Spline IK Solver Result"); parchan->flag |= POSE_DONE; - OperationKey final_transforms_key(&object->id, - NodeType::BONE, - parchan->name, - OperationCode::BONE_DONE); - add_relation( - solver_key, final_transforms_key, "Spline IK Solver Result"); root_map->add_bone(parchan->name, rootchan->name); - /* TODO(sergey): This is an arbitrary value, which was just following - * old code convention. */ - segcount++; - if ((segcount == data->chainlen) || (segcount > 255)) { - break; - } } OperationKey pose_done_key( &object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE); |