diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 74 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_add.c | 10 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_constraint.c | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_api.c | 3 |
5 files changed, 86 insertions, 13 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 41da728fa5b..fa6329af33f 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -299,7 +299,10 @@ void BKE_constraint_mat_convertspace(Object *ob, mul_m4_m4m4(mat, imat, mat); /* Use pose-space as stepping stone for other spaces. */ - if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) { + if (ELEM(to, + CONSTRAINT_SPACE_LOCAL, + CONSTRAINT_SPACE_PARLOCAL, + CONSTRAINT_SPACE_OWNLOCAL)) { /* Call self with slightly different values. */ BKE_constraint_mat_convertspace( ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale); @@ -315,6 +318,17 @@ void BKE_constraint_mat_convertspace(Object *ob, BKE_armature_mat_pose_to_bone(pchan, mat, mat); } } + /* pose to owner local */ + else if (to == CONSTRAINT_SPACE_OWNLOCAL) { + /* pose to local */ + if (pchan->bone) { + BKE_armature_mat_pose_to_bone(pchan, mat, mat); + } + + /* local to owner local (recursive) */ + BKE_constraint_mat_convertspace( + ob, pchan, cob, mat, CONSTRAINT_SPACE_LOCAL, to, keep_scale); + } /* pose to local with parent */ else if (to == CONSTRAINT_SPACE_PARLOCAL) { if (pchan->bone) { @@ -336,17 +350,59 @@ void BKE_constraint_mat_convertspace(Object *ob, } case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */ { + /* local to owner local */ + if (to == CONSTRAINT_SPACE_OWNLOCAL) { + if (pchan->bone) { + copy_m4_m4(diff_mat, pchan->bone->arm_mat); + + if (cob && cob->pchan && cob->pchan->bone) { + invert_m4_m4(imat, cob->pchan->bone->arm_mat); + mul_m4_m4m4(diff_mat, imat, diff_mat); + } + + zero_v3(diff_mat[3]); + invert_m4_m4(imat, diff_mat); + mul_m4_series(mat, diff_mat, mat, imat); + } + } /* local to pose - do inverse procedure that was done for pose to local */ + else { + if (pchan->bone) { + /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */ + BKE_armature_mat_bone_to_pose(pchan, mat, mat); + } + + /* use pose-space as stepping stone for other spaces */ + if (ELEM(to, + CONSTRAINT_SPACE_WORLD, + CONSTRAINT_SPACE_PARLOCAL, + CONSTRAINT_SPACE_CUSTOM)) { + /* call self with slightly different values */ + BKE_constraint_mat_convertspace( + ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale); + } + } + break; + } + case CONSTRAINT_SPACE_OWNLOCAL: { /* -------------- FROM OWNER LOCAL ---------- */ + /* owner local to local */ if (pchan->bone) { - /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */ - BKE_armature_mat_bone_to_pose(pchan, mat, mat); + copy_m4_m4(diff_mat, pchan->bone->arm_mat); + + if (cob && cob->pchan && cob->pchan->bone) { + invert_m4_m4(imat, cob->pchan->bone->arm_mat); + mul_m4_m4m4(diff_mat, imat, diff_mat); + } + + zero_v3(diff_mat[3]); + invert_m4_m4(imat, diff_mat); + mul_m4_series(mat, imat, mat, diff_mat); } - /* use pose-space as stepping stone for other spaces */ - if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_CUSTOM)) { + if (to != CONSTRAINT_SPACE_LOCAL) { /* call self with slightly different values */ BKE_constraint_mat_convertspace( - ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale); + ob, pchan, cob, mat, CONSTRAINT_SPACE_LOCAL, to, keep_scale); } break; } @@ -358,7 +414,11 @@ void BKE_constraint_mat_convertspace(Object *ob, } /* use pose-space as stepping stone for other spaces */ - if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_CUSTOM)) { + if (ELEM(to, + CONSTRAINT_SPACE_WORLD, + CONSTRAINT_SPACE_LOCAL, + CONSTRAINT_SPACE_OWNLOCAL, + CONSTRAINT_SPACE_CUSTOM)) { /* call self with slightly different values */ BKE_constraint_mat_convertspace( ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale); diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 0ee11a6ef55..baa279dea11 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -438,17 +438,15 @@ static void updateDuplicateSubtarget(EditBone *dup_bone, } } -static void updateDuplicateActionConstraintSettings(EditBone *dup_bone, - EditBone *orig_bone, - Object *ob, - bConstraint *curcon) +static void updateDuplicateActionConstraintSettings( + EditBone *dup_bone, EditBone *orig_bone, Object *ob, bPoseChannel *pchan, bConstraint *curcon) { bActionConstraint *act_con = (bActionConstraint *)curcon->data; bAction *act = (bAction *)act_con->act; float mat[4][4]; - bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = NULL}; + bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan}; BKE_constraint_custom_object_space_get(cob.space_obj_world_matrix, curcon); unit_m4(mat); @@ -832,7 +830,7 @@ static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig for (curcon = conlist->first; curcon; curcon = curcon->next) { switch (curcon->type) { case CONSTRAINT_TYPE_ACTION: - updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, curcon); + updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, pchan, curcon); break; case CONSTRAINT_TYPE_KINEMATIC: updateDuplicateKinematicConstraintSettings(curcon); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 25f72da2f15..6531933af23 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -741,6 +741,8 @@ typedef enum eBConstraint_SpaceTypes { CONSTRAINT_SPACE_POSE = 2, /** For posechannels - local with parent. */ CONSTRAINT_SPACE_PARLOCAL = 3, + /** For posechannels - local converted to the owner bone orientation. */ + CONSTRAINT_SPACE_OWNLOCAL = 6, /** For files from between 2.43-2.46 (should have been parlocal). */ CONSTRAINT_SPACE_INVALID = 4, /* do not exchange for anything! */ } eBConstraint_SpaceTypes; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index d34885e1a68..28aef635688 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -206,6 +206,7 @@ static const EnumPropertyItem target_space_pchan_items[] = { "Custom Space", "The transformation of the target is evaluated relative to a custom object/bone/vertex " "group"}, + {0, "", 0, NULL, NULL}, {CONSTRAINT_SPACE_POSE, "POSE", 0, @@ -224,6 +225,14 @@ static const EnumPropertyItem target_space_pchan_items[] = { "Local Space", "The transformation of the target is evaluated relative to its local " "coordinate system"}, + {CONSTRAINT_SPACE_OWNLOCAL, + "LOCAL_OWNER_ORIENT", + 0, + "Local Space (Owner Orientation)", + "The transformation of the target bone is evaluated relative to its local coordinate " + "system, followed by a correction for the difference in target and owner rest pose " + "orientations. When applied as local transform to the owner produces the same global " + "motion as the target if the parents are still in rest pose"}, {0, NULL, 0, NULL, NULL}, }; @@ -238,6 +247,7 @@ static const EnumPropertyItem owner_space_pchan_items[] = { 0, "Custom Space", "The constraint is applied in local space of a custom object/bone/vertex group"}, + {0, "", 0, NULL, NULL}, {CONSTRAINT_SPACE_POSE, "POSE", 0, diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 4608b0c1bac..10ba2b9acb1 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -303,6 +303,9 @@ static void rna_Object_mat_convert_space(Object *ob, { copy_m4_m4((float(*)[4])mat_ret, (float(*)[4])mat); + BLI_assert(!ELEM(from, CONSTRAINT_SPACE_OWNLOCAL)); + BLI_assert(!ELEM(to, CONSTRAINT_SPACE_OWNLOCAL)); + /* Error in case of invalid from/to values when pchan is NULL */ if (pchan == NULL) { if (ELEM(from, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) { |