improvement to axis/angle gimble conversion added last commit. fixed flipping problems and enabled for pose bones.
This commit is contained in:
@@ -156,6 +156,37 @@ static void stats_editbone(RegionView3D *rv3d, EditBone *ebo)
|
|||||||
protectflag_to_drawflags(OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE, &rv3d->twdrawflag);
|
protectflag_to_drawflags(OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE, &rv3d->twdrawflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* could move into BLI_math however this is only useful for display/editing purposes */
|
||||||
|
static void axis_angle_to_gimbal_axis(float gmat[3][3], float axis[3], float angle)
|
||||||
|
{
|
||||||
|
/* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
|
||||||
|
|
||||||
|
float cross_vec[3];
|
||||||
|
float quat[4];
|
||||||
|
|
||||||
|
/* this is an un-scientific method to get a vector to cross with
|
||||||
|
* XYZ intentionally YZX */
|
||||||
|
cross_vec[0]= axis[1];
|
||||||
|
cross_vec[1]= axis[2];
|
||||||
|
cross_vec[2]= axis[0];
|
||||||
|
|
||||||
|
/* X-axis */
|
||||||
|
cross_v3_v3v3(gmat[0], cross_vec, axis);
|
||||||
|
normalize_v3(gmat[0]);
|
||||||
|
axis_angle_to_quat(quat, axis, angle);
|
||||||
|
mul_qt_v3(quat, gmat[0]);
|
||||||
|
|
||||||
|
/* Y-axis */
|
||||||
|
axis_angle_to_quat(quat, axis, M_PI/2.0);
|
||||||
|
copy_v3_v3(gmat[1], gmat[0]);
|
||||||
|
mul_qt_v3(quat, gmat[1]);
|
||||||
|
|
||||||
|
/* Z-axis */
|
||||||
|
copy_v3_v3(gmat[2], axis);
|
||||||
|
|
||||||
|
normalize_m3(gmat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int test_rotmode_euler(short rotmode)
|
static int test_rotmode_euler(short rotmode)
|
||||||
{
|
{
|
||||||
@@ -169,10 +200,18 @@ int gimbal_axis(Object *ob, float gmat[][3])
|
|||||||
{
|
{
|
||||||
bPoseChannel *pchan= get_active_posechannel(ob);
|
bPoseChannel *pchan= get_active_posechannel(ob);
|
||||||
|
|
||||||
if(pchan && test_rotmode_euler(pchan->rotmode)) {
|
if(pchan) {
|
||||||
float mat[3][3], tmat[3][3], obmat[3][3];
|
float mat[3][3], tmat[3][3], obmat[3][3];
|
||||||
|
if(test_rotmode_euler(pchan->rotmode)) {
|
||||||
|
eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
|
||||||
|
}
|
||||||
|
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
|
||||||
|
axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
|
||||||
|
}
|
||||||
|
else { /* quat */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
|
|
||||||
|
|
||||||
/* apply bone transformation */
|
/* apply bone transformation */
|
||||||
mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
|
mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
|
||||||
@@ -204,34 +243,7 @@ int gimbal_axis(Object *ob, float gmat[][3])
|
|||||||
eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
|
eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
|
||||||
}
|
}
|
||||||
else if(ob->rotmode == ROT_MODE_AXISANGLE) {
|
else if(ob->rotmode == ROT_MODE_AXISANGLE) {
|
||||||
/* X/Y are arbitrary axies, most importantly Z is the axis of rotation
|
axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
|
||||||
* there is also an axis flipping problem if the rotation axis points
|
|
||||||
* exactly on Z and Y value is modified. */
|
|
||||||
float cross_vec[3]= {0};
|
|
||||||
float quat[4];
|
|
||||||
|
|
||||||
if(ob->rotAxis[0] || ob->rotAxis[1]) {
|
|
||||||
cross_vec[2]= 1.0f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cross_vec[0]= 1.0f; /* could be X or Y */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* X-axis */
|
|
||||||
cross_v3_v3v3(gmat[0], cross_vec, ob->rotAxis);
|
|
||||||
normalize_v3(gmat[0]);
|
|
||||||
axis_angle_to_quat(quat, ob->rotAxis, ob->rotAngle);
|
|
||||||
mul_qt_v3(quat, gmat[0]);
|
|
||||||
|
|
||||||
/* Y-axis */
|
|
||||||
axis_angle_to_quat(quat, ob->rotAxis, M_PI/2.0);
|
|
||||||
copy_v3_v3(gmat[1], gmat[0]);
|
|
||||||
mul_qt_v3(quat, gmat[1]);
|
|
||||||
|
|
||||||
/* Z-axis */
|
|
||||||
copy_v3_v3(gmat[2], ob->rotAxis);
|
|
||||||
|
|
||||||
normalize_m3(gmat);
|
|
||||||
}
|
}
|
||||||
else { /* quat */
|
else { /* quat */
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user