[Bf-blender-cvs] [31fda0363d5] temp-angavrilov-constraints: Add Custom Space to Constraints

Henrik Dick noreply at git.blender.org
Wed Dec 2 18:25:37 CET 2020


Commit: 31fda0363d55f9b451427b6693591a1be062e905
Author: Henrik Dick
Date:   Mon Nov 23 19:26:53 2020 +0300
Branches: temp-angavrilov-constraints
https://developer.blender.org/rB31fda0363d55f9b451427b6693591a1be062e905

Add Custom Space to Constraints

Constraints can currently only use World Space, Local Space, Pose Space, Local with Parent.
This patch adds Custom Space with a custom object to define the evaluation space.

The Custom Space option uses the Local Space of an other object/bone/vertex group.
If selected on owner or target it will show a box for object selection.
If an armature is selected, then it will also show a box for bone selection.
If a mesh object is selected it will show the option for using the local space of a vertex group.

It looks like this in the UI:
{F8731291}

The motivation for this patch is the following situation.
If you have a copy location constraint in your armature you are already limited when you want to use a specific axis. It can be done, but its unneccessarily difficult (as far as I know). But the situation is close to impossible as soon as you have a root bone in your armature (which I was told you always want). I need to only copy the location along a custom axis for a lot of things. The same goes for copy rotation/scale and all the limit constraints because I need to make that axis relat [...]

Here is a demo video:
{F8498960}
This is the file of that video:
{F8647541}

This is the file for the tests included in this patch:
{F8699677}

File intended for acceptance test:
{F8879818}

Reviewed By: #animation_rigging, sybren, Severin, angavrilov

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

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

M	release/scripts/startup/bl_ui/properties_constraint.py
M	source/blender/blenkernel/BKE_constraint.h
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/blenkernel/intern/fcurve_driver.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
M	tests/python/bl_constraints.py

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

diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index f46e9f9727f..71a7b056d07 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -85,14 +85,23 @@ class ConstraintButtonsPanel(Panel):
             row.operator("constraint.disable_keep_transform", text="", icon='CANCEL')
 
     @staticmethod
-    def space_template(layout, con, target=True, owner=True):
+    def space_template(layout, con, target=True, owner=True, separator=True):
         if target or owner:
-            layout.separator()
+            if separator:
+                layout.separator()
             if target:
                 layout.prop(con, "target_space", text="Target")
             if owner:
                 layout.prop(con, "owner_space", text="Owner")
 
+            if con.target_space == 'CUSTOM' or con.owner_space == 'CUSTOM':
+                col = layout.column()
+                col.prop(con, "space_object")
+                if con.space_object and con.space_object.type == 'ARMATURE':
+                    col.prop_search(con, "space_subtarget", con.space_object.data, "bones", text="Bone")
+                elif con.space_object and con.space_object.type in {'MESH', 'LATTICE'}:
+                    col.prop_search(con, "space_subtarget", con.space_object, "vertex_groups", text="Vertex Group")
+
     @staticmethod
     def target_template(layout, con, subtargets=True):
         col = layout.column()
@@ -237,7 +246,7 @@ class ConstraintButtonsPanel(Panel):
         row.label(icon="BLANK1")
 
         layout.prop(con, "use_transform_limit")
-        layout.prop(con, "owner_space")
+        self.space_template(layout, con, target=False, owner=True)
 
         self.draw_influence(layout, con)
 
@@ -306,7 +315,7 @@ class ConstraintButtonsPanel(Panel):
         row.prop_decorator(con, "max_z")
 
         layout.prop(con, "use_transform_limit")
-        layout.prop(con, "owner_space")
+        self.space_template(layout, con, target=False, owner=True)
 
         self.draw_influence(layout, con)
 
@@ -375,7 +384,7 @@ class ConstraintButtonsPanel(Panel):
         row.prop_decorator(con, "max_z")
 
         layout.prop(con, "use_transform_limit")
-        layout.prop(con, "owner_space")
+        self.space_template(layout, con, target=False, owner=True)
 
         self.draw_influence(layout, con)
 
@@ -483,7 +492,7 @@ class ConstraintButtonsPanel(Panel):
 
         layout.prop(con, "volume")
 
-        layout.prop(con, "owner_space")
+        self.space_template(layout, con, target=False, owner=True)
 
         self.draw_influence(layout, con)
 
@@ -1117,7 +1126,7 @@ class ConstraintButtonsSubPanel(Panel):
         col = layout.column()
         col.active = not con.use_eval_time
         col.prop(con, "transform_channel", text="Channel")
-        col.prop(con, "target_space")
+        ConstraintButtonsPanel.space_template(col, con, target=True, owner=False, separator=False)
 
         sub = col.column(align=True)
         sub.prop(con, "min", text="Range Min")
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index e5c4535560d..4b9f480e091 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -56,6 +56,8 @@ typedef struct bConstraintOb {
   float matrix[4][4];
   /** original matrix (before constraint solving) */
   float startmat[4][4];
+  /** space matrix for custom object space */
+  float space_obj_world_matrix[4][4];
 
   /** type of owner  */
   short type;
@@ -203,6 +205,7 @@ void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
 
 void BKE_constraint_mat_convertspace(struct Object *ob,
                                      struct bPoseChannel *pchan,
+                                     struct bConstraintOb *cob,
                                      float mat[4][4],
                                      short from,
                                      short to,
@@ -221,6 +224,7 @@ void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph,
                                             struct bConstraintOb *ob,
                                             struct ListBase *targets,
                                             float ctime);
+void BKE_constraint_custom_object_space_get(float r_mat[4][4], struct bConstraint *con);
 void BKE_constraints_solve(struct Depsgraph *depsgraph,
                            struct ListBase *conlist,
                            struct bConstraintOb *cob,
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 5497065bb34..1a16f1d3c6e 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -261,8 +261,13 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
  * of a matrix from one space to another for constraint evaluation.
  * For now, this is only implemented for Objects and PoseChannels.
  */
-void BKE_constraint_mat_convertspace(
-    Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale)
+void BKE_constraint_mat_convertspace(Object *ob,
+                                     bPoseChannel *pchan,
+                                     bConstraintOb *cob,
+                                     float mat[4][4],
+                                     short from,
+                                     short to,
+                                     const bool keep_scale)
 {
   float diff_mat[4][4];
   float imat[4][4];
@@ -282,25 +287,30 @@ void BKE_constraint_mat_convertspace(
     switch (from) {
       case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
       {
-        /* world to pose */
-        invert_m4_m4(imat, ob->obmat);
-        mul_m4_m4m4(mat, imat, mat);
-
-        /* use pose-space as stepping stone for other spaces... */
-        if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
-          /* call self with slightly different values */
-          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+        if (to == CONSTRAINT_SPACE_CUSTOM) {
+          /* World to custom. */
+          BLI_assert(cob);
+          invert_m4_m4(imat, cob->space_obj_world_matrix);
+          mul_m4_m4m4(mat, imat, mat);
+        }
+        else {
+          /* World to pose. */
+          invert_m4_m4(imat, ob->obmat);
+          mul_m4_m4m4(mat, imat, mat);
+
+          /* Use pose-space as stepping stone for other spaces. */
+          if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
+            /* Call self with slightly different values. */
+            BKE_constraint_mat_convertspace(
+                ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+          }
         }
         break;
       }
       case CONSTRAINT_SPACE_POSE: /* ---------- FROM POSESPACE ---------- */
       {
-        /* pose to world */
-        if (to == CONSTRAINT_SPACE_WORLD) {
-          mul_m4_m4m4(mat, ob->obmat, mat);
-        }
         /* pose to local */
-        else if (to == CONSTRAINT_SPACE_LOCAL) {
+        if (to == CONSTRAINT_SPACE_LOCAL) {
           if (pchan->bone) {
             BKE_armature_mat_pose_to_bone(pchan, mat, mat);
           }
@@ -312,6 +322,16 @@ void BKE_constraint_mat_convertspace(
             mul_m4_m4m4(mat, imat, mat);
           }
         }
+        else {
+          /* Pose to world. */
+          mul_m4_m4m4(mat, ob->obmat, mat);
+          /* Use world-space as stepping stone for other spaces. */
+          if (to != CONSTRAINT_SPACE_WORLD) {
+            /* Call self with slightly different values. */
+            BKE_constraint_mat_convertspace(
+                ob, pchan, cob, mat, CONSTRAINT_SPACE_WORLD, to, keep_scale);
+          }
+        }
         break;
       }
       case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
@@ -323,9 +343,10 @@ void BKE_constraint_mat_convertspace(
         }
 
         /* use pose-space as stepping stone for other spaces */
-        if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
+        if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_CUSTOM)) {
           /* call self with slightly different values */
-          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+          BKE_constraint_mat_convertspace(
+              ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
         }
         break;
       }
@@ -337,9 +358,24 @@ void BKE_constraint_mat_convertspace(
         }
 
         /* use pose-space as stepping stone for other spaces */
-        if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
+        if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_CUSTOM)) {
           /* call self with slightly different values */
-          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+          BKE_constraint_mat_convertspace(
+              ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+        }
+        break;
+      }
+      case CONSTRAINT_SPACE_CUSTOM: /* -------------- FROM CUSTOM SPACE ---------- */
+      {
+        /* Custom to world. */
+        BLI_assert(cob);
+        mul_m4_m4m4(mat, cob->space_obj_world_matrix, mat);
+
+        /* Use world-space as stepping stone for other spaces. */
+        if (to != CONSTRAINT_SPACE_WORLD) {
+          /* Call self with slightly different values. */
+          BKE_constraint_mat_convertspace(
+              ob, pchan, cob, mat, CONSTRAINT_SPACE_WORLD, to, keep_scale);
         }
         break;
       }
@@ -347,37 +383,44 @@ void BKE_constraint_mat_convertspace(
   }
   else {
     /* objects */
-    if (from == CONSTRAINT_SPACE_WORLD && to == CONSTRAINT_SPACE_LOCAL) {
-      /* check if object has a parent */
-      if (ob->parent) {
-        /* 'subtract' parent's effects from owner */
-        mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
-        invert_m4_m4_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list