[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24168] trunk/blender/source/blender/ editors: 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 ).

Martin Poirier theeth at yahoo.com
Thu Oct 29 22:34:09 CET 2009


Revision: 24168
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24168
Author:   theeth
Date:     2009-10-29 22:34:09 +0100 (Thu, 29 Oct 2009)

Log Message:
-----------
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).

Modified Paths:
--------------
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/transform/transform_manipulator.c

Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c	2009-10-29 21:31:55 UTC (rev 24167)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c	2009-10-29 21:34:09 UTC (rev 24168)
@@ -2034,9 +2034,10 @@
 	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 @@
 		 * 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 @@
 		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 @@
 
 		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 @@
 			}
 			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 @@
 			
 			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 @@
 			}
 			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 @@
 	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;
 			}

Modified: trunk/blender/source/blender/editors/transform/transform_manipulator.c
===================================================================
--- trunk/blender/source/blender/editors/transform/transform_manipulator.c	2009-10-29 21:31:55 UTC (rev 24167)
+++ trunk/blender/source/blender/editors/transform/transform_manipulator.c	2009-10-29 21:34:09 UTC (rev 24168)
@@ -736,12 +736,43 @@
 	}
 }
 
+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 @@
 		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 @@
 			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 @@
 			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 @@
 			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 @@
 {
 	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 @@
 	}
 	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 @@
 		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 @@
 
 		/* 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 @@
 
 		/* 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);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list