improvement to axis/angle gimble conversion added last commit. fixed flipping problem...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 1 Nov 2010 11:50:15 +0000 (11:50 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 1 Nov 2010 11:50:15 +0000 (11:50 +0000)
source/blender/editors/transform/transform_manipulator.c

index 5bce18ef5f78e254f0fd6c5807dfc37c94d40ff4..73b58b51ffcbedc1df2ff1f02144e10feebef190 100644 (file)
@@ -156,6 +156,37 @@ static void stats_editbone(RegionView3D *rv3d, EditBone *ebo)
                protectflag_to_drawflags(OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE, &rv3d->twdrawflag);
 }
 
+/* could move into BLI_math however this is only useful for display/editing purposes */
+static void axis_angle_to_gimbal_axis(float gmat[3][3], float axis[3], float angle)
+{
+       /* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
+
+       float cross_vec[3];
+       float quat[4];
+
+       /* this is an un-scientific method to get a vector to cross with
+        * XYZ intentionally YZX */
+       cross_vec[0]= axis[1];
+       cross_vec[1]= axis[2];
+       cross_vec[2]= axis[0];
+
+       /* X-axis */
+       cross_v3_v3v3(gmat[0], cross_vec, axis);
+       normalize_v3(gmat[0]);
+       axis_angle_to_quat(quat, axis, angle);
+       mul_qt_v3(quat, gmat[0]);
+
+       /* Y-axis */
+       axis_angle_to_quat(quat, axis, M_PI/2.0);
+       copy_v3_v3(gmat[1], gmat[0]);
+       mul_qt_v3(quat, gmat[1]);
+
+       /* Z-axis */
+       copy_v3_v3(gmat[2], axis);
+
+       normalize_m3(gmat);
+}
+
 
 static int test_rotmode_euler(short rotmode)
 {
@@ -169,10 +200,18 @@ int gimbal_axis(Object *ob, float gmat[][3])
                {
                        bPoseChannel *pchan= get_active_posechannel(ob);
 
-                       if(pchan && test_rotmode_euler(pchan->rotmode)) {
+                       if(pchan) {
                                float mat[3][3], tmat[3][3], obmat[3][3];
+                               if(test_rotmode_euler(pchan->rotmode)) {
+                                       eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
+                               }
+                               else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+                                       axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
+                               }
+                               else { /* quat */
+                                       return 0;
+                               }
 
-                               eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
 
                                /* apply bone transformation */
                                mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
@@ -204,34 +243,7 @@ int gimbal_axis(Object *ob, float gmat[][3])
                                eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
                        }
                        else if(ob->rotmode == ROT_MODE_AXISANGLE) {
-                               /* X/Y are arbitrary axies, most importantly Z is the axis of rotation
-                                * there is also an axis flipping problem if the rotation axis points
-                                * exactly on Z and Y value is modified. */
-                               float cross_vec[3]= {0};
-                               float quat[4];
-
-                               if(ob->rotAxis[0] || ob->rotAxis[1]) {
-                                       cross_vec[2]= 1.0f;
-                               }
-                               else {
-                                       cross_vec[0]= 1.0f; /* could be X or Y */
-                               }
-
-                               /* X-axis */
-                               cross_v3_v3v3(gmat[0], cross_vec, ob->rotAxis);
-                               normalize_v3(gmat[0]);
-                               axis_angle_to_quat(quat, ob->rotAxis, ob->rotAngle);
-                               mul_qt_v3(quat, gmat[0]);
-
-                               /* Y-axis */
-                               axis_angle_to_quat(quat, ob->rotAxis, M_PI/2.0);
-                               copy_v3_v3(gmat[1], gmat[0]);
-                               mul_qt_v3(quat, gmat[1]);
-
-                               /* Z-axis */
-                               copy_v3_v3(gmat[2], ob->rotAxis);
-
-                               normalize_m3(gmat);
+                               axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
                        }
                        else { /* quat */
                                return 0;