From baf12d3d1712235f94bf7db27aed21421d74efea Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 11 Sep 2009 12:44:09 +0000 Subject: [PATCH] 2.5 - Rotation work (axis angle bugfixes + cleanups) * Made transform work better with axis-angle * Corrected the rotation-type handling code in a few places --- .../blender/editors/armature/editarmature.c | 12 +++++++++ source/blender/editors/armature/poselib.c | 16 +++-------- source/blender/editors/armature/poseobject.c | 14 +++++++--- .../editors/space_view3d/view3d_buttons.c | 26 +++++++++++++++--- source/blender/editors/transform/transform.c | 27 +++++++++++++------ .../editors/transform/transform_conversions.c | 3 +-- 6 files changed, 70 insertions(+), 28 deletions(-) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 4f5d8872384..3b6c9e9d13d 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4856,9 +4856,13 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) QUATCOPY(quat1, pchan->quat); QuatToEul(pchan->quat, oldeul); } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + continue; // XXX + } else { VECCOPY(oldeul, pchan->eul); } + eul[0]= eul[1]= eul[2]= 0.0f; if (pchan->protectflag & OB_LOCK_ROTX) @@ -4875,6 +4879,9 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) QuatMulf(pchan->quat, -1.0f); } } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + // TODO... + } else { VECCOPY(pchan->eul, eul); } @@ -4884,6 +4891,11 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) pchan->quat[1]=pchan->quat[2]=pchan->quat[3]= 0.0f; pchan->quat[0]= 1.0f; } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + /* by default, make rotation of 0 radians around y-axis (roll) */ + pchan->quat[0]=pchan->quat[1]=pchan->quat[3]= 0.0f; + pchan->quat[2]= 1.0f; + } else { pchan->eul[0]= pchan->eul[1]= pchan->eul[2]= 0.0f; } diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 56d714fd058..46d08afa656 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -278,8 +278,7 @@ void poselib_validate_act (bAction *act) /* ************************************************************* */ /* Pointers to the builtin KeyingSets that we want to use */ -static KeyingSet *poselib_ks_locrotscale = NULL; /* quaternion rotations */ -static KeyingSet *poselib_ks_locrotscale2 = NULL; /* euler rotations */ // XXX FIXME... +static KeyingSet *poselib_ks_locrotscale = NULL; /* the only keyingset we'll need*/ static short poselib_ks_need_init= 1; /* have the above been obtained yet? */ /* Make sure the builtin KeyingSets are initialised properly @@ -290,13 +289,9 @@ static void poselib_get_builtin_keyingsets (void) /* only if we haven't got these yet */ // FIXME: this assumes that we will always get the builtin sets... if (poselib_ks_need_init) { - /* LocRotScale (quaternions) */ + /* LocRotScale (quaternions or eulers depending on context) */ poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - /* LocRotScale (euler) */ - //ks_locrotscale2= ANIM_builtin_keyingset_get_named(ks_locrotscale, "LocRotScale"); - poselib_ks_locrotscale2= poselib_ks_locrotscale; // FIXME: for now, just use the same one... - /* clear flag requesting init */ poselib_ks_need_init= 0; } @@ -410,11 +405,8 @@ static int poselib_add_exec (bContext *C, wmOperator *op) /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ cks.pchan= pchan; - /* KeyingSet to use depends on rotation mode */ - if (pchan->rotmode) - modify_keyframes(C, &dsources, act, poselib_ks_locrotscale2, MODIFYKEY_MODE_INSERT, (float)frame); - else - modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame); + /* KeyingSet to use depends on rotation mode (but that's handled by the templates code) */ + modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame); } } } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 0ae92de4407..9a404e24e12 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -812,10 +812,17 @@ void pose_copy_menu(Scene *scene) armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat); - if (pchan->rotmode > 0) - Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode); - else + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float tmp_quat[4]; + + /* need to convert to quat first (in temp var)... */ + Mat4ToQuat(delta_mat, tmp_quat); + QuatToAxisAngle(tmp_quat, &pchan->quat[1], &pchan->quat[0]); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) Mat4ToQuat(delta_mat, pchan->quat); + else + Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode); } break; case 11: /* Visual Size */ @@ -991,6 +998,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) pchan->flag= chan->flag; /* check if rotation modes are compatible (i.e. do they need any conversions) */ + // FIXME: add axis-angle here too... if (pchan->rotmode == chan->rotmode) { /* copy the type of rotation in use */ if (pchan->rotmode > 0) { diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 06320f871da..d78928921e5 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -511,8 +511,17 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 140, 140, 19, bone->name, 1, 31, 0, 0, ""); uiButSetFunc(but, validate_bonebutton_cb, bone, NULL); uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob); - - QuatToEulO(pchan->quat, tfp->ob_eul, pchan->rotmode); // XXX? + + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float quat[4]; + /* convert to euler, passing through quats... */ + AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]); + QuatToEul(quat, tfp->ob_eul); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) + QuatToEul(pchan->quat, tfp->ob_eul); + else + VecCopyf(tfp->ob_eul, pchan->eul); tfp->ob_eul[0]*= 180.0/M_PI; tfp->ob_eul[1]*= 180.0/M_PI; tfp->ob_eul[2]*= 180.0/M_PI; @@ -841,7 +850,18 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) eul[0]= M_PI*tfp->ob_eul[0]/180.0; eul[1]= M_PI*tfp->ob_eul[1]/180.0; eul[2]= M_PI*tfp->ob_eul[2]/180.0; - EulOToQuat(eul, pchan->rotmode, pchan->quat); // xxx? + + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float quat[4]; + /* convert to axis-angle, passing through quats */ + EulToQuat(eul, quat); + QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) + EulToQuat(eul, pchan->quat); + else + VecCopyf(pchan->eul, eul); + } /* no break, pass on */ case B_ARMATUREPANEL2: diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ac5d688cd1c..6405e87c4c0 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2673,14 +2673,25 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); - /* if axis-angle, we now convert the quat representation to axis-angle again - * - this means that the math above is not totally correct, but it works well enough so far... - */ - if (td->rotOrder == PCHAN_ROT_AXISANGLE) { - /* make temp copy (since stored in same place) */ - QuatCopy(quat, td->ext->quat); - QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); - } + } + else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + /* calculate effect based on quats */ + float iquat[4]; + + /* td->ext->(i)quat is in axis-angle form, not quats! */ + AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]); + + Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); + Mat3ToQuat(fmat, quat); // Actual transform + + QuatMul(td->ext->quat, quat, iquat); + + /* this function works on end result */ + protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); + + /* make temp copy (since stored in same place) */ + QuatCopy(quat, td->ext->quat); + QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); } else { float eulmat[3][3]; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 7a37ffdeeca..e0d058f160f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -552,9 +552,8 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ob = ob; td->flag = TD_SELECTED; - if ((pchan->rotmode == PCHAN_ROT_QUAT) || (pchan->rotmode == PCHAN_ROT_AXISANGLE)) + if (pchan->rotmode == PCHAN_ROT_QUAT) { - // XXX: for now, axis-angle will be treated like for quats (the only difference is the normalisation) td->flag |= TD_USEQUAT; } if (bone->flag & BONE_HINGE_CHILD_TRANSFORM)