diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-01-11 12:41:26 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-01-11 12:41:26 +0300 |
commit | ca3d4052de2b26d4f3f15c4786794e619ffeef26 (patch) | |
tree | 5c7a00f74b83a11df40acdb9f7e0044110e7d9f7 /source | |
parent | 5bcee8cd0ad11f93cc067c3c251676e7c921ce74 (diff) |
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.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/generic/mathutils_matrix.c | 12 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_quat.c | 16 |
2 files changed, 14 insertions, 14 deletions
diff --git a/source/blender/python/generic/mathutils_matrix.c b/source/blender/python/generic/mathutils_matrix.c index 2418f746dd0..c36341269db 100644 --- a/source/blender/python/generic/mathutils_matrix.c +++ b/source/blender/python/generic/mathutils_matrix.c @@ -170,11 +170,11 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) 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 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) } } - 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; diff --git a/source/blender/python/generic/mathutils_quat.c b/source/blender/python/generic/mathutils_quat.c index 18eabcb77a1..9d79a86dbcc 100644 --- a/source/blender/python/generic/mathutils_quat.c +++ b/source/blender/python/generic/mathutils_quat.c @@ -782,22 +782,24 @@ static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void * 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 int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void * 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 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw 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 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw 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 */ |