diff options
Diffstat (limited to 'source/blender/depsgraph')
5 files changed, 83 insertions, 35 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index eb2ed0e637d..8c349b7067f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -261,7 +261,18 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible) object_cow, pchan_index), DEG_OPCODE_BONE_DONE); + + /* B-Bone shape computation - the real last step if present. */ + if (pchan->bone != NULL && pchan->bone->segments > 1) { + op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name, + function_bind(BKE_pose_eval_bbone_segments, _1, + object_cow, + pchan_index), + DEG_OPCODE_BONE_SEGMENTS); + } + op_node->set_as_exit(); + /* Custom properties. */ if (pchan->prop != NULL) { add_operation_node(&object->id, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 8f579216518..5e1ebee337c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -206,6 +206,17 @@ static eDepsOperation_Code bone_target_opcode(ID *target, return DEG_OPCODE_BONE_DONE; } +static bool bone_has_segments(Object *object, const char *bone_name) +{ + /* Proxies don't have BONE_SEGMENTS */ + if (ID_IS_LINKED(object) && object->proxy_from != NULL) { + return false; + } + /* Only B-Bones have segments. */ + bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name); + return pchan && pchan->bone && pchan->bone->segments > 1; +} + /* **** General purpose functions **** */ DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain, @@ -1017,39 +1028,20 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, /* relation to bone */ opcode = bone_target_opcode(&ct->tar->id, ct->subtarget, id, component_subdata, root_map); + /* Armature constraint always wants the final position and chan_mat. */ + if (ELEM(con->type, CONSTRAINT_TYPE_ARMATURE)) { + opcode = DEG_OPCODE_BONE_DONE; + } + /* if needs bbone shape, reference the segment computation */ + if (BKE_constraint_target_uses_bbone(con, ct) && + bone_has_segments(ct->tar, ct->subtarget)) { + opcode = DEG_OPCODE_BONE_SEGMENTS; + } 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 (BKE_constraint_target_uses_bbone(con, ct)) { - 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); - } - } - } } else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) 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 1abed8bb6a2..1260ce013ea 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -488,10 +488,41 @@ void DepsgraphRelationBuilder::build_rig(Object *object) * For IK chains however, an additional rel is created from IK * to done, with transitive reduction removing this one. */ add_relation(bone_ready_key, bone_done_key, "Ready -> Done"); - /* Assume that all bones must be done for the pose to be ready - * (for deformers). */ - add_relation(bone_done_key, pose_done_key, "PoseEval Result-Bone Link"); - add_relation(bone_done_key, pose_cleanup_key, "Cleanup dependency"); + /* B-Bone shape is the real final step after Done if present. */ + if (pchan->bone != NULL && pchan->bone->segments > 1) { + OperationKey bone_segments_key(&object->id, + DEG_NODE_TYPE_BONE, + pchan->name, + DEG_OPCODE_BONE_SEGMENTS); + /* B-Bone shape depends on the final position of the bone. */ + add_relation(bone_done_key, bone_segments_key, "Done -> B-Bone Segments"); + /* B-Bone shape depends on final position of handle bones. */ + bPoseChannel *prev, *next; + BKE_pchan_get_bbone_handles(pchan, &prev, &next); + if (prev) { + OperationKey prev_key(&object->id, + DEG_NODE_TYPE_BONE, + prev->name, + DEG_OPCODE_BONE_DONE); + add_relation(prev_key, bone_segments_key, "Prev Handle -> B-Bone Segments"); + } + if (next) { + OperationKey next_key(&object->id, + DEG_NODE_TYPE_BONE, + next->name, + DEG_OPCODE_BONE_DONE); + add_relation(next_key, bone_segments_key, "Next Handle -> B-Bone Segments"); + } + /* Pose requires the B-Bone shape. */ + add_relation(bone_segments_key, pose_done_key, "PoseEval Result-Bone Link"); + add_relation(bone_segments_key, pose_cleanup_key, "Cleanup dependency"); + } + else { + /* Assume that all bones must be done for the pose to be ready + * (for deformers). */ + add_relation(bone_done_key, pose_done_key, "PoseEval Result-Bone Link"); + add_relation(bone_done_key, pose_cleanup_key, "Cleanup dependency"); + } /* Custom shape. */ if (pchan->custom != NULL) { build_object(NULL, pchan->custom); @@ -537,9 +568,20 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object) add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done"); /* Make sure bone in the proxy is not done before it's FROM is done. */ - add_relation(from_bone_done_key, - bone_done_key, - "From Bone Done -> Pose Done"); + if (pchan->bone && pchan->bone->segments > 1) { + OperationKey from_bone_segments_key(&proxy_from->id, + DEG_NODE_TYPE_BONE, + pchan->name, + DEG_OPCODE_BONE_SEGMENTS); + add_relation(from_bone_segments_key, + bone_done_key, + "From Bone Segments -> Bone Done"); + } + else { + add_relation(from_bone_done_key, + bone_done_key, + "From Bone Done -> Bone Done"); + } if (pchan->prop != NULL) { OperationKey bone_parameters(&object->id, diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index 44e21656570..3f36b9f7831 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -157,6 +157,7 @@ const char *operationCodeAsString(eDepsOperation_Code opcode) STRINGIFY_OPCODE(BONE_CONSTRAINTS); STRINGIFY_OPCODE(BONE_READY); STRINGIFY_OPCODE(BONE_DONE); + STRINGIFY_OPCODE(BONE_SEGMENTS); /* Particles. */ STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL_INIT); STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL); diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index d81483526ed..f8b519cb1aa 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -254,6 +254,8 @@ typedef enum eDepsOperation_Code { // TODO: deform mats could get calculated in the final_transform ops... DEG_OPCODE_BONE_READY, DEG_OPCODE_BONE_DONE, + /* B-Bone segment shape computation (after DONE) */ + DEG_OPCODE_BONE_SEGMENTS, /* Particles. --------------------------------------- */ /* Particle System evaluation. */ |