Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-02-05 06:28:07 +0300
committerJoshua Leung <aligorith@gmail.com>2009-02-05 06:28:07 +0300
commitf89e3d251711f3617c982cae35f33d4c6115e72b (patch)
tree83b0399aba32a346ae448960f5153e26b2ebdabd /source/blender/editors/armature
parent61a6e1957a4a1555564f1eb8dbdb9707fb276826 (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.c54
-rw-r--r--source/blender/editors/armature/editarmature.c149
-rw-r--r--source/blender/editors/armature/poseobject.c23
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
}
}