Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2021-06-27 23:15:57 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2021-07-02 15:15:05 +0300
commit5a693ce9e396f04d88140d8e015fcace7eddc6c2 (patch)
treefec38890821b4b256aa5b531b5e2f12a8d804c25 /source/blender/blenkernel/intern/constraint.c
parentbc8ae58727bf078df1fc5803a9de5c9eb984aeb7 (diff)
Constraints: support a new Local Space (Owner Orientation) for targets.
Add a new transformation space choice for bone constraints, which represent the local transformation of the target bone in the constraint owner's local space. The use case for this is transferring the local (i.e. excluding the effect of parents) motion of one bone to another one, while ignoring the difference between their rest pose orientations. The new option replaces the following setup: * A `child` bone of the `target`, rotated the same as `owner` in rest pose. * A `sibling` bone of the `target`, positioned same as `child` in rest pose and using Copy Transforms in World Space from `child`. * The `owner` bone constraint uses Local Space of `sibling`. (This analogy applies provided both bones use Local Location) Differential Revision: https://developer.blender.org/D9493
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r--source/blender/blenkernel/intern/constraint.c74
1 files changed, 67 insertions, 7 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);