diff options
author | Martin Poirier <theeth@yahoo.com> | 2009-10-30 00:34:09 +0300 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2009-10-30 00:34:09 +0300 |
commit | 1a8b9e63d92727374367609730bdc5e4e3304c8c (patch) | |
tree | b00da259157f0b12074769f79be59de1db26c316 /source | |
parent | 0400f3cd5c8bd7d5da28e8d8b0821f636fc991e2 (diff) |
When transform orientation is not orthogonal (which is often the case with Gimbal), orthogonalize the orientation separately when drawing each rotation circles (this makes sure they really appear perpendicular and not just be that way in the skewed space of the orientation).
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 30 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_manipulator.c | 100 |
2 files changed, 107 insertions, 23 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 5cdf3b9dcc8..c40c2aeb32c 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2034,9 +2034,10 @@ static float ui_numedit_apply_snap(int temp, float softmin, float softmax, int s return temp; } -static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx) +static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx, int my) { float deler, tempf, softmin, softmax, softrange; + float ladder = powf(10.0, floorf((my - data->dragstarty) / 100.0f)); int lvalue, temp, changed= 0; if(mx == data->draglastx) @@ -2062,7 +2063,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i * 2px == 1-int, or 1px == 1-ClickStep */ if(ui_is_but_float(but)) { fac *= 0.01*but->a1; - tempf = data->startvalue + ((mx - data->dragstartx) * fac); + tempf = data->startvalue + ((mx - data->dragstartx) * fac) * ladder; tempf= ui_numedit_apply_snapf(tempf, softmin, softmax, softrange, snap); #if 1 /* fake moving the click start, nicer for dragging back after passing the limit */ @@ -2086,7 +2087,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i else { fac = 0.5; /* simple 2px == 1 */ - temp= data->startvalue + ((mx - data->dragstartx) * fac); + temp= data->startvalue + ((mx - data->dragstartx) * fac) * ladder; temp= ui_numedit_apply_snap(temp, softmin, softmax, snap); #if 1 /* fake moving the click start, nicer for dragging back after passing the limit */ @@ -2121,13 +2122,13 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i if(ui_is_but_float(but) && softrange > 11) { /* non linear change in mouse input- good for high precicsion */ - data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002); + data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002)*ladder; } else if (!ui_is_but_float(but) && softrange > 129) { /* only scale large int buttons */ /* non linear change in mouse input- good for high precicsionm ints need less fine tuning */ - data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004); + data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004)*ladder; } else { /*no scaling */ - data->dragf+= ((float)(mx-data->draglastx))/deler ; + data->dragf+= ((float)(mx-data->draglastx))/deler*ladder ; } if(data->dragf>1.0) data->dragf= 1.0; @@ -2197,6 +2198,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } else if(event->type == LEFTMOUSE) { data->dragstartx= data->draglastx= ui_is_a_warp_but(but) ? screen_mx:mx; + data->dragstarty= data->draglasty= ui_is_a_warp_but(but) ? screen_my:my; button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval= WM_UI_HANDLER_BREAK; } @@ -2235,7 +2237,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton snap= (event->ctrl)? (event->shift)? 2: 1: 0; - if(ui_numedit_but_NUM(but, data, fac, snap, (ui_is_a_warp_but(but) ? screen_mx:mx))) + if(ui_numedit_but_NUM(but, data, fac, snap, (ui_is_a_warp_but(but) ? screen_mx:mx), (ui_is_a_warp_but(but) ? screen_my:my))) ui_numedit_apply(C, block, but, data); } retval= WM_UI_HANDLER_BREAK; @@ -2421,7 +2423,9 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } else if(event->type == LEFTMOUSE) { data->dragstartx= mx; + data->dragstarty= my; data->draglastx= mx; + data->draglasty= my; button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval= WM_UI_HANDLER_BREAK; } @@ -2522,14 +2526,10 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut if(data->state == BUTTON_STATE_HIGHLIGHT) { if(event->val==KM_PRESS) { if(event->type == LEFTMOUSE) { - if(horizontal) { - data->dragstartx= mx; - data->draglastx= mx; - } - else { - data->dragstartx= my; - data->draglastx= my; - } + data->dragstartx= mx; + data->draglastx= mx; + data->dragstartx= my; + data->draglastx= my; button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval= WM_UI_HANDLER_BREAK; } diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 2247977ef87..51a820dcdcb 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -736,12 +736,43 @@ static void draw_manipulator_axes(View3D *v3d, int colcode, int flagx, int flagy } } +static void preOrtho(int ortho, float twmat[][4], int axis) +{ + if (ortho == 0) { + float omat[4][4]; + Mat4CpyMat4(omat, twmat); + Mat4Orthogonal(omat, axis); + glPushMatrix(); + wmMultMatrix(omat); + } +} + +static void preOrthoFront(int ortho, float twmat[][4], int axis) +{ + if (ortho == 0) { + float omat[4][4]; + Mat4CpyMat4(omat, twmat); + Mat4Orthogonal(omat, axis); + glPushMatrix(); + wmMultMatrix(omat); + glFrontFace( is_mat4_flipped(omat)?GL_CW:GL_CCW); + } +} + +static void postOrtho(int ortho) +{ + if (ortho == 0) { + glPopMatrix(); + } +} + /* only called while G.moving */ static void draw_manipulator_rotate_ghost(View3D *v3d, RegionView3D *rv3d, int drawflags) { GLUquadricObj *qobj; float size, phi, startphi, vec[3], svec[3], matt[4][4], cross[3], tmat[3][3]; int arcs= (G.rt!=2); + int ortho; glDisable(GL_DEPTH_TEST); @@ -796,11 +827,18 @@ static void draw_manipulator_rotate_ghost(View3D *v3d, RegionView3D *rv3d, int d Mat3MulVecfl(tmat, svec); // tmat is used further on Normalize(svec); } + + ortho = IsMat4Orthogonal(rv3d->twmat); - wmMultMatrix(rv3d->twmat); // aligns with original widget + if (ortho) { + wmMultMatrix(rv3d->twmat); // aligns with original widget + } + /* Z disk */ if(drawflags & MAN_ROT_Z) { + preOrtho(ortho, rv3d->twmat, 2); + if(arcs) { /* correct for squeezed arc */ svec[0]+= tmat[2][0]; @@ -820,9 +858,13 @@ static void draw_manipulator_rotate_ghost(View3D *v3d, RegionView3D *rv3d, int d if(Inpf(cross, rv3d->twmat[2]) > 0.0) phi= -phi; gluPartialDisk(qobj, 0.0, 1.0, 32, 1, 180.0*startphi/M_PI, 180.0*(phi)/M_PI); } + + postOrtho(ortho); } /* X disk */ if(drawflags & MAN_ROT_X) { + preOrtho(ortho, rv3d->twmat, 0); + if(arcs) { /* correct for squeezed arc */ svec[1]+= tmat[2][1]; @@ -844,9 +886,13 @@ static void draw_manipulator_rotate_ghost(View3D *v3d, RegionView3D *rv3d, int d gluPartialDisk(qobj, 0.0, 1.0, 32, 1, 180.0*startphi/M_PI, 180.0*phi/M_PI); glRotatef(-90.0, 0.0, 1.0, 0.0); } + + postOrtho(ortho); } /* Y circle */ if(drawflags & MAN_ROT_Y) { + preOrtho(ortho, rv3d->twmat, 1); + if(arcs) { /* correct for squeezed arc */ svec[0]+= tmat[2][0]; @@ -868,6 +914,8 @@ static void draw_manipulator_rotate_ghost(View3D *v3d, RegionView3D *rv3d, int d gluPartialDisk(qobj, 0.0, 1.0, 32, 1, 180.0*startphi/M_PI, 180.0*phi/M_PI); glRotatef(90.0, 1.0, 0.0, 0.0); } + + postOrtho(ortho); } glDisable(GL_BLEND); @@ -878,11 +926,13 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, { GLUquadricObj *qobj; double plane[4]; + float matt[4][4]; float size, vec[3], unitmat[4][4]; float cywid= 0.33f*0.01f*(float)U.tw_handlesize; float cusize= cywid*0.65f; int arcs= (G.rt!=2); int colcode; + int ortho; if(moving) colcode= MAN_MOVECOL; else colcode= MAN_RGB; @@ -940,17 +990,23 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, } glPopMatrix(); + + ortho = IsMat4Orthogonal(rv3d->twmat); + /* apply the transform delta */ if(moving) { - float matt[4][4]; Mat4CpyMat4(matt, rv3d->twmat); // to copy the parts outside of [3][3] // XXX Mat4MulMat34(matt, t->mat, rv3d->twmat); - wmMultMatrix(matt); - glFrontFace( is_mat4_flipped(matt)?GL_CW:GL_CCW); + if (ortho) { + wmMultMatrix(matt); + glFrontFace( is_mat4_flipped(matt)?GL_CW:GL_CCW); + } } else { - glFrontFace( is_mat4_flipped(rv3d->twmat)?GL_CW:GL_CCW); - wmMultMatrix(rv3d->twmat); + if (ortho) { + glFrontFace( is_mat4_flipped(rv3d->twmat)?GL_CW:GL_CCW); + wmMultMatrix(rv3d->twmat); + } } /* axes */ @@ -958,23 +1014,33 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, if(!(G.f & G_PICKSEL)) { if( (combo & V3D_MANIP_SCALE)==0) { /* axis */ - glBegin(GL_LINES); if( (drawflags & MAN_ROT_X) || (moving && (drawflags & MAN_ROT_Z)) ) { + preOrthoFront(ortho, rv3d->twmat, 2); manipulator_setcolor(v3d, 'x', colcode); + glBegin(GL_LINES); glVertex3f(0.2f, 0.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); + glEnd(); + postOrtho(ortho); } if( (drawflags & MAN_ROT_Y) || (moving && (drawflags & MAN_ROT_X)) ) { + preOrthoFront(ortho, rv3d->twmat, 0); manipulator_setcolor(v3d, 'y', colcode); + glBegin(GL_LINES); glVertex3f(0.0f, 0.2f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); + glEnd(); + postOrtho(ortho); } if( (drawflags & MAN_ROT_Z) || (moving && (drawflags & MAN_ROT_Y)) ) { + preOrthoFront(ortho, rv3d->twmat, 1); manipulator_setcolor(v3d, 'z', colcode); + glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.2f); glVertex3f(0.0f, 0.0f, 1.0f); + glEnd(); + postOrtho(ortho); } - glEnd(); } } } @@ -983,25 +1049,31 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, /* Z circle */ if(drawflags & MAN_ROT_Z) { + preOrthoFront(ortho, matt, 2); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); manipulator_setcolor(v3d, 'z', colcode); drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat); + postOrtho(ortho); } /* X circle */ if(drawflags & MAN_ROT_X) { + preOrthoFront(ortho, matt, 0); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X); glRotatef(90.0, 0.0, 1.0, 0.0); manipulator_setcolor(v3d, 'x', colcode); drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat); glRotatef(-90.0, 0.0, 1.0, 0.0); + postOrtho(ortho); } /* Y circle */ if(drawflags & MAN_ROT_Y) { + preOrthoFront(ortho, matt, 1); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); glRotatef(-90.0, 1.0, 0.0, 0.0); manipulator_setcolor(v3d, 'y', colcode); drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat); glRotatef(90.0, 1.0, 0.0, 0.0); + postOrtho(ortho); } if(arcs) glDisable(GL_CLIP_PLANE0); @@ -1012,25 +1084,31 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, /* Z circle */ if(drawflags & MAN_ROT_Z) { + preOrthoFront(ortho, rv3d->twmat, 2); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); manipulator_setcolor(v3d, 'z', colcode); partial_donut(cusize/4.0f, 1.0f, 0, 48, 8, 48); + postOrtho(ortho); } /* X circle */ if(drawflags & MAN_ROT_X) { + preOrthoFront(ortho, rv3d->twmat, 0); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X); glRotatef(90.0, 0.0, 1.0, 0.0); manipulator_setcolor(v3d, 'x', colcode); partial_donut(cusize/4.0f, 1.0f, 0, 48, 8, 48); glRotatef(-90.0, 0.0, 1.0, 0.0); + postOrtho(ortho); } /* Y circle */ if(drawflags & MAN_ROT_Y) { + preOrthoFront(ortho, rv3d->twmat, 1); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); glRotatef(-90.0, 1.0, 0.0, 0.0); manipulator_setcolor(v3d, 'y', colcode); partial_donut(cusize/4.0f, 1.0f, 0, 48, 8, 48); glRotatef(90.0, 1.0, 0.0, 0.0); + postOrtho(ortho); } glDisable(GL_CLIP_PLANE0); @@ -1040,6 +1118,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, /* Z handle on X axis */ if(drawflags & MAN_ROT_Z) { + preOrthoFront(ortho, rv3d->twmat, 2); glPushMatrix(); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); manipulator_setcolor(v3d, 'z', colcode); @@ -1047,10 +1126,12 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, partial_donut(0.7f*cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); + postOrtho(ortho); } /* Y handle on X axis */ if(drawflags & MAN_ROT_Y) { + preOrthoFront(ortho, rv3d->twmat, 1); glPushMatrix(); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); manipulator_setcolor(v3d, 'y', colcode); @@ -1060,10 +1141,12 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, partial_donut(0.7f*cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); + postOrtho(ortho); } /* X handle on Z axis */ if(drawflags & MAN_ROT_X) { + preOrthoFront(ortho, rv3d->twmat, 0); glPushMatrix(); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X); manipulator_setcolor(v3d, 'x', colcode); @@ -1073,6 +1156,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, partial_donut(0.7f*cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); + postOrtho(ortho); } } |