diff options
-rw-r--r-- | source/blender/include/BIF_editarmature.h | 4 | ||||
-rw-r--r-- | source/blender/src/drawview.c | 3 | ||||
-rw-r--r-- | source/blender/src/editarmature.c | 95 | ||||
-rw-r--r-- | source/blender/src/header_view3d.c | 42 | ||||
-rw-r--r-- | source/blender/src/space.c | 7 |
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); } } |