[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34252] trunk/blender/source/blender/ python/generic: py/mathutils fix for eternal loop with Matrix.Rotation().

Campbell Barton ideasman42 at gmail.com
Tue Jan 11 10:41:27 CET 2011


Revision: 34252
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=34252
Author:   campbellbarton
Date:     2011-01-11 09:41:26 +0000 (Tue, 11 Jan 2011)
Log Message:
-----------
py/mathutils fix for eternal loop with Matrix.Rotation().
rotation range clamping used a while loop which would run forever when the value was so big subtracting a full revolution didnt change the value.

Solve by using fmod() and double precision angle.

Modified Paths:
--------------
    trunk/blender/source/blender/python/generic/mathutils_matrix.c
    trunk/blender/source/blender/python/generic/mathutils_quat.c

Modified: trunk/blender/source/blender/python/generic/mathutils_matrix.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_matrix.c	2011-01-11 08:25:34 UTC (rev 34251)
+++ trunk/blender/source/blender/python/generic/mathutils_matrix.c	2011-01-11 09:41:26 UTC (rev 34252)
@@ -170,11 +170,11 @@
 	VectorObject *vec= NULL;
 	char *axis= NULL;
 	int matSize;
-	float angle = 0.0f;
+	double angle; /* use double because of precission problems at high values */
 	float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
 		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
 
-	if(!PyArg_ParseTuple(args, "fi|O", &angle, &matSize, &vec)) {
+	if(!PyArg_ParseTuple(args, "di|O", &angle, &matSize, &vec)) {
 		PyErr_SetString(PyExc_TypeError, "mathutils.RotationMatrix(angle, size, axis): expected float int and a string or vector");
 		return NULL;
 	}
@@ -191,11 +191,9 @@
 		}
 	}
 
-	while (angle<-(Py_PI*2))
-		angle+=(Py_PI*2);
-	while (angle>(Py_PI*2))
-		angle-=(Py_PI*2);
-	
+	/* clamp angle between -360 and 360 in radians */
+	angle= fmod(angle + M_PI*2, M_PI*4) - M_PI*2;
+
 	if(matSize != 2 && matSize != 3 && matSize != 4) {
 		PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix");
 		return NULL;

Modified: trunk/blender/source/blender/python/generic/mathutils_quat.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_quat.c	2011-01-11 08:25:34 UTC (rev 34251)
+++ trunk/blender/source/blender/python/generic/mathutils_quat.c	2011-01-11 09:41:26 UTC (rev 34252)
@@ -782,22 +782,24 @@
 	float tquat[4];
 	float len;
 	
-	float axis[3];
-	float angle;
+	float axis[3], angle_dummy;
+	double angle;
 
 	if(!BaseMath_ReadCallback(self))
 		return -1;
 
 	len= normalize_qt_qt(tquat, self->quat);
-	quat_to_axis_angle(axis, &angle, tquat);
+	quat_to_axis_angle(axis, &angle_dummy, tquat);
 
-	angle = PyFloat_AsDouble(value);
+	angle= PyFloat_AsDouble(value);
 
 	if(angle==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
 		PyErr_SetString(PyExc_TypeError, "quaternion.angle = value: float expected");
 		return -1;
 	}
 
+	angle= fmod(angle + M_PI*2, M_PI*4) - M_PI*2;
+
 	/* If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations */
 	if( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) &&
 		EXPP_FloatsAreEqual(axis[1], 0.0f, 10) &&
@@ -878,7 +880,7 @@
 static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
 	PyObject *seq= NULL;
-	float angle = 0.0f;
+	double angle = 0.0f;
 	float quat[QUAT_SIZE]= {0.0f, 0.0f, 0.0f, 0.0f};
 
 	if(kwds && PyDict_Size(kwds)) {
@@ -886,7 +888,7 @@
 		return NULL;
 	}
 	
-	if(!PyArg_ParseTuple(args, "|Of:mathutils.Quaternion", &seq, &angle))
+	if(!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle))
 		return NULL;
 
 	switch(PyTuple_GET_SIZE(args)) {
@@ -899,7 +901,7 @@
 	case 2:
 		if (mathutils_array_parse(quat, 3, 3, seq, "mathutils.Quaternion()") == -1)
 			return NULL;
-
+		angle= fmod(angle + M_PI*2, M_PI*4) - M_PI*2; /* clamp because of precission issues */
 		axis_angle_to_quat(quat, quat, angle);
 		break;
 	/* PyArg_ParseTuple assures no more then 2 */




More information about the Bf-blender-cvs mailing list