[Bf-blender-cvs] [e858d21ae42] master: Transformation Constraint: implement a Mix Mode option.

Alexander Gavrilov noreply at git.blender.org
Fri Sep 6 11:54:35 CEST 2019


Commit: e858d21ae42386c57c7f5b4b0982642173f460e5
Author: Alexander Gavrilov
Date:   Fri Sep 6 11:54:34 2019 +0300
Branches: master
https://developer.blender.org/rBe858d21ae42386c57c7f5b4b0982642173f460e5

Transformation Constraint: implement a Mix Mode option.

Allow selecting how the new location/rotation/scale is combined with
the existing transformation. This is most useful for rotation, which
has multiple options, and scale, which previously could only replace.

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

M	release/scripts/startup/bl_ui/properties_constraint.py
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/editors/transform/transform_convert.c
M	source/blender/makesdna/DNA_constraint_types.h
M	source/blender/makesrna/intern/rna_constraint.c

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

diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index df53fccf9ea..dce2d2f2758 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -761,6 +761,8 @@ class ConstraintButtonsPanel:
         sub.prop(con, "to_min_z" + ext, text="Min")
         sub.prop(con, "to_max_z" + ext, text="Max")
 
+        layout.prop(con, "mix_mode" + ext, text="Mix")
+
         self.space_template(layout, con)
 
     def SHRINKWRAP(self, _context, layout, con):
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 58011c8d753..9b32996aa96 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3802,7 +3802,8 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
   /* only evaluate if there is a target */
   if (VALID_CONS_TARGET(ct)) {
     float *from_min, *from_max, *to_min, *to_max;
-    float loc[3], eul[3], size[3];
+    float loc[3], rot[3][3], oldeul[3], size[3];
+    float newloc[3], newrot[3][3], neweul[3], newsize[3];
     float dbuf[4], sval[3];
     float *const dvec = dbuf + 1;
     int i;
@@ -3844,9 +3845,7 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
     }
 
     /* extract components of owner's matrix */
-    copy_v3_v3(loc, cob->matrix[3]);
-    mat4_to_eulO(eul, rot_order, cob->matrix);
-    mat4_to_size(size, cob->matrix);
+    mat4_to_loc_rot_size(loc, rot, size, cob->matrix);
 
     /* determine where in range current transforms lie */
     if (data->expo) {
@@ -3878,18 +3877,42 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
         to_min = data->to_min_scale;
         to_max = data->to_max_scale;
         for (i = 0; i < 3; i++) {
-          /* multiply with original scale (so that it can still be scaled) */
-          /* size[i] *= to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])); */
-          /* Stay absolute, else it breaks existing rigs... sigh. */
-          size[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
+          newsize[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
+        }
+        switch (data->mix_mode_scale) {
+          case TRANS_MIXSCALE_MULTIPLY:
+            mul_v3_v3(size, newsize);
+            break;
+          case TRANS_MIXSCALE_REPLACE:
+          default:
+            copy_v3_v3(size, newsize);
+            break;
         }
         break;
       case TRANS_ROTATION:
         to_min = data->to_min_rot;
         to_max = data->to_max_rot;
         for (i = 0; i < 3; i++) {
-          /* add to original rotation (so that it can still be rotated) */
-          eul[i] += to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
+          neweul[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
+        }
+        switch (data->mix_mode_rot) {
+          case TRANS_MIXROT_REPLACE:
+            eulO_to_mat3(rot, neweul, rot_order);
+            break;
+          case TRANS_MIXROT_BEFORE:
+            eulO_to_mat3(newrot, neweul, rot_order);
+            mul_m3_m3m3(rot, newrot, rot);
+            break;
+          case TRANS_MIXROT_AFTER:
+            eulO_to_mat3(newrot, neweul, rot_order);
+            mul_m3_m3m3(rot, rot, newrot);
+            break;
+          case TRANS_MIXROT_ADD:
+          default:
+            mat3_to_eulO(oldeul, rot_order, rot);
+            add_v3_v3(neweul, oldeul);
+            eulO_to_mat3(rot, neweul, rot_order);
+            break;
         }
         break;
       case TRANS_LOCATION:
@@ -3897,14 +3920,22 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
         to_min = data->to_min;
         to_max = data->to_max;
         for (i = 0; i < 3; i++) {
-          /* add to original location (so that it can still be moved) */
-          loc[i] += (to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])));
+          newloc[i] = (to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])));
+        }
+        switch (data->mix_mode_loc) {
+          case TRANS_MIXLOC_REPLACE:
+            copy_v3_v3(loc, newloc);
+            break;
+          case TRANS_MIXLOC_ADD:
+          default:
+            add_v3_v3(loc, newloc);
+            break;
         }
         break;
     }
 
     /* apply to matrix */
-    loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, rot_order);
+    loc_rot_size_to_mat4(cob->matrix, loc, rot, size);
   }
 }
 
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index cbb291414bf..6da03d917a6 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -1348,11 +1348,13 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list)
           /* Transform constraint needs it for rotation at least (r.57309),
            * but doing so when translating may also mess things up [#36203]
            */
+          bTransformConstraint *data = (bTransformConstraint *)con->data;
 
-          if (t->mode == TFM_ROTATION) {
-            return true;
+          if (data->to == TRANS_ROTATION) {
+            if (t->mode == TFM_ROTATION && data->mix_mode_rot == TRANS_MIXROT_BEFORE) {
+              return true;
+            }
           }
-          /* ??? (t->mode == TFM_SCALE) ? */
         }
       }
     }
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index d123cf21db9..83fc4d2a3f7 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -450,7 +450,12 @@ typedef struct bTransformConstraint {
   /** Output euler order override. */
   char to_euler_order;
 
-  char _pad[6];
+  /** Mixing modes for location, rotation, and scale. */
+  char mix_mode_loc;
+  char mix_mode_rot;
+  char mix_mode_scale;
+
+  char _pad[3];
 
   /** From_min/max defines range of target transform. */
   float from_min[3];
@@ -809,6 +814,34 @@ typedef enum eTransform_ToFrom {
   TRANS_SCALE = 2,
 } eTransform_ToFrom;
 
+/* bTransformConstraint.mix_mode_loc */
+typedef enum eTransform_MixModeLoc {
+  /* Add component values together (default). */
+  TRANS_MIXLOC_ADD = 0,
+  /* Replace component values. */
+  TRANS_MIXLOC_REPLACE,
+} eTransform_MixModeLoc;
+
+/* bTransformConstraint.mix_mode_rot */
+typedef enum eTransform_MixModeRot {
+  /* Add component values together (default). */
+  TRANS_MIXROT_ADD = 0,
+  /* Replace component values. */
+  TRANS_MIXROT_REPLACE,
+  /* Multiply the generated rotation on the left. */
+  TRANS_MIXROT_BEFORE,
+  /* Multiply the generated rotation on the right. */
+  TRANS_MIXROT_AFTER,
+} eTransform_MixModeRot;
+
+/* bTransformConstraint.mix_mode_scale */
+typedef enum eTransform_MixModeScale {
+  /* Replace component values (default). */
+  TRANS_MIXSCALE_REPLACE = 0,
+  /* Multiply component values together. */
+  TRANS_MIXSCALE_MULTIPLY,
+} eTransform_MixModeScale;
+
 /* bSameVolumeConstraint.free_axis */
 typedef enum eSameVolume_Axis {
   SAMEVOL_X = 0,
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 658addece8a..7732bf531d8 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1934,6 +1934,34 @@ static void rna_def_constraint_transform(BlenderRNA *brna)
       {0, NULL, 0, NULL, NULL},
   };
 
+  static const EnumPropertyItem mix_mode_loc_items[] = {
+      {TRANS_MIXLOC_REPLACE, "REPLACE", 0, "Replace", "Replace component values"},
+      {TRANS_MIXLOC_ADD, "ADD", 0, "Add", "Add component values together"},
+      {0, NULL, 0, NULL, NULL},
+  };
+
+  static const EnumPropertyItem mix_mode_rot_items[] = {
+      {TRANS_MIXROT_REPLACE, "REPLACE", 0, "Replace", "Replace component values"},
+      {TRANS_MIXROT_ADD, "ADD", 0, "Add", "Add component values together"},
+      {TRANS_MIXROT_BEFORE,
+       "BEFORE",
+       0,
+       "Before Original",
+       "Apply new rotation before original, as if it was on a parent"},
+      {TRANS_MIXROT_AFTER,
+       "AFTER",
+       0,
+       "After Original",
+       "Apply new rotation after original, as if it was on a child"},
+      {0, NULL, 0, NULL, NULL},
+  };
+
+  static const EnumPropertyItem mix_mode_scale_items[] = {
+      {TRANS_MIXSCALE_REPLACE, "REPLACE", 0, "Replace", "Replace component values"},
+      {TRANS_MIXSCALE_MULTIPLY, "MULTIPLY", 0, "Multiply", "Multiply component values together"},
+      {0, NULL, 0, NULL, NULL},
+  };
+
   srna = RNA_def_struct(brna, "TransformConstraint", "Constraint");
   RNA_def_struct_ui_text(
       srna, "Transformation Constraint", "Map transformations of the target to the object");
@@ -2066,6 +2094,13 @@ static void rna_def_constraint_transform(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "To Maximum Z", "Top range of Z axis destination motion");
   RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
 
+  prop = RNA_def_property(srna, "mix_mode", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "mix_mode_loc");
+  RNA_def_property_enum_items(prop, mix_mode_loc_items);
+  RNA_def_property_ui_text(
+      prop, "Location Mix Mode", "Specify how to combine the new location with original");
+  RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
   /* Rot */
   prop = RNA_def_property(srna, "from_min_x_rot", PROP_FLOAT, PROP_ANGLE);
   RNA_def_property_float_sdna(prop, NULL, "from_min_rot[0]");
@@ -2139,6 +2174,13 @@ static void rna_def_constraint_transform(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "To Maximum Z", "Top range of Z axis destination motion");
   RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
 
+  prop = RNA_def_property(srna, "mix_mode_rot", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "mix_mode_rot");
+  RNA_def_prope

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list