[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30727] trunk/blender/source/blender: bugfix [#22836] Alt+MMB view alignment don't respect all axes directions

Campbell Barton ideasman42 at gmail.com
Mon Jul 26 02:11:14 CEST 2010


Revision: 30727
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30727
Author:   campbellbarton
Date:     2010-07-26 02:11:14 +0200 (Mon, 26 Jul 2010)

Log Message:
-----------
bugfix [#22836] Alt+MMB view alignment don't respect all axes directions
also moved rotation_between_quats_to_quat into BLI_math from python mathutils.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_math_rotation.h
    trunk/blender/source/blender/blenlib/intern/math_rotation.c
    trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
    trunk/blender/source/blender/python/generic/mathutils_quat.c

Modified: trunk/blender/source/blender/blenlib/BLI_math_rotation.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_rotation.h	2010-07-25 22:49:40 UTC (rev 30726)
+++ trunk/blender/source/blender/blenlib/BLI_math_rotation.h	2010-07-26 00:11:14 UTC (rev 30727)
@@ -40,10 +40,10 @@
 
 /* init */
 void unit_qt(float q[4]);
-void copy_qt_qt(float q[4], float a[4]);
+void copy_qt_qt(float q[4], const float a[4]);
 
 /* arithmetic */
-void mul_qt_qtqt(float q[4], float a[4], float b[4]);
+void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
 void mul_qt_v3(float q[4], float r[3]);
 void mul_qt_fl(float q[4], float f);
 void mul_fac_qt_fl(float q[4], float f);
@@ -51,6 +51,7 @@
 void sub_qt_qtqt(float q[4], float a[4], float b[4]);
 
 void invert_qt(float q[4]);
+void invert_qt_qt(float *q1, const float *q2);
 void conjugate_qt(float q[4]);
 float dot_qtqt(float a[4], float b[4]);
 void normalize_qt(float q[4]);
@@ -72,6 +73,7 @@
 void vec_to_quat(float q[4], float vec[3], short axis, short upflag);
 /* note: v1 and v2 must be normalized */
 void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
+void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]);
 
 /* TODO: don't what this is, but it's not the same as mat3_to_quat */
 void mat3_to_quat_is_ok(float q[4], float mat[3][3]);

Modified: trunk/blender/source/blender/blenlib/intern/math_rotation.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_rotation.c	2010-07-25 22:49:40 UTC (rev 30726)
+++ trunk/blender/source/blender/blenlib/intern/math_rotation.c	2010-07-26 00:11:14 UTC (rev 30727)
@@ -36,7 +36,7 @@
 	q[1]= q[2]= q[3]= 0.0f;
 }
 
-void copy_qt_qt(float *q1, float *q2)
+void copy_qt_qt(float *q1, const float *q2)
 {
 	q1[0]= q2[0];
 	q1[1]= q2[1];
@@ -49,7 +49,7 @@
 	return (q[0] == 0 && q[1] == 0 && q[2] == 0 && q[3] == 0);
 }
 
-void mul_qt_qtqt(float *q, float *q1, float *q2)
+void mul_qt_qtqt(float *q, const float *q1, const float *q2)
 {
 	float t0,t1,t2;
 
@@ -104,6 +104,12 @@
 	mul_qt_fl(q, 1.0f/f);
 }
 
+void invert_qt_qt(float *q1, const float *q2)
+{
+	copy_qt_qt(q1, q2);
+	invert_qt(q1);
+}
+
 /* simple mult */
 void mul_qt_fl(float *q, float f)
 {
@@ -336,6 +342,23 @@
 	axis_angle_to_quat(q, axis, angle);
 }
 
+void rotation_between_quats_to_quat(float *q, const float q1[4], const float q2[4])
+{
+	float tquat[4];
+	double dot = 0.0f;
+	int x;
+
+	copy_qt_qt(tquat, q1);
+	conjugate_qt(tquat);
+	dot = 1.0f / dot_qtqt(tquat, tquat);
+
+	for(x = 0; x < 4; x++)
+		tquat[x] *= dot;
+
+	mul_qt_qtqt(q, tquat, q2);
+}
+
+
 void vec_to_quat(float *q,float *vec, short axis, short upflag)
 {
 	float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1;

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2010-07-25 22:49:40 UTC (rev 30726)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2010-07-26 00:11:14 UTC (rev 30727)
@@ -600,23 +600,66 @@
 	/* check for view snap */
 	if (vod->axis_snap){
 		int i;
-		float viewmat[3][3];
+		float viewquat_inv[4];
+		float zaxis[3]={0,0,1};
+		invert_qt_qt(viewquat_inv, rv3d->viewquat);
 
+		mul_qt_v3(viewquat_inv, zaxis);
 
-		quat_to_mat3( viewmat,rv3d->viewquat);
+		for (i = 0 ; i < 39; i++){
 
-		for (i = 0 ; i < 39; i++){
-			float snapmat[3][3];
 			float view = (int)snapquats[i][4];
+			float viewquat_inv_test[4];
+			float zaxis_test[3]={0,0,1};
 
-			quat_to_mat3( snapmat,snapquats[i]);
+			invert_qt_qt(viewquat_inv_test, snapquats[i]);
+			mul_qt_v3(viewquat_inv_test, zaxis_test);
+			
+			if(angle_v3v3(zaxis_test, zaxis) < DEG2RAD(45/3)) {
+				/* find the best roll */
+				float quat_roll[4], quat_final[4], quat_best[4];
+				float viewquat_align[4]; /* viewquat aligned to zaxis_test */
+				float viewquat_align_inv[4]; /* viewquat aligned to zaxis_test */
+				float best_angle = FLT_MAX;
+				int j;
 
-			if ((dot_v3v3(snapmat[0], viewmat[0]) > thres) &&
-				(dot_v3v3(snapmat[1], viewmat[1]) > thres) &&
-				(dot_v3v3(snapmat[2], viewmat[2]) > thres)
-			) {
-				copy_qt_qt(rv3d->viewquat, snapquats[i]);
-				rv3d->view= view;
+				/* viewquat_align is the original viewquat aligned to the snapped axis
+				 * for testing roll */
+				rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis);
+				normalize_qt(viewquat_align);
+				mul_qt_qtqt(viewquat_align, rv3d->viewquat, viewquat_align);
+				normalize_qt(viewquat_align);
+				invert_qt_qt(viewquat_align_inv, viewquat_align);
+
+				/* find best roll */
+				for(j= 0; j<8; j++) {
+					float angle;
+					float xaxis1[3]={1,0,0};
+					float xaxis2[3]={1,0,0};
+					float quat_final_inv[4];
+
+					axis_angle_to_quat(quat_roll, zaxis_test, j * DEG2RAD(45.0));
+					normalize_qt(quat_roll);
+
+					mul_qt_qtqt(quat_final, snapquats[i], quat_roll);
+					normalize_qt(quat_final);
+					
+					/* compare 2 vector angles to find the least roll */
+					invert_qt_qt(quat_final_inv, quat_final);
+					mul_qt_v3(viewquat_align_inv, xaxis1);
+					mul_qt_v3(quat_final_inv, xaxis2);
+					angle= angle_v3v3(xaxis1, xaxis2);
+
+					if(angle <= best_angle) {
+						best_angle= angle;
+						copy_qt_qt(quat_best, quat_final);
+						if(j) view= 0; /* view grid assumes certain up axis */
+					}
+				}
+
+				copy_qt_qt(rv3d->viewquat, quat_best);
+				rv3d->view= view; /* if we snap to a rolled camera the grid is invalid */
+
 				break;
 			}
 		}

Modified: trunk/blender/source/blender/python/generic/mathutils_quat.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_quat.c	2010-07-25 22:49:40 UTC (rev 30726)
+++ trunk/blender/source/blender/python/generic/mathutils_quat.c	2010-07-26 00:11:14 UTC (rev 30727)
@@ -190,9 +190,7 @@
 
 static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject * value)
 {
-	float quat[QUAT_SIZE], tempQuat[QUAT_SIZE];
-	double dot = 0.0f;
-	int x;
+	float quat[QUAT_SIZE];
 
 	if (!QuaternionObject_Check(value)) {
 		PyErr_SetString( PyExc_TypeError, "quat.difference(value): expected a quaternion argument" );
@@ -202,14 +200,8 @@
 	if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
 		return NULL;
 
-	copy_qt_qt(tempQuat, self->quat);
-	conjugate_qt(tempQuat);
-	dot = sqrt(dot_qtqt(tempQuat, tempQuat));
+	rotation_between_quats_to_quat(quat, self->quat, value->quat);
 
-	for(x = 0; x < QUAT_SIZE; x++) {
-		tempQuat[x] /= (float)(dot * dot);
-	}
-	mul_qt_qtqt(quat, tempQuat, value->quat);
 	return newQuaternionObject(quat, Py_NEW, NULL);
 }
 





More information about the Bf-blender-cvs mailing list