[Bf-blender-cvs] [1854cccad7c] master: Drivers: add an Average Scale option to the Transform Channel driver vars.

Alexander Gavrilov noreply at git.blender.org
Mon May 6 18:16:56 CEST 2019


Commit: 1854cccad7c31a6b8235faf980ffdd6a80163e02
Author: Alexander Gavrilov
Date:   Sun May 5 13:25:43 2019 +0300
Branches: master
https://developer.blender.org/rB1854cccad7c31a6b8235faf980ffdd6a80163e02

Drivers: add an Average Scale option to the Transform Channel driver vars.

Unlike location and rotation, there is a meaningful definition of
overall/average scaling via the total change in the volume. This
adds an option to retrieve that via a single driver variable,
instead of having to use three and an expression.

Using the determinant to compute the volume scaling also allows
detecting flipping due to negative scale - this is impossible
to do via the three variable approach.

The volume_scale functions are added purely for code readability:
'volume scale factor' is easier to understand than determinant.

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

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

M	source/blender/blenkernel/intern/fcurve.c
M	source/blender/blenlib/BLI_math_matrix.h
M	source/blender/blenlib/intern/math_matrix.c
M	source/blender/makesdna/DNA_anim_types.h
M	source/blender/makesrna/intern/rna_fcurve.c

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

diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 8c95e4c7ff3..e2d0a479792 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1707,6 +1707,11 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
     /* not valid channel */
     return 0.0f;
   }
+  else if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) {
+    /* Cubic root of the change in volume, equal to the geometric mean
+     * of scale over all three axes unless the matrix includes shear. */
+    return cbrtf(mat4_to_volume_scale(mat));
+  }
   else if (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) {
     /* Extract scale, and choose the right axis,
      * inline 'mat4_to_size'. */
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 652f096f32d..cc3159556bf 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -260,6 +260,7 @@ float determinant_m2(float a, float b, float c, float d);
 float determinant_m3(
     float a, float b, float c, float d, float e, float f, float g, float h, float i);
 float determinant_m3_array(const float m[3][3]);
+float determinant_m4_mat3_array(const float m[4][4]);
 float determinant_m4(const float A[4][4]);
 
 #define PSEUDOINVERSE_EPSILON 1e-8f
@@ -277,6 +278,9 @@ void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4]);
 void scale_m3_fl(float R[3][3], float scale);
 void scale_m4_fl(float R[4][4], float scale);
 
+float mat3_to_volume_scale(const float M[3][3]);
+float mat4_to_volume_scale(const float M[4][4]);
+
 float mat3_to_scale(const float M[3][3]);
 float mat4_to_scale(const float M[4][4]);
 float mat4_to_xy_scale(const float M[4][4]);
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index e09fae7d140..0fd947b6b1a 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -931,6 +931,13 @@ float determinant_m3_array(const float m[3][3])
           m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
 }
 
+float determinant_m4_mat3_array(const float m[4][4])
+{
+  return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
+          m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
+          m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
+}
+
 bool invert_m3_ex(float m[3][3], const float epsilon)
 {
   float tmp[3][3];
@@ -1641,6 +1648,19 @@ void mat4_to_size(float size[3], const float mat[4][4])
   size[2] = len_v3(mat[2]);
 }
 
+/* This computes the overall volume scale factor of a transformation matrix.
+ * For an orthogonal matrix, it is the product of all three scale values.
+ * Returns a negative value if the transform is flipped by negative scale. */
+float mat3_to_volume_scale(const float mat[3][3])
+{
+  return determinant_m3_array(mat);
+}
+
+float mat4_to_volume_scale(const float mat[4][4])
+{
+  return determinant_m4_mat3_array(mat);
+}
+
 /* this gets the average scale of a matrix, only use when your scaling
  * data that has no idea of scale axis, examples are bone-envelope-radius
  * and curve radius */
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index c76d4895b25..fbb720ad0b1 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -357,6 +357,7 @@ typedef enum eDriverTarget_TransformChannels {
   DTAR_TRANSCHAN_SCALEX,
   DTAR_TRANSCHAN_SCALEY,
   DTAR_TRANSCHAN_SCALEZ,
+  DTAR_TRANSCHAN_SCALE_AVG,
 
   MAX_DTAR_TRANSCHAN_TYPES,
 } eDriverTarget_TransformChannels;
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index c8df01a7dc7..d9917b670d9 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1645,6 +1645,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
       {DTAR_TRANSCHAN_SCALEX, "SCALE_X", 0, "X Scale", ""},
       {DTAR_TRANSCHAN_SCALEY, "SCALE_Y", 0, "Y Scale", ""},
       {DTAR_TRANSCHAN_SCALEZ, "SCALE_Z", 0, "Z Scale", ""},
+      {DTAR_TRANSCHAN_SCALE_AVG, "SCALE_AVG", 0, "Average Scale", ""},
       {0, NULL, 0, NULL, NULL},
   };



More information about the Bf-blender-cvs mailing list