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:
@@ -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 *************** */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user