diff options
author | Joseph Eagar <joeedh@gmail.com> | 2010-09-04 09:31:25 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2010-09-04 09:31:25 +0400 |
commit | bb7339a7aec37bdb2ee8a21599e6c65b37ef1277 (patch) | |
tree | 6fb8da94c6e43098c606f768e722484b04b8645c /source/blender/python/generic/mathutils_quat.c | |
parent | 37f2c8a64c3277f100ab084ef1bb3846bc7b2c62 (diff) | |
parent | 8a320974f1b3e6004db3b3ad64f97742f878cbee (diff) |
merge with trunk at r31523
Diffstat (limited to 'source/blender/python/generic/mathutils_quat.c')
-rw-r--r-- | source/blender/python/generic/mathutils_quat.c | 134 |
1 files changed, 104 insertions, 30 deletions
diff --git a/source/blender/python/generic/mathutils_quat.c b/source/blender/python/generic/mathutils_quat.c index f94e5e2a03a..553844b6ee5 100644 --- a/source/blender/python/generic/mathutils_quat.c +++ b/source/blender/python/generic/mathutils_quat.c @@ -109,7 +109,7 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args) } //----------------------------Quaternion.toMatrix()------------------ static char Quaternion_ToMatrix_doc[] = -".. method:: to_matrix(other)\n" +".. method:: to_matrix()\n" "\n" " Return a matrix representation of the quaternion.\n" "\n" @@ -190,9 +190,7 @@ static char Quaternion_Difference_doc[] = 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 @@ static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject 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); } @@ -668,8 +660,9 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) return NULL; } - if(quat1 && quat2) { /* QUAT*QUAT (dot product) */ - return PyFloat_FromDouble(dot_qtqt(quat1->quat, quat2->quat)); + if(quat1 && quat2) { /* QUAT*QUAT (cross product) */ + mul_qt_qtqt(quat, quat1->quat, quat2->quat); + return newQuaternionObject(quat, Py_NEW, NULL); } /* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */ @@ -685,12 +678,19 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) } else { /* QUAT*SOMETHING */ if(VectorObject_Check(q2)){ /* QUAT*VEC */ + float tvec[3]; vec = (VectorObject*)q2; if(vec->size != 3){ PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n"); return NULL; } - return quat_rotation((PyObject*)quat1, (PyObject*)vec); /* vector updating done inside the func */ + if(!BaseMath_ReadCallback(vec)) { + return NULL; + } + + copy_v3_v3(tvec, vec->vec); + mul_qt_v3(quat1->quat, tvec); + return newVectorObject(tvec, 3, Py_NEW, NULL); } scalar= PyFloat_AsDouble(q2); @@ -774,27 +774,101 @@ static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type ) { + if(!BaseMath_ReadCallback(self)) + return NULL; + return PyFloat_FromDouble(sqrt(dot_qtqt(self->quat, self->quat))); } static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type ) { + if(!BaseMath_ReadCallback(self)) + return NULL; + return PyFloat_FromDouble(2.0 * (saacos(self->quat[0]))); } -static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type ) +static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void * type) +{ + float axis[3]; + float angle; + + if(!BaseMath_ReadCallback(self)) + return -1; + + quat_to_axis_angle(axis, &angle, self->quat); + + 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; + } + + /* 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) && + EXPP_FloatsAreEqual(axis[2], 0.0f, 10) + ) { + axis[0] = 1.0f; + } + + axis_angle_to_quat(self->quat, axis, angle); + + if(!BaseMath_WriteCallback(self)) + return -1; + + return 0; +} + +static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *type) { - float vec[3]; + float axis[3]; + float angle; - normalize_v3_v3(vec, self->quat+1); + if(!BaseMath_ReadCallback(self)) + return NULL; + + quat_to_axis_angle(axis, &angle, self->quat); /* If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations */ - if( EXPP_FloatsAreEqual(vec[0], 0.0f, 10) && - EXPP_FloatsAreEqual(vec[1], 0.0f, 10) && - EXPP_FloatsAreEqual(vec[2], 0.0f, 10) ){ - vec[0] = 1.0f; + if( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && + EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && + EXPP_FloatsAreEqual(axis[2], 0.0f, 10) + ) { + axis[0] = 1.0f; } - return (PyObject *) newVectorObject(vec, 3, Py_NEW, NULL); + + return (PyObject *) newVectorObject(axis, 3, Py_NEW, NULL); +} + +static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *type) +{ + float axis[3]; + float angle; + + VectorObject *vec; + + if(!BaseMath_ReadCallback(self)) + return -1; + + quat_to_axis_angle(axis, &angle, self->quat); + + if(!VectorObject_Check(value)) { + PyErr_SetString(PyExc_TypeError, "quaternion.axis = value: expected a 3D Vector"); + return -1; + } + + vec= (VectorObject *)value; + if(!BaseMath_ReadCallback(vec)) + return -1; + + axis_angle_to_quat(self->quat, vec->vec, angle); + + if(!BaseMath_WriteCallback(self)) + return -1; + + return 0; } //----------------------------------mathutils.Quaternion() -------------- @@ -848,15 +922,15 @@ static struct PyMethodDef Quaternion_methods[] = { /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Quaternion_getseters[] = { - {"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion W value. **type** float", (void *)0}, - {"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion X axis. **type** float", (void *)1}, - {"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Y axis. **type** float", (void *)2}, - {"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Z axis. **type** float", (void *)3}, - {"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, "Size of the quaternion (readonly). **type** float", NULL}, - {"angle", (getter)Quaternion_getAngle, (setter)NULL, "angle of the quaternion (readonly). **type** float", NULL}, - {"axis",(getter)Quaternion_getAxisVec, (setter)NULL, "quaternion axis as a vector (readonly). **type** :class:`Vector`", NULL}, + {"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion W value.\n\n:type: float", (void *)0}, + {"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion X axis.\n\n:type: float", (void *)1}, + {"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Y axis.\n\n:type: float", (void *)2}, + {"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Z axis.\n\n:type: float", (void *)3}, + {"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, "Size of the quaternion (readonly).\n\n:type: float", NULL}, + {"angle", (getter)Quaternion_getAngle, (setter)Quaternion_setAngle, "angle of the quaternion.\n\n:type: float", NULL}, + {"axis",(getter)Quaternion_getAxisVec, (setter)Quaternion_setAxisVec, "quaternion axis as a vector.\n\n:type: :class:`Vector`", NULL}, {"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL}, - {"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL}, + {"owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; |