diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-02-05 06:28:07 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-02-05 06:28:07 +0300 |
commit | f89e3d251711f3617c982cae35f33d4c6115e72b (patch) | |
tree | 83b0399aba32a346ae448960f5153e26b2ebdabd /source/blender/editors/armature | |
parent | 61a6e1957a4a1555564f1eb8dbdb9707fb276826 (diff) |
2.5 - Context API access for Bones (EditMode and PoseMode)
* Added selected, selected+editable, and active to access EditBones for Armature Operators to use. These take into account X-Axis Mirror too, so there is really no need to check that sort of thing anymore in tools.
* Added a quick testing operator for verifying that these loops filter the data correctly. I've dumped this in armature_ops.c for now. It can be activated using the TKEY hotkey in Armature EditMode only. This should be removed once we have a few more functional tools.
* Ported over cleaned up roll-calculation tools from AnimSys2
* Removed a few ugly stubs from posemode code
Diffstat (limited to 'source/blender/editors/armature')
-rw-r--r-- | source/blender/editors/armature/armature_ops.c | 54 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature.c | 149 | ||||
-rw-r--r-- | source/blender/editors/armature/poseobject.c | 23 |
3 files changed, 145 insertions, 81 deletions
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index eaa8207bc11..e8f75bd4440 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -58,6 +58,49 @@ #include "armature_intern.h" +/* ************************** quick tests **********************************/ + +/* XXX This is a quick test operator to print names of all EditBones in context + * that should be removed once tool coding starts... + */ + +static int armature_test_exec (bContext *C, wmOperator *op) +{ + printf("EditMode Armature Test: \n"); + + printf("\tSelected Bones \n"); + CTX_DATA_BEGIN(C, EditBone*, ebone, selected_bones) + { + printf("\t\tEditBone '%s' \n", ebone->name); + } + CTX_DATA_END; + + printf("\tEditable Bones \n"); + CTX_DATA_BEGIN(C, EditBone*, ebone, selected_editable_bones) + { + printf("\t\tEditBone '%s' \n", ebone->name); + } + CTX_DATA_END; + + printf("\tActive Bone \n"); + { + EditBone *ebone= CTX_data_active_bone(C); + if (ebone) printf("\t\tEditBone '%s' \n"); + else printf("\t\t<None> \n"); + } + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_test(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Test Context"; + ot->idname= "ARMATURE_OT_test"; + + /* api callbacks */ + ot->exec= armature_test_exec; +} /* ************************** registration **********************************/ @@ -66,16 +109,23 @@ void ED_operatortypes_armature(void) { WM_operatortype_append(POSE_OT_hide); WM_operatortype_append(POSE_OT_reveil); + + WM_operatortype_append(ARMATURE_OT_test); // XXX temp test for context iterators... to be removed } void ED_keymap_armature(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Armature", 0, 0); + ListBase *keymap; wmKeymapItem *kmi; + /* Armature ------------------------ */ + keymap= WM_keymap_listbase(wm, "Armature", 0, 0); + /* only set in editmode armature, by space_view3d listener */ // WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0); - + WM_keymap_add_item(keymap, "ARMATURE_OT_test", TKEY, KM_PRESS, 0, 0); // XXX temp test for context iterators... to be removed + + /* Pose ------------------------ */ /* only set in posemode, by space_view3d listener */ keymap= WM_keymap_listbase(wm, "Pose", 0, 0); diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 631f6ce39df..d083dbec103 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -1844,20 +1844,97 @@ float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]) return roll; } + +/* Set roll value for given bone -> Z-Axis Point up (original method) */ +void auto_align_ebone_zaxisup(Scene *scene, View3D *v3d, EditBone *ebone) +{ + float delta[3], curmat[3][3]; + float xaxis[3]={1.0f, 0.0f, 0.0f}, yaxis[3], zaxis[3]={0.0f, 0.0f, 1.0f}; + float targetmat[3][3], imat[3][3], diffmat[3][3]; + + /* Find the current bone matrix */ + VecSubf(delta, ebone->tail, ebone->head); + vec_roll_to_mat3(delta, 0.0f, curmat); + + /* Make new matrix based on y axis & z-up */ + VECCOPY(yaxis, curmat[1]); + + Mat3One(targetmat); + VECCOPY(targetmat[0], xaxis); + VECCOPY(targetmat[1], yaxis); + VECCOPY(targetmat[2], zaxis); + Mat3Ortho(targetmat); + + /* Find the difference between the two matrices */ + Mat3Inv(imat, targetmat); + Mat3MulMat3(diffmat, imat, curmat); + + // old-method... let's see if using mat3_to_vec_roll is more accurate + //ebone->roll = atan2(diffmat[2][0], diffmat[2][2]); + mat3_to_vec_roll(diffmat, delta, &ebone->roll); +} + +/* Set roll value for given bone -> Z-Axis point towards cursor */ +void auto_align_ebone_tocursor(Scene *scene, View3D *v3d, EditBone *ebone) +{ + Object *obedit= scene->obedit; // XXX get from context + float *cursor= give_cursor(scene, v3d); + float delta[3], curmat[3][3]; + float mat[4][4], tmat[4][4], imat[4][4]; + float rmat[4][4], rot[3]; + float vec[3]; + + /* find the current bone matrix as a 4x4 matrix (in Armature Space) */ + VecSubf(delta, ebone->tail, ebone->head); + vec_roll_to_mat3(delta, ebone->roll, curmat); + Mat4CpyMat3(mat, curmat); + VECCOPY(mat[3], ebone->head); + + /* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */ + Mat4MulMat4(tmat, mat, obedit->obmat); + Mat4Invert(imat, tmat); + + /* find position of cursor relative to bone */ + VecMat4MulVecfl(vec, imat, cursor); + + /* check that cursor is in usable position */ + if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) { + /* Compute a rotation matrix around y */ + rot[1] = atan2(vec[0], vec[2]); + rot[0] = rot[2] = 0.0f; + EulToMat4(rot, rmat); + + /* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */ + Mat4MulMat4(tmat, rmat, mat); + Mat3CpyMat4(curmat, tmat); + + /* Now convert from new bone-matrix, back to a roll value (in radians) */ + mat3_to_vec_roll(curmat, delta, &ebone->roll); + } +} + /* Sets the roll value of selected bones, depending on the mode * mode == 0: their z-axes point upwards * mode == 1: their z-axes point towards 3d-cursor */ void auto_align_armature(Scene *scene, View3D *v3d, short mode) { - Object *obedit= scene->obedit; // XXX get from context + Object *obedit= scene->obedit; bArmature *arm= obedit->data; EditBone *ebone; EditBone *flipbone = NULL; - float delta[3]; - float curmat[3][3]; - float *cursor= give_cursor(scene, v3d); - + void (*roll_func)(Scene *, View3D *, EditBone *) = NULL; + + /* specific method used to calculate roll depends on mode */ + switch (mode) { + case 1: /* Z-Axis point towards cursor */ + roll_func= auto_align_ebone_tocursor; + break; + default: /* Z-Axis Point Up */ + roll_func= auto_align_ebone_zaxisup; + break; + } + for (ebone = arm->edbo->first; ebone; ebone=ebone->next) { if (EBONE_VISIBLE(arm, ebone)) { if (arm->flag & ARM_MIRROR_EDIT) @@ -1866,65 +1943,8 @@ void auto_align_armature(Scene *scene, View3D *v3d, short mode) if ((ebone->flag & BONE_SELECTED) || (flipbone && (flipbone->flag & BONE_SELECTED))) { - /* specific method used to calculate roll depends on mode */ - if (mode == 1) { - /* Z-Axis point towards cursor */ - float mat[4][4], tmat[4][4], imat[4][4]; - float rmat[4][4], rot[3]; - float vec[3]; - - /* find the current bone matrix as a 4x4 matrix (in Armature Space) */ - VecSubf(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, ebone->roll, curmat); - Mat4CpyMat3(mat, curmat); - VECCOPY(mat[3], ebone->head); - - /* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */ - Mat4MulMat4(tmat, mat, obedit->obmat); - Mat4Invert(imat, tmat); - - /* find position of cursor relative to bone */ - VecMat4MulVecfl(vec, imat, cursor); - - /* check that cursor is in usable position */ - if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) { - /* Compute a rotation matrix around y */ - rot[1] = atan2(vec[0], vec[2]); - rot[0] = rot[2] = 0.0f; - EulToMat4(rot, rmat); - - /* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */ - Mat4MulMat4(tmat, rmat, mat); - Mat3CpyMat4(curmat, tmat); - - /* Now convert from new bone-matrix, back to a roll value (in radians) */ - mat3_to_vec_roll(curmat, delta, &ebone->roll); - } - } - else { - /* Z-Axis Point Up */ - float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0}; - float targetmat[3][3], imat[3][3], diffmat[3][3]; - - /* Find the current bone matrix */ - VecSubf(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, 0.0, curmat); - - /* Make new matrix based on y axis & z-up */ - VECCOPY (yaxis, curmat[1]); - - Mat3One(targetmat); - VECCOPY (targetmat[0], xaxis); - VECCOPY (targetmat[1], yaxis); - VECCOPY (targetmat[2], zaxis); - Mat3Ortho(targetmat); - - /* Find the difference between the two matrices */ - Mat3Inv(imat, targetmat); - Mat3MulMat3(diffmat, imat, curmat); - - ebone->roll = atan2(diffmat[2][0], diffmat[2][2]); - } + /* roll func is a callback which assumes that all is well */ + roll_func(scene, v3d, ebone); } } } @@ -3539,6 +3559,7 @@ static int clear_active_flag(Object *ob, Bone *bone, void *data) } +// XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer static int bone_looper(Object *ob, Bone *bone, void *data, int (*bone_func)(Object *, Bone *, void *)) { diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index bb883c5a98d..0771806a4a2 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -91,11 +91,10 @@ static void error() {}; static void BIF_undo_push() {} static void countall() {} static void add_constraint() {} -static void select_actionchannel_by_name() {} static void autokeyframe_pose_cb_func() {} /* ************* XXX *************** */ - +/* This function is used to indicate that a bone is selected and needs keyframes inserted */ void set_pose_keys (Object *ob) { bArmature *arm= ob->data; @@ -104,16 +103,15 @@ void set_pose_keys (Object *ob) if (ob->pose){ for (chan=ob->pose->chanbase.first; chan; chan=chan->next){ Bone *bone= chan->bone; - if(bone && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) { - chan->flag |= POSE_KEY; - } - else { + if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) + chan->flag |= POSE_KEY; + else chan->flag &= ~POSE_KEY; - } } } } +/* This function is used to process the necessary updates for */ void ED_armature_enter_posemode(bContext *C, Base *base) { Object *ob= base->object; @@ -472,9 +470,7 @@ void pose_select_hierarchy(Scene *scene, short direction, short add_to_sel) curbone->flag &= ~BONE_ACTIVE; pabone->flag |= (BONE_ACTIVE|BONE_SELECTED); - // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier - select_actionchannel_by_name (ob->action, pchan->name, 0); - select_actionchannel_by_name (ob->action, pchan->parent->name, 1); + // XXX notifiers need to be sent to other editors to update break; } } else { // BONE_SELECT_CHILD @@ -488,9 +484,7 @@ void pose_select_hierarchy(Scene *scene, short direction, short add_to_sel) curbone->flag &= ~BONE_ACTIVE; chbone->flag |= (BONE_ACTIVE|BONE_SELECTED); - // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier - select_actionchannel_by_name (ob->action, pchan->name, 0); - select_actionchannel_by_name (ob->action, pchan->child->name, 1); + // XXX notifiers need to be sent to other editors to update break; } } @@ -1339,8 +1333,7 @@ void pose_activate_flipped_bone(Scene *scene) DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); } - // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier - select_actionchannel_by_name(ob->action, name, 1); + // XXX notifiers need to be sent to other editors to update } } |