Simplify gimbal axis code and make gimbal orientation work correctly with parents (objects or pose bones). Works for all euler orders too, obviously.

This commit is contained in:
Martin Poirier
2009-11-01 21:10:54 +00:00
parent 7bb6e18f20
commit 94209d58aa
2 changed files with 52 additions and 38 deletions

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

View 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]);
/* apply bone transformation */
Mat3MulMat3(tmat, pchan->bone->bone_mat, mat);
if (pchan->parent)
{
float parent_mat[3][3];
if(pchan->parent) {
bPoseChannel *pchan_par= pchan->parent;
Mat3CpyMat4(parent_mat, pchan->parent->pose_mat);
Mat3MulMat3(mat, parent_mat, tmat);
float tmat[3][3];
Mat3CpyMat4(tmat, pchan_par->pose_mat);
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);
}
else
{
/* needed if object transformation isn't identity */
Mat3CpyMat4(obmat, ob->obmat);
Mat3MulMat3(gmat, obmat, tmat);
}
/* needed if object trans isnt identity */
for (i=0; i<3; i++) {
float tmat[3][3];
Mat3CpyMat4(tmat, ob->obmat);
Mat3MulVecfl(tmat, gmat[i]);
}
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);
}
}
}
}