Simplify gimbal axis code and make gimbal orientation work correctly with parents...
authorMartin Poirier <theeth@yahoo.com>
Sun, 1 Nov 2009 21:10:54 +0000 (21:10 +0000)
committerMartin Poirier <theeth@yahoo.com>
Sun, 1 Nov 2009 21:10:54 +0000 (21:10 +0000)
source/blender/blenlib/intern/arithb.c
source/blender/editors/transform/transform_manipulator.c

index fe8f97b4bcf63c66aff1f34e2c998f7e30b5bccf..874756135e59ac3279f68f5f9a3dfd577ffb63ff 100644 (file)
@@ -3471,28 +3471,25 @@ void EulToGimbalAxis(float gmat[][3], float *eul, short order)
 {
        RotOrderInfo *R= GET_ROTATIONORDER_INFO(order);
 
-       float quat[4];
+       float mat[3][3];
        float teul[3];
-       float tvec[3];
-       int i, a;
-
-       for(i= 0; i<3; i++) {
-               tvec[0]= tvec[1]= tvec[2]= 0.0f;
-               tvec[i] = 1.0f;
-
-               VecCopyf(teul, eul);
-
-               /* TODO - only works on XYZ and ZXY */
-               for(a= R->axis[i]; a >= 1; a--)
-                       teul[R->axis[a-1]]= 0.0f;
-
-               EulOToQuat(teul, order, quat);
-               NormalQuat(quat);
-               QuatMulVecf(quat, tvec);
-               Normalize(tvec);
 
-               VecCopyf(gmat[i], tvec);
-       }
+       /* first axis is local */
+       EulOToMat3(eul, order, mat);
+       VecCopyf(gmat[R->axis[0]], mat[R->axis[0]]);
+       
+       /* second axis is local minus first rotation */
+       VecCopyf(teul, eul);
+       teul[R->axis[0]] = 0;
+       EulOToMat3(teul, order, mat);
+       VecCopyf(gmat[R->axis[1]], mat[R->axis[1]]);
+       
+       
+       /* Last axis is global */
+       gmat[R->axis[2]][0] = 0;
+       gmat[R->axis[2]][1] = 0;
+       gmat[R->axis[2]][2] = 0;
+       gmat[R->axis[2]][R->axis[2]] = 1;
 }
 
 /* ************ AXIS ANGLE *************** */
index 4d48c2c0158e75efa2882ff3a11ebeded68841e4..357e164961d07c116df70e6337ae7949af0d02d6 100644 (file)
@@ -197,34 +197,51 @@ void gimbal_axis(Object *ob, float gmat[][3])
                }
 
                if(pchan) {
-                       int i;
+                       float mat[3][3], tmat[3][3], obmat[3][3];
 
-                       EulToGimbalAxis(gmat, pchan->eul, pchan->rotmode);
+                       EulToGimbalAxis(mat, pchan->eul, pchan->rotmode);
 
-                       for (i=0; i<3; i++)
-                               Mat3MulVecfl(pchan->bone->bone_mat, gmat[i]);
-
-                       if(pchan->parent) {
-                               bPoseChannel *pchan_par= pchan->parent;
+                       /* apply bone transformation */
+                       Mat3MulMat3(tmat, pchan->bone->bone_mat, mat);
+                       
+                       if (pchan->parent)
+                       {
+                               float parent_mat[3][3];
 
-                               float tmat[3][3];
-                               Mat3CpyMat4(tmat, pchan_par->pose_mat);
+                               Mat3CpyMat4(parent_mat, pchan->parent->pose_mat);
+                               Mat3MulMat3(mat, parent_mat, tmat);
 
-                               for (i=0; i<3; i++)
-                                       Mat3MulVecfl(tmat, gmat[i]);
+                               /* needed if object transformation isn't identity */
+                               Mat3CpyMat4(obmat, ob->obmat);
+                               Mat3MulMat3(gmat, obmat, mat);
                        }
-
-                       /* needed if object trans isnt identity */
-                       for (i=0; i<3; i++) {
-                               float tmat[3][3];
-                               Mat3CpyMat4(tmat, ob->obmat);
-                               Mat3MulVecfl(tmat, gmat[i]);
+                       else
+                       {
+                               /* needed if object transformation isn't identity */
+                               Mat3CpyMat4(obmat, ob->obmat);
+                               Mat3MulMat3(gmat, obmat, tmat);
                        }
+
+                       Mat3Ortho(gmat);
                }
        }
        else {
                if(test_rotmode_euler(ob->rotmode)) {
-                       EulToGimbalAxis(gmat, ob->rot, ob->rotmode);
+                       
+                       
+                       if (ob->parent)
+                       {
+                               float parent_mat[3][3], amat[3][3];
+                               
+                               EulToGimbalAxis(amat, ob->rot, ob->rotmode);
+                               Mat3CpyMat4(parent_mat, ob->parent->obmat);
+                               Mat3Ortho(parent_mat);
+                               Mat3MulMat3(gmat, parent_mat, amat);
+                       }
+                       else
+                       {
+                               EulToGimbalAxis(gmat, ob->rot, ob->rotmode);
+                       }
                }
        }
 }