Commit: adff34eed8e5967e4f6fdf8af54ab88377a51369
Author: Alexander Gavrilov
Date:   Fri Dec 11 11:53:25 2020 +0300
Branches: temp-angavrilov-constraints
https://developer.blender.org/rBadff34eed8e5967e4f6fdf8af54ab88377a51369

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.

Owner Local Space 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)

Since the space list is getting long, also add a couple of separators.

Differential Revision: https://developer.blender.org/D9493

===================================================================

M       source/blender/blenkernel/intern/constraint.c
M       source/blender/editors/armature/armature_add.c
M       source/blender/makesdna/DNA_constraint_types.h
M       source/blender/makesrna/intern/rna_constraint.c
M       source/blender/makesrna/intern/rna_object_api.c

===================================================================

diff --git a/source/blender/blenkernel/intern/constraint.c 
b/source/blender/blenkernel/intern/constraint.c
index 9df071be754..5d7ef12dbc2 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 cf5cc1e9ea1..69389bc3af1 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -433,17 +433,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_init(&cob, curcon);
 
   unit_m4(mat);
@@ -827,7 +825,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 5d378bb579f..18b6205dde6 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -742,6 +742,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 acb9bf2ec11..25a529bb328 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 e463323c6dc..024f1a867ce 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)) {

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to