[Bf-committers] Bug #816 (180 deg rotation limit for trackball in 3D window) with Possible Patch

Nathanael Law bf-committers@blender.org
Thu, 25 Dec 2003 09:23:55 -0700


--ibTvN161/egqYuK8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello all,

I would like to discuss a possible solution to bug #816. To summarize
the bug report, in the 3D window, you cannot rotate beyond 180 degrees
in trackball mode.

1. Is this the behavior that is desired?

2. If not, does the included patch correctly address the issue?

3. If you think it does address the issue, but is not well-coded, what
   can I do to improve it?

The included patch allows unlimited rotation in the 3D window in
trackball mode; however, it changes the relationship between the mouse
movement and the angle rotation.

The unpatched angle of rotation is proportional to the arcsin of the
relative distance that the mouse has moved.  This works quite will if
rotation is restricted to the [-180,180] degree interval.  The
response graph is shown at
http://www.xyrodian.com/bf-committers/UTRR.png  For the majority of
the range of operation, the response is approximately linear.

If the interval of rotation is extended without changing the
relationship between the mouse distance and the angle of rotation, the
non-linear part of the relationship becomes very obvious.  I immediately
noticed this when I was testing the extension of rotation.  The response
graph is shown at http://www.xyrodian.com/bf-committers/ETRR.png and a
zoomed in view of the non-linear region is at
http://www.xyrodian.com/bf-committers/ETRRZ.png.  The result of this is
the user feels a lack of control around the +/- 180 range.  A small
movement of the mouse rotates the view by a large number of degrees.

To eradicate the non-linear response for the extended range of
rotation, I changed the conversion of mouse distance to angle from
phi = asin(si) to phi = si * M_PI / 2.0.  As can be seen in the patched
response, http://www.xyrodian.com/bf-committers/PTRR.png, this results
in completely linear response that very closely resembles the current
behavior for most angles and eliminates the rapid change of angles
around +/- 180 degrees.

I appreciate any feedback: comments, criticisms, suggestions, etc.

References
 - http://projects.blender.org/tracker/index.php?func=detail&aid=816&group_id=9&atid=125
 - http://www.xyrodian.com/bf-committers/UTRR.png
 - http://www.xyrodian.com/bf-committers/ETRR.png
 - http://www.xyrodian.com/bf-committers/ETRRZ.png
 - http://www.xyrodian.com/bf-committers/PTRR.png
 
-- 
 - Nathanael Law <njlaw@xyrodian.com>


--ibTvN161/egqYuK8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="Bug816Fix.diff"

Index: source/blender/src/view.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/view.c,v
retrieving revision 1.20
diff -u -r1.20 view.c
--- source/blender/src/view.c	21 Dec 2003 21:52:51 -0000	1.20
+++ source/blender/src/view.c	25 Dec 2003 14:59:46 -0000
@@ -459,35 +459,42 @@
 				si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]);
 				si/= (2.0*TRACKBALLSIZE);
 				
-				/* is there an acceptable solution? (180 degrees limitor) */
-				if(si<1.0) {
-					Crossf(q1+1, firstvec, newvec);
+				Crossf(q1+1, firstvec, newvec);
 
-					Normalise(q1+1);
+				Normalise(q1+1);
 		
-					phi= asin(si);
-	
-					si= sin(phi);
-					q1[0]= cos(phi);
-					q1[1]*= si;
-					q1[2]*= si;
-					q1[3]*= si;
+				/* Allow for rotation beyond the interval
+				 * [-pi, pi] */
+				while (si > 1.0)
+					si -= 2.0;
+
+				/* This relation is used instead of
+				 * phi = asin(si) so that the angle
+				 * of rotation is linearly proportional
+				 * to the distance that the mouse is
+				 * dragged. */
+				phi = si * M_PI / 2.0;
+	
+				si= sin(phi);
+				q1[0]= cos(phi);
+				q1[1]*= si;
+				q1[2]*= si;
+				q1[3]*= si;
 					
-					QuatMul(G.vd->viewquat, q1, oldquat);
+				QuatMul(G.vd->viewquat, q1, oldquat);
 
-					if( (U.flag & TRACKBALL)==0 ) {
+				if( (U.flag & TRACKBALL)==0 ) {
 					
-						/* rotate around z-axis (mouse x moves)  */
+					/* rotate around z-axis (mouse x moves)  */
 						
-						phi= 2*(mval[0]-mvalball[0]);
-						phi/= (float)curarea->winx;
-						si= sin(phi);
-						q1[0]= cos(phi);
-						q1[1]= q1[2]= 0.0;
-						q1[3]= si;
+					phi= 2*(mval[0]-mvalball[0]);
+					phi/= (float)curarea->winx;
+					si= sin(phi);
+					q1[0]= cos(phi);
+					q1[1]= q1[2]= 0.0;
+					q1[3]= si;
 						
-						QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
-					}
+					QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
 				}
 			}
 			else if(mode==1) {	/* translate */
@@ -1107,4 +1114,4 @@
 
 	v3d->view= 0;
 	if (v3d->persp>=2) v3d->persp= 0; /* switch out of camera mode */
-}
\ No newline at end of file
+}

--ibTvN161/egqYuK8--