diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-02-28 10:12:06 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-02-28 10:12:06 +0400 |
commit | 2afca3e317d7b545757864071a53889223cf0ff6 (patch) | |
tree | e9e855b0be41bea3870022347168f50f51b13f68 /source/blender/editors/transform | |
parent | 748dd18de44e485b7f0f30c296ae4df048cc0e37 (diff) |
fix [#34426] Manipulator handles drawn incorrectly by depth
original patch by Philipp Oeser (lichtwerk) with own changes.
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/transform_manipulator.c | 310 |
1 files changed, 207 insertions, 103 deletions
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index cd6035a232b..54fb567b8a2 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -841,37 +841,89 @@ static void manipulator_setcolor(View3D *v3d, char axis, int colcode, unsigned c glColor4ubv(col); } -/* viewmatrix should have been set OK, also no shademode! */ -static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode, int flagx, int flagy, int flagz) +static void axis_sort_v3(const float axis_values[3], int r_axis_order[3]) { + float v[3]; + copy_v3_v3(v, axis_values); - /* axes */ - if (flagx) { - manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0])); - if (flagx & MAN_SCALE_X) glLoadName(MAN_SCALE_X); - else if (flagx & MAN_TRANS_X) glLoadName(MAN_TRANS_X); - glBegin(GL_LINES); - glVertex3f(0.2f, 0.0f, 0.0f); - glVertex3f(1.0f, 0.0f, 0.0f); - glEnd(); +#define SWAP_AXIS(a, b) { \ + SWAP(float, v[a], v[b]); \ + SWAP(int, r_axis_order[a], r_axis_order[b]); \ +} (void)0 + + if (v[0] < v[1]) { + if (v[2] < v[0]) { SWAP_AXIS(0, 2); } + } + else { + if (v[1] < v[2]) { SWAP_AXIS(0, 1); } + else { SWAP_AXIS(0, 2); } } - if (flagy) { - if (flagy & MAN_SCALE_Y) glLoadName(MAN_SCALE_Y); - else if (flagy & MAN_TRANS_Y) glLoadName(MAN_TRANS_Y); - manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1])); - glBegin(GL_LINES); - glVertex3f(0.0f, 0.2f, 0.0f); - glVertex3f(0.0f, 1.0f, 0.0f); - glEnd(); + if (v[2] < v[1]) { SWAP_AXIS(1, 2); } + +#undef SWAP_AXIS +} +static void manipulator_axis_order(RegionView3D *rv3d, int r_axis_order[3]) +{ + float axis_values[3]; + float vec[3]; + + ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], vec); + + axis_values[0] = -dot_v3v3(rv3d->twmat[0], vec); + axis_values[1] = -dot_v3v3(rv3d->twmat[1], vec); + axis_values[2] = -dot_v3v3(rv3d->twmat[2], vec); + + axis_sort_v3(axis_values, r_axis_order); +} + +/* viewmatrix should have been set OK, also no shademode! */ +static void draw_manipulator_axes_single(View3D *v3d, RegionView3D *rv3d, int colcode, + int flagx, int flagy, int flagz, int axis) +{ + switch (axis) { + case 0: + /* axes */ + if (flagx) { + manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0])); + if (flagx & MAN_SCALE_X) glLoadName(MAN_SCALE_X); + else if (flagx & MAN_TRANS_X) glLoadName(MAN_TRANS_X); + glBegin(GL_LINES); + glVertex3f(0.2f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 0.0f); + glEnd(); + } + break; + case 1: + if (flagy) { + if (flagy & MAN_SCALE_Y) glLoadName(MAN_SCALE_Y); + else if (flagy & MAN_TRANS_Y) glLoadName(MAN_TRANS_Y); + manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1])); + glBegin(GL_LINES); + glVertex3f(0.0f, 0.2f, 0.0f); + glVertex3f(0.0f, 1.0f, 0.0f); + glEnd(); + } + break; + case 2: + if (flagz) { + if (flagz & MAN_SCALE_Z) glLoadName(MAN_SCALE_Z); + else if (flagz & MAN_TRANS_Z) glLoadName(MAN_TRANS_Z); + manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2])); + glBegin(GL_LINES); + glVertex3f(0.0f, 0.0f, 0.2f); + glVertex3f(0.0f, 0.0f, 1.0f); + glEnd(); + } + break; } - if (flagz) { - if (flagz & MAN_SCALE_Z) glLoadName(MAN_SCALE_Z); - else if (flagz & MAN_TRANS_Z) glLoadName(MAN_TRANS_Z); - manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2])); - glBegin(GL_LINES); - glVertex3f(0.0f, 0.0f, 0.2f); - glVertex3f(0.0f, 0.0f, 1.0f); - glEnd(); +} +static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode, + int flagx, int flagy, int flagz, + const int axis_order[3]) +{ + int i; + for (i = 0; i < 3; i++) { + draw_manipulator_axes_single(v3d, rv3d, colcode, flagx, flagy, flagz, axis_order[i]); } } @@ -1214,10 +1266,14 @@ static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving, { float cywid = 0.25f * 0.01f * (float)U.tw_handlesize; float cusize = cywid * 0.75f, dz; + int axis_order[3] = {2, 0, 1}; + int i; /* when called while moving in mixed mode, do not draw when... */ if ((drawflags & MAN_SCALE_C) == 0) return; + manipulator_axis_order(rv3d, axis_order); + glDisable(GL_DEPTH_TEST); /* not in combo mode */ @@ -1255,28 +1311,41 @@ static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving, /* axis */ /* in combo mode, this is always drawn as first type */ - draw_manipulator_axes(v3d, rv3d, colcode, drawflags & MAN_SCALE_X, drawflags & MAN_SCALE_Y, drawflags & MAN_SCALE_Z); - - /* Z cube */ - glTranslatef(0.0, 0.0, dz); - if (drawflags & MAN_SCALE_Z) { - if (G.f & G_PICKSEL) glLoadName(MAN_SCALE_Z); - manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2])); - drawsolidcube(cusize); - } - /* X cube */ - glTranslatef(dz, 0.0, -dz); - if (drawflags & MAN_SCALE_X) { - if (G.f & G_PICKSEL) glLoadName(MAN_SCALE_X); - manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0])); - drawsolidcube(cusize); - } - /* Y cube */ - glTranslatef(-dz, dz, 0.0); - if (drawflags & MAN_SCALE_Y) { - if (G.f & G_PICKSEL) glLoadName(MAN_SCALE_Y); - manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1])); - drawsolidcube(cusize); + draw_manipulator_axes(v3d, rv3d, colcode, + drawflags & MAN_SCALE_X, drawflags & MAN_SCALE_Y, drawflags & MAN_SCALE_Z, + axis_order); + + + for (i = 0; i < 3; i++) { + switch (axis_order[i]) { + case 0: /* X cube */ + if (drawflags & MAN_SCALE_X) { + glTranslatef(dz, 0.0, 0.0); + if (G.f & G_PICKSEL) glLoadName(MAN_SCALE_X); + manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0])); + drawsolidcube(cusize); + glTranslatef(-dz, 0.0, 0.0); + } + break; + case 1: /* Y cube */ + if (drawflags & MAN_SCALE_Y) { + glTranslatef(0.0, dz, 0.0); + if (G.f & G_PICKSEL) glLoadName(MAN_SCALE_Y); + manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1])); + drawsolidcube(cusize); + glTranslatef(0.0, -dz, 0.0); + } + break; + case 2: /* Z cube */ + if (drawflags & MAN_SCALE_Z) { + glTranslatef(0.0, 0.0, dz); + if (G.f & G_PICKSEL) glLoadName(MAN_SCALE_Z); + manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2])); + drawsolidcube(cusize); + glTranslatef(0.0, 0.0, -dz); + } + break; + } } /* if shiftkey, center point as last, for selectbuffer order */ @@ -1333,16 +1402,17 @@ static void draw_manipulator_translate(View3D *v3d, RegionView3D *rv3d, int UNUS float cywid = 0.25f * cylen, dz, size; float unitmat[4][4]; int shift = 0; // XXX + int axis_order[3] = {0, 1, 2}; + int i; /* when called while moving in mixed mode, do not draw when... */ if ((drawflags & MAN_TRANS_C) == 0) return; + manipulator_axis_order(rv3d, axis_order); + // XXX if (moving) glTranslatef(t->vec[0], t->vec[1], t->vec[2]); glDisable(GL_DEPTH_TEST); - qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - /* center circle, do not add to selection when shift is pressed (planar constraint) */ if ((G.f & G_PICKSEL) && shift == 0) glLoadName(MAN_TRANS_C); @@ -1360,8 +1430,11 @@ static void draw_manipulator_translate(View3D *v3d, RegionView3D *rv3d, int UNUS glLoadName(-1); // translate drawn as last, only axis when no combo with scale, or for ghosting - if ((combo & V3D_MANIP_SCALE) == 0 || colcode == MAN_GHOST) - draw_manipulator_axes(v3d, rv3d, colcode, drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z); + if ((combo & V3D_MANIP_SCALE) == 0 || colcode == MAN_GHOST) { + draw_manipulator_axes(v3d, rv3d, colcode, + drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z, + axis_order); + } /* offset in combo mode, for rotate a bit more */ @@ -1369,29 +1442,43 @@ static void draw_manipulator_translate(View3D *v3d, RegionView3D *rv3d, int UNUS else if (combo & (V3D_MANIP_SCALE)) dz = 1.0f + 0.5f * cylen; else dz = 1.0f; - /* Z Cone */ - glTranslatef(0.0, 0.0, dz); - if (drawflags & MAN_TRANS_Z) { - if (G.f & G_PICKSEL) glLoadName(MAN_TRANS_Z); - manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2])); - draw_cone(qobj, cylen, cywid); - } - /* X Cone */ - glTranslatef(dz, 0.0, -dz); - if (drawflags & MAN_TRANS_X) { - if (G.f & G_PICKSEL) glLoadName(MAN_TRANS_X); - glRotatef(90.0, 0.0, 1.0, 0.0); - manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0])); - draw_cone(qobj, cylen, cywid); - glRotatef(-90.0, 0.0, 1.0, 0.0); - } - /* Y Cone */ - glTranslatef(-dz, dz, 0.0); - if (drawflags & MAN_TRANS_Y) { - if (G.f & G_PICKSEL) glLoadName(MAN_TRANS_Y); - glRotatef(-90.0, 1.0, 0.0, 0.0); - manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1])); - draw_cone(qobj, cylen, cywid); + qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + + for (i = 0; i < 3; i++) { + switch (axis_order[i]) { + case 0: /* Z Cone */ + if (drawflags & MAN_TRANS_Z) { + glTranslatef(0.0, 0.0, dz); + if (G.f & G_PICKSEL) glLoadName(MAN_TRANS_Z); + manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2])); + draw_cone(qobj, cylen, cywid); + glTranslatef(0.0, 0.0, -dz); + } + break; + case 1: /* X Cone */ + if (drawflags & MAN_TRANS_X) { + glTranslatef(dz, 0.0, 0.0); + if (G.f & G_PICKSEL) glLoadName(MAN_TRANS_X); + glRotatef(90.0, 0.0, 1.0, 0.0); + manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0])); + draw_cone(qobj, cylen, cywid); + glRotatef(-90.0, 0.0, 1.0, 0.0); + glTranslatef(-dz, 0.0, 0.0); + } + break; + case 2: /* Y Cone */ + if (drawflags & MAN_TRANS_Y) { + glTranslatef(0.0, dz, 0.0); + if (G.f & G_PICKSEL) glLoadName(MAN_TRANS_Y); + glRotatef(-90.0, 1.0, 0.0, 0.0); + manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1])); + draw_cone(qobj, cylen, cywid); + glRotatef(90.0, 1.0, 0.0, 0.0); + glTranslatef(0.0, -dz, 0.0); + } + break; + } } gluDeleteQuadric(qobj); @@ -1407,10 +1494,13 @@ static void draw_manipulator_rotate_cyl(View3D *v3d, RegionView3D *rv3d, int mov float size; float cylen = 0.01f * (float)U.tw_handlesize; float cywid = 0.25f * cylen; - + int axis_order[3] = {2, 0, 1}; + int i; /* when called while moving in mixed mode, do not draw when... */ if ((drawflags & MAN_ROT_C) == 0) return; + manipulator_axis_order(rv3d, axis_order); + /* prepare for screen aligned draw */ glPushMatrix(); size = screen_aligned(rv3d, rv3d->twmat); @@ -1461,36 +1551,50 @@ static void draw_manipulator_rotate_cyl(View3D *v3d, RegionView3D *rv3d, int mov if ((G.f & G_PICKSEL) == 0) { // only draw axis when combo didn't draw scale axes - if ((combo & V3D_MANIP_SCALE) == 0) - draw_manipulator_axes(v3d, rv3d, colcode, drawflags & MAN_ROT_X, drawflags & MAN_ROT_Y, drawflags & MAN_ROT_Z); + if ((combo & V3D_MANIP_SCALE) == 0) { + draw_manipulator_axes(v3d, rv3d, colcode, + drawflags & MAN_ROT_X, drawflags & MAN_ROT_Y, drawflags & MAN_ROT_Z, + axis_order); + } /* only has to be set when not in picking */ gluQuadricDrawStyle(qobj, GLU_FILL); } - /* Z cyl */ - glTranslatef(0.0, 0.0, 1.0); - if (drawflags & MAN_ROT_Z) { - if (G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); - manipulator_setcolor(v3d, 'Z', colcode, 255); - draw_cylinder(qobj, cylen, cywid); - } - /* X cyl */ - glTranslatef(1.0, 0.0, -1.0); - if (drawflags & MAN_ROT_X) { - if (G.f & G_PICKSEL) glLoadName(MAN_ROT_X); - glRotatef(90.0, 0.0, 1.0, 0.0); - manipulator_setcolor(v3d, 'X', colcode, 255); - draw_cylinder(qobj, cylen, cywid); - glRotatef(-90.0, 0.0, 1.0, 0.0); - } - /* Y cylinder */ - glTranslatef(-1.0, 1.0, 0.0); - if (drawflags & MAN_ROT_Y) { - if (G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); - glRotatef(-90.0, 1.0, 0.0, 0.0); - manipulator_setcolor(v3d, 'Y', colcode, 255); - draw_cylinder(qobj, cylen, cywid); + for (i = 0; i < 3; i++) { + switch (axis_order[i]) { + case 0: /* X cylinder */ + if (drawflags & MAN_ROT_X) { + glTranslatef(1.0, 0.0, 0.0); + if (G.f & G_PICKSEL) glLoadName(MAN_ROT_X); + glRotatef(90.0, 0.0, 1.0, 0.0); + manipulator_setcolor(v3d, 'X', colcode, 255); + draw_cylinder(qobj, cylen, cywid); + glRotatef(-90.0, 0.0, 1.0, 0.0); + glTranslatef(-1.0, 0.0, 0.0); + } + break; + case 1: /* Y cylinder */ + if (drawflags & MAN_ROT_Y) { + glTranslatef(0.0, 1.0, 0.0); + if (G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); + glRotatef(-90.0, 1.0, 0.0, 0.0); + manipulator_setcolor(v3d, 'Y', colcode, 255); + draw_cylinder(qobj, cylen, cywid); + glRotatef(90.0, 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.0, 0.0); + } + break; + case 2: /* Z cylinder */ + if (drawflags & MAN_ROT_Z) { + glTranslatef(0.0, 0.0, 1.0); + if (G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); + manipulator_setcolor(v3d, 'Z', colcode, 255); + draw_cylinder(qobj, cylen, cywid); + glTranslatef(0.0, 0.0, -1.0); + } + break; + } } /* restore */ |