Drivers: support accessing Quaternion rotation channels.
authorAlexander Gavrilov <angavrilov@gmail.com>
Sat, 31 Aug 2019 17:27:19 +0000 (20:27 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Sat, 31 Aug 2019 17:53:32 +0000 (20:53 +0300)
After adding the Euler order option, it's an easy addition to
the enum. The list of channels had of course to be expanded too.

source/blender/blenkernel/intern/fcurve.c
source/blender/makesdna/DNA_anim_types.h
source/blender/makesrna/intern/rna_fcurve.c

index dec410c819261043bde5210aad7959e4a1308154..ef53c926daa9acc4a86d71fc0e25e0bb65f4f394 100644 (file)
@@ -1714,7 +1714,10 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
      * 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) {
+  else if (ELEM(dtar->transChan,
+                DTAR_TRANSCHAN_SCALEX,
+                DTAR_TRANSCHAN_SCALEY,
+                DTAR_TRANSCHAN_SCALEZ)) {
     /* Extract scale, and choose the right axis,
      * inline 'mat4_to_size'. */
     return len_v3(mat[dtar->transChan - DTAR_TRANSCHAN_SCALEX]);
@@ -1728,7 +1731,18 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
      *     b) [NOT USED] directly use the original values (no decomposition)
      *         - only an option for "transform space", if quality is really bad with a)
      */
-    float eul[3];
+    float quat[4];
+    float *const eul = quat + 1;
+    int channel;
+
+    if (dtar->transChan == DTAR_TRANSCHAN_ROTW) {
+      channel = 0;
+      quat[0] = 0.0f;
+    }
+    else {
+      channel = 1 + dtar->transChan - DTAR_TRANSCHAN_ROTX;
+      BLI_assert(channel < 4);
+    }
 
     if (dtar->rotation_mode == DTAR_ROTMODE_AUTO) {
       mat4_to_eulO(eul, rot_order, mat);
@@ -1741,12 +1755,15 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
              dtar->rotation_mode <= DTAR_ROTMODE_EULER_MAX) {
       mat4_to_eulO(eul, dtar->rotation_mode, mat);
     }
+    else if (dtar->rotation_mode == DTAR_ROTMODE_QUATERNION) {
+      mat4_to_quat(quat, mat);
+    }
     else {
       BLI_assert(false);
       zero_v3(eul);
     }
 
-    return eul[dtar->transChan - DTAR_TRANSCHAN_ROTX];
+    return quat[channel];
   }
   else {
     /* extract location and choose right axis */
index 8c25d470a36eb8feaec8a9fa175d4f5c6fa6f133..be4850d67794123821273ece2021a71f0206053f 100644 (file)
@@ -362,6 +362,7 @@ typedef enum eDriverTarget_TransformChannels {
   DTAR_TRANSCHAN_SCALEY,
   DTAR_TRANSCHAN_SCALEZ,
   DTAR_TRANSCHAN_SCALE_AVG,
+  DTAR_TRANSCHAN_ROTW,
 
   MAX_DTAR_TRANSCHAN_TYPES,
 } eDriverTarget_TransformChannels;
@@ -379,6 +380,8 @@ typedef enum eDriverTarget_RotationMode {
   DTAR_ROTMODE_EULER_ZXY,
   DTAR_ROTMODE_EULER_ZYX,
 
+  DTAR_ROTMODE_QUATERNION,
+
   DTAR_ROTMODE_EULER_MIN = DTAR_ROTMODE_EULER_XYZ,
   DTAR_ROTMODE_EULER_MAX = DTAR_ROTMODE_EULER_ZYX,
 } eDriverTarget_RotationMode;
index 6cb3a18605c8b3bfd385a6583e0cffd417ea55b1..684c786b1b9021c2cf55488e965738c0930e7ac2 100644 (file)
@@ -1674,6 +1674,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
       {DTAR_TRANSCHAN_ROTX, "ROT_X", 0, "X Rotation", ""},
       {DTAR_TRANSCHAN_ROTY, "ROT_Y", 0, "Y Rotation", ""},
       {DTAR_TRANSCHAN_ROTZ, "ROT_Z", 0, "Z Rotation", ""},
+      {DTAR_TRANSCHAN_ROTW, "ROT_W", 0, "W Rotation", ""},
       {DTAR_TRANSCHAN_SCALEX, "SCALE_X", 0, "X Scale", ""},
       {DTAR_TRANSCHAN_SCALEY, "SCALE_Y", 0, "Y Scale", ""},
       {DTAR_TRANSCHAN_SCALEZ, "SCALE_Z", 0, "Z Scale", ""},
@@ -1709,6 +1710,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
       {DTAR_ROTMODE_EULER_YZX, "YZX", 0, "YZX Euler", "Euler using the YZX rotation order"},
       {DTAR_ROTMODE_EULER_ZXY, "ZXY", 0, "ZXY Euler", "Euler using the ZXY rotation order"},
       {DTAR_ROTMODE_EULER_ZYX, "ZYX", 0, "ZYX Euler", "Euler using the ZYX rotation order"},
+      {DTAR_ROTMODE_QUATERNION, "QUATERNION", 0, "Quaternion", "Quaternion rotation"},
       {0, NULL, 0, NULL, NULL},
   };