Bugfix #19703: Axis Angle wont work
authorJoshua Leung <aligorith@gmail.com>
Thu, 22 Oct 2009 02:14:11 +0000 (02:14 +0000)
committerJoshua Leung <aligorith@gmail.com>
Thu, 22 Oct 2009 02:14:11 +0000 (02:14 +0000)
* Transform code was not properly fixed to work with the new way that axis-angle data was stored
* The order of the args for the conversion function when switching rotation representations was wrong, causing problems when switching from quaternion to axis angle (i.e. these occurred for newly created bones).

source/blender/blenkernel/intern/armature.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c

index 9894cc8578474ace45c40ea31f517f481393dd94..504450e033414894cc02c8fbfc5a99f0b0f0bc4c 100644 (file)
@@ -1286,7 +1286,7 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float
  *     - the result should be that the rotations given in the provided pointers have had conversions 
  *       applied (as appropriate), such that the rotation of the element hasn't 'visually' changed 
  */
-void BKE_rotMode_change_values (float quat[4], float eul[3], float *axis, float angle[3], short oldMode, short newMode)
+void BKE_rotMode_change_values (float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode)
 {
        /* check if any change - if so, need to convert data */
        if (newMode > 0) { /* to euler */
index 3df74020fab397e8d15c367871c3fcfa15b4d9d7..3b001bff12f517d16ff396597637e5ea3532f2f3 100644 (file)
@@ -1634,7 +1634,7 @@ static void protectedRotateBits(short protectflag, float *eul, float *oldeul)
 
 /* this function only does the delta rotation */
 /* axis-angle is usually internally stored as quats... */
-static void protectedAxisAngleBits(short protectflag, float *quat, float *oldquat)
+static void protectedAxisAngleBits(short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle)
 {
        /* check that protection flags are set */
        if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0)
@@ -1643,21 +1643,20 @@ static void protectedAxisAngleBits(short protectflag, float *quat, float *oldqua
        if (protectflag & OB_LOCK_ROT4D) {
                /* axis-angle getting limited as 4D entities that they are... */
                if (protectflag & OB_LOCK_ROTW)
-                       quat[0]= oldquat[0];
+                       *angle= oldAngle;
                if (protectflag & OB_LOCK_ROTX)
-                       quat[1]= oldquat[1];
+                       axis[0]= oldAxis[0];
                if (protectflag & OB_LOCK_ROTY)
-                       quat[2]= oldquat[2];
+                       axis[1]= oldAxis[1];
                if (protectflag & OB_LOCK_ROTZ)
-                       quat[3]= oldquat[3];
+                       axis[2]= oldAxis[2];
        }
        else {
                /* axis-angle get limited with euler... */
-               float eul[3], oldeul[3], quat1[4];
+               float eul[3], oldeul[3];
                
-               QUATCOPY(quat1, quat);
-               AxisAngleToEulO(quat+1, quat[0], eul, EULER_ORDER_DEFAULT);
-               AxisAngleToEulO(oldquat+1, oldquat[0], oldeul, EULER_ORDER_DEFAULT);
+               AxisAngleToEulO(axis, *angle, eul, EULER_ORDER_DEFAULT);
+               AxisAngleToEulO(oldAxis, oldAngle, oldeul, EULER_ORDER_DEFAULT);
                
                if (protectflag & OB_LOCK_ROTX)
                        eul[0]= oldeul[0];
@@ -1666,12 +1665,12 @@ static void protectedAxisAngleBits(short protectflag, float *quat, float *oldqua
                if (protectflag & OB_LOCK_ROTZ)
                        eul[2]= oldeul[2];
                
-               EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, quat+1, quat);
+               EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, axis, angle);
                
                /* when converting to axis-angle, we need a special exception for the case when there is no axis */
-               if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) {
+               if (IS_EQ(axis[0], axis[1]) && IS_EQ(axis[1], axis[2])) {
                        /* for now, rotate around y-axis then (so that it simply becomes the roll) */
-                       quat[2]= 1.0f;
+                       axis[1]= 1.0f;
                }
        }
 }
@@ -2690,22 +2689,18 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
                        }
                        else if (td->rotOrder == ROT_MODE_AXISANGLE) {
                                /* calculate effect based on quats */
-                               float iquat[4];
+                               float iquat[4], tquat[4];
                                
-                               /* td->ext->(i)quat is in axis-angle form, not quats! */
-                               AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]);
+                               AxisAngleToQuat(iquat, td->ext->irotAxis, td->ext->irotAngle);
                                
                                Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
                                Mat3ToQuat(fmat, quat); // Actual transform
+                               QuatMul(tquat, quat, iquat);
                                
-                               QuatMul(td->ext->quat, quat, iquat);
-                               
-                               /* make temp copy (since stored in same place) */
-                               QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro
-                               QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); 
+                               QuatToAxisAngle(tquat, td->ext->rotAxis, td->ext->rotAngle); 
                                
                                /* this function works on end result */
-                               protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat);
+                               protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
                        }
                        else { 
                                float eulmat[3][3];
@@ -2762,22 +2757,18 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
                        }
                        else if (td->rotOrder == ROT_MODE_AXISANGLE) {
                                /* calculate effect based on quats */
-                               float iquat[4];
+                               float iquat[4], tquat[4];
                                
-                               /* td->ext->(i)quat is in axis-angle form, not quats! */
-                               AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]);
+                               AxisAngleToQuat(iquat, td->ext->irotAxis, td->ext->irotAngle);
                                
                                Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
                                Mat3ToQuat(fmat, quat); // Actual transform
+                               QuatMul(tquat, quat, iquat);
                                
-                               QuatMul(td->ext->quat, quat, iquat);
-                               
-                               /* make temp copy (since stored in same place) */
-                               QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro
-                               QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); 
+                               QuatToAxisAngle(quat, td->ext->rotAxis, td->ext->rotAngle); 
                                
                                /* this function works on end result */
-                               protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat);
+                               protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
                        }
                        else {
                                float obmat[3][3];
index 46e5dad3e053a49e8b7d1ef485a1d8021eb2a1f0..819cb95d948e68dd8c89a92059d979057b52a0b9 100644 (file)
@@ -125,12 +125,18 @@ typedef struct TransCon {
 
 typedef struct TransDataExtension {
        float drot[3];           /* Initial object drot */
+       float drotAngle;         /* Initial object drotAngle */
+       float drotAxis[3];       /* Initial object drotAxis */
        float dquat[4];          /* Initial object dquat */
        float dsize[3];          /* Initial object dsize */
     float *rot;          /* Rotation of the data to transform (Faculative)                                 */
     float  irot[3];      /* Initial rotation                                                               */
     float *quat;         /* Rotation quaternion of the data to transform (Faculative)                      */
     float  iquat[4];    /* Initial rotation quaternion                                                    */
+       float *rotAngle;         /* Rotation angle of the data to transform (Faculative)                                                 */
+       float  irotAngle;        /* Initial rotation angle                                                                                               */
+       float *rotAxis;          /* Rotation axis of the data to transform (Faculative)                                                  */
+       float  irotAxis[4];      /* Initial rotation axis                                                                                                        */
     float *size;         /* Size of the data to transform (Faculative)                                     */
     float  isize[3];    /* Initial size                                                                   */
        float  obmat[4][4];      /* Object matrix */
index 8998550c6d14d44b59205f5c1429baaad68e9698..71ce97b2d48f5531888dc7067eeed1fa99c877b2 100644 (file)
@@ -575,12 +575,25 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
 
        if (pchan->rotmode > 0) {
                td->ext->rot= pchan->eul;
+               td->ext->rotAxis= NULL;
+               td->ext->rotAngle= NULL;
                td->ext->quat= NULL;
                
                VECCOPY(td->ext->irot, pchan->eul);
        }
+       else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+               td->ext->rot= NULL;
+               td->ext->rotAxis= pchan->rotAxis;
+               td->ext->rotAngle= &pchan->rotAngle;
+               td->ext->quat= NULL;
+               
+               td->ext->irotAngle= pchan->rotAngle;
+               VECCOPY(td->ext->irotAxis, pchan->rotAxis);
+       }
        else {
                td->ext->rot= NULL;
+               td->ext->rotAxis= NULL;
+               td->ext->rotAngle= NULL;
                td->ext->quat= pchan->quat;
                
                QUATCOPY(td->ext->iquat, pchan->quat);
@@ -4195,14 +4208,37 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
 
        td->loc = ob->loc;
        VECCOPY(td->iloc, td->loc);
-
-       td->ext->rot = ob->rot;
-       VECCOPY(td->ext->irot, ob->rot);
-       VECCOPY(td->ext->drot, ob->drot);
        
-       td->ext->quat = ob->quat;
-       QUATCOPY(td->ext->iquat, ob->quat);
-       QUATCOPY(td->ext->dquat, ob->dquat);
+       if (ob->rotmode > 0) {
+               td->ext->rot= ob->rot;
+               td->ext->rotAxis= NULL;
+               td->ext->rotAngle= NULL;
+               td->ext->quat= NULL;
+               
+               VECCOPY(td->ext->irot, ob->rot);
+               VECCOPY(td->ext->drot, ob->drot);
+       }
+       else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+               td->ext->rot= NULL;
+               td->ext->rotAxis= ob->rotAxis;
+               td->ext->rotAngle= &ob->rotAngle;
+               td->ext->quat= NULL;
+               
+               td->ext->irotAngle= ob->rotAngle;
+               VECCOPY(td->ext->irotAxis, ob->rotAxis);
+               td->ext->drotAngle= ob->drotAngle;
+               VECCOPY(td->ext->drotAxis, ob->drotAxis);
+       }
+       else {
+               td->ext->rot= NULL;
+               td->ext->rotAxis= NULL;
+               td->ext->rotAngle= NULL;
+               td->ext->quat= ob->quat;
+               
+               QUATCOPY(td->ext->iquat, ob->quat);
+               QUATCOPY(td->ext->dquat, ob->dquat);
+       }
+       td->rotOrder=ob->rotmode;
 
        td->ext->size = ob->size;
        VECCOPY(td->ext->isize, ob->size);