Bugfix #19703: Axis Angle wont work

* 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).
This commit is contained in:
Joshua Leung
2009-10-22 02:14:11 +00:00
parent 64d4ae639b
commit c825a9aeaa
4 changed files with 71 additions and 38 deletions

View 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 */

View 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];

View 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 */

View 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);