diff options
-rw-r--r-- | source/blender/editors/transform/transform_manipulator.c | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 5bce18ef5f7..73b58b51ffc 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -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); } +/* 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) { @@ -169,10 +200,18 @@ int gimbal_axis(Object *ob, float gmat[][3]) { 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]; + 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 */ 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); } else if(ob->rotmode == ROT_MODE_AXISANGLE) { - /* X/Y are arbitrary axies, most importantly Z is the axis of rotation - * 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); + axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle); } else { /* quat */ return 0; |