[Bf-blender-cvs] [a6c4e39876d] master: Add Custom Object Space to Constraints

Henrik Dick noreply at git.blender.org
Thu Dec 3 11:26:39 CET 2020


Commit: a6c4e39876d8a0765290312f6d8c0175274114cd
Author: Henrik Dick
Date:   Thu Dec 3 10:42:29 2020 +0100
Branches: master
https://developer.blender.org/rBa6c4e39876d8a0765290312f6d8c0175274114cd

Add Custom Object Space to Constraints

Add Custom Space to the list of space conversions for constraints.

Constraints can use World Space, Local Space, Pose Space, Local with
Parent, and now also 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.

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