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
path: root/source
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2007-08-03 15:16:12 +0400
committerJoshua Leung <aligorith@gmail.com>2007-08-03 15:16:12 +0400
commitfa5b4954a23f568bf0ba5359a745df72f5c99ff0 (patch)
tree4299734a88a60357d871f60988fac20e36ae0b52 /source
parent834e64e0e666ea651ed067e7dbc58b147b49fcba (diff)
== Bone Roll - Align to Cursor ==
In this commit, a new way to set the bone roll is introduced. It aligns the z-axis of the selected bone(s) to the 3D-Cursor, so that the cursor intersects with the YZ plane. This makes it easier to align bone rolls to a target, for use in rigs where arms/legs are not horizontal/vertical. To use this, just press Ctrl N, and choose the "Align Z-Axis to 3D-Cursor" option. Credits go to Robert Christian (wavez) for providing the method as a working BPy script, that demonstrated this in action.
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BIF_editarmature.h4
-rw-r--r--source/blender/src/drawview.c3
-rw-r--r--source/blender/src/editarmature.c95
-rw-r--r--source/blender/src/header_view3d.c42
-rw-r--r--source/blender/src/space.c7
5 files changed, 110 insertions, 41 deletions
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index b8ae90b7cfa..f2b6dbf38bd 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -106,9 +106,9 @@ void remake_editArmature(void);
void selectconnected_armature(void);
void selectconnected_posearmature(void);
void select_bone_parent(void);
-void unique_editbone_name (struct ListBase *ebones, char* name);
+void unique_editbone_name (struct ListBase *ebones, char *name);
-void auto_align_armature(void);
+void auto_align_armature(short mode);
void create_vgroups_from_armature(Object *ob, Object *par);
void hide_selected_pose_bones(void);
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 14e7107a31f..e68c0c1e0c8 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -1866,7 +1866,6 @@ static void validate_bonebutton_cb(void *bonev, void *namev)
}
}
-
static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim)
{
uiBut *but;
@@ -1954,9 +1953,9 @@ static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim)
uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipY:", 160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipZ:", 160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
uiBlockEndAlign(block);
+
tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
-
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipRadius:", 10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index b18316edbda..61e6f2d9d37 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -1269,37 +1269,80 @@ void deselectall_armature(int toggle, int doundo)
}
}
-void auto_align_armature(void)
-/* Sets the roll value of selected bones so that their zaxes point upwards */
+/* 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(short mode)
{
bArmature *arm= G.obedit->data;
EditBone *ebone;
- 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];
- float curmat[3][3], diffmat[3][3];
float delta[3];
-
- for (ebone = G.edbo.first; ebone; ebone=ebone->next){
+ float curmat[3][3];
+ float *cursor= give_cursor();
+
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
if(arm->layer & ebone->layer) {
- if (ebone->flag & BONE_SELECTED){
- /* 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]);
+ if (ebone->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, G.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]);
+ }
}
}
}
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index 05b4df137ed..f3d36e7d59f 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -3633,6 +3633,39 @@ static uiBlock *view3d_edit_armature_parentmenu(void *arg_unused)
return block;
}
+void do_view3d_edit_armature_rollmenu(void *arg, int event)
+{
+ if (event == 1 || event == 2)
+ /* set roll based on aligning z-axis */
+ auto_align_armature(event);
+ else if (event == 3) {
+ /* interactively set bone roll */
+ initTransform(TFM_BONE_ROLL, CTX_NONE);
+ Transform();
+ }
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+static uiBlock *view3d_edit_armature_rollmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco = 20, menuwidth = 120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_edit_armature_rollmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_view3d_edit_armature_rollmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Roll (Z-Axis Up)|Ctrl N, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Roll to Cursor|Ctrl N, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Roll|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+ return block;
+}
+
static void do_view3d_edit_armaturemenu(void *arg, int event)
{
switch(event) {
@@ -3662,18 +3695,12 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
case 10: /* forked! */
extrude_armature(1);
break;
- case 11: /* clear roll */
- auto_align_armature();
- break;
case 12: /* subdivide */
subdivide_armature();
break;
case 13: /* flip left and right names */
armature_flip_names();
break;
- case 14: /* interactively set bone roll */
- initTransform(TFM_BONE_ROLL, CTX_NONE);
- Transform();
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -3729,8 +3756,7 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Bone Roll Angle|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Bone Roll Angle|Ctrl N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
+ uiDefIconTextBlockBut(block, view3d_edit_armature_rollmenu, NULL, ICON_RIGHTARROW_THIN, "Bone Roll", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 768a2ea0ac3..d44a4d5c85e 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -2080,9 +2080,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.obedit) {
switch (G.obedit->type){
case OB_ARMATURE:
- if(G.qual==LR_CTRLKEY){
- if (okee("Recalculate bone roll angles")) {
- auto_align_armature();
+ if(G.qual==LR_CTRLKEY) {
+ pupval= pupmenu("Recalculate Bone Roll Angles%t|Clear Roll (Z-Axis Up) %x1|Align Z-Axis to 3D-Cursor %x2");
+ if (pupval > 0) {
+ auto_align_armature(pupval - 1);
allqueue(REDRAWVIEW3D, 0);
}
}