PyObject* PyObjectFrom(const MT_Quaternion &qrot) { /* NOTE, were re-ordering here for Mathutils compat */ float fvec[4]; qrot.getValue(fvec); return Quaternion_CreatePyObject(fvec, Py_NEW, NULL); }
static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar) { float tquat[4]; copy_qt_qt(tquat, quat->quat); mul_qt_fl(tquat, scalar); return Quaternion_CreatePyObject(tquat, Py_NEW, Py_TYPE(quat)); }
/* subtraction */ static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2) { int x; float quat[QUAT_SIZE]; QuaternionObject *quat1 = NULL, *quat2 = NULL; if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) { PyErr_Format(PyExc_TypeError, "Quaternion subtraction: (%s - %s) " "invalid type for this operation", Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); return NULL; } quat1 = (QuaternionObject *)q1; quat2 = (QuaternionObject *)q2; if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) return NULL; for (x = 0; x < QUAT_SIZE; x++) { quat[x] = quat1->quat[x] - quat2->quat[x]; } return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1)); }
static PyObject *Quaternion_copy(QuaternionObject *self) { if (BaseMath_ReadCallback(self) == -1) return NULL; return Quaternion_CreatePyObject(self->quat, Py_NEW, Py_TYPE(self)); }
static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args) { PyObject *value; float tquat[QUAT_SIZE], quat[QUAT_SIZE], fac; if (!PyArg_ParseTuple(args, "Of:slerp", &value, &fac)) { PyErr_SetString(PyExc_TypeError, "quat.slerp(): " "expected Quaternion types and float"); return NULL; } if (BaseMath_ReadCallback(self) == -1) return NULL; if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.slerp(other), invalid 'other' arg") == -1) { return NULL; } if (fac > 1.0f || fac < 0.0f) { PyErr_SetString(PyExc_ValueError, "quat.slerp(): " "interpolation factor must be between 0.0 and 1.0"); return NULL; } interp_qt_qtqt(quat, self->quat, tquat, fac); return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self)); }
/* -obj * returns the negative of this object*/ static PyObject *Quaternion_neg(QuaternionObject *self) { float tquat[QUAT_SIZE]; if (BaseMath_ReadCallback(self) == -1) return NULL; negate_v4_v4(tquat, self->quat); return Quaternion_CreatePyObject(tquat, Py_NEW, Py_TYPE(self)); }
static PyObject *Euler_to_quaternion(EulerObject *self) { float quat[4]; if (BaseMath_ReadCallback(self) == -1) return NULL; eulO_to_quat(quat, self->eul, self->order); return Quaternion_CreatePyObject(quat, Py_NEW, NULL); }
PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user, unsigned char cb_type, unsigned char cb_subtype) { QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, Py_NEW, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; self->cb_type = cb_type; self->cb_subtype = cb_subtype; PyObject_GC_Track(self); } return (PyObject *)self; }
static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value) { float quat[QUAT_SIZE], tquat[QUAT_SIZE]; if (BaseMath_ReadCallback(self) == -1) return NULL; if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.cross(other), invalid 'other' arg") == -1) { return NULL; } mul_qt_qtqt(quat, self->quat, tquat); return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self)); }
static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject *value) { float tquat[QUAT_SIZE], quat[QUAT_SIZE]; if (BaseMath_ReadCallback(self) == -1) return NULL; if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.difference(other), invalid 'other' arg") == -1) { return NULL; } rotation_between_quats_to_quat(quat, self->quat, tquat); return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self)); }
//------------------------NUMERIC PROTOCOLS---------------------- //------------------------obj + obj------------------------------ //addition static PyObject *Quaternion_add(PyObject *q1, PyObject *q2) { float quat[QUAT_SIZE]; QuaternionObject *quat1 = NULL, *quat2 = NULL; if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) { PyErr_Format(PyExc_TypeError, "Quaternion addition: (%s + %s) " "invalid type for this operation", Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); return NULL; } quat1 = (QuaternionObject *)q1; quat2 = (QuaternionObject *)q2; if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) return NULL; add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f); return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1)); }
/* ----------------------------------mathutils.Quaternion() -------------- */ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *seq = NULL; double angle = 0.0f; float quat[QUAT_SIZE] = {0.0f, 0.0f, 0.0f, 0.0f}; if (kwds && PyDict_Size(kwds)) { PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): " "takes no keyword args"); return NULL; } if (!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle)) return NULL; switch (PyTuple_GET_SIZE(args)) { case 0: break; case 1: if (mathutils_array_parse(quat, QUAT_SIZE, QUAT_SIZE, seq, "mathutils.Quaternion()") == -1) return NULL; break; case 2: { float axis[3]; if (mathutils_array_parse(axis, 3, 3, seq, "mathutils.Quaternion()") == -1) return NULL; angle = angle_wrap_rad(angle); /* clamp because of precision issues */ axis_angle_to_quat(quat, axis, angle); break; /* PyArg_ParseTuple assures no more than 2 */ } } return Quaternion_CreatePyObject(quat, Py_NEW, type); }
//------------------------obj * obj------------------------------ //mulplication static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) { float quat[QUAT_SIZE], scalar; QuaternionObject *quat1 = NULL, *quat2 = NULL; if (QuaternionObject_Check(q1)) { quat1 = (QuaternionObject *)q1; if (BaseMath_ReadCallback(quat1) == -1) return NULL; } if (QuaternionObject_Check(q2)) { quat2 = (QuaternionObject *)q2; if (BaseMath_ReadCallback(quat2) == -1) return NULL; } if (quat1 && quat2) { /* QUAT * QUAT (cross product) */ mul_qt_qtqt(quat, quat1->quat, quat2->quat); return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1)); } /* the only case this can happen (for a supported type is "FLOAT * QUAT") */ else if (quat2) { /* FLOAT * QUAT */ if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) { return quat_mul_float(quat2, scalar); } } else if (quat1) { /* QUAT * VEC */ if (VectorObject_Check(q2)) { VectorObject *vec2 = (VectorObject *)q2; float tvec[3]; if (vec2->size != 3) { PyErr_SetString(PyExc_ValueError, "Vector multiplication: " "only 3D vector rotations (with quats) " "currently supported"); return NULL; } if (BaseMath_ReadCallback(vec2) == -1) { return NULL; } copy_v3_v3(tvec, vec2->vec); mul_qt_v3(quat1->quat, tvec); return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec2)); } /* QUAT * FLOAT */ else if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) { return quat_mul_float(quat1, scalar); } } else { BLI_assert(!"internal error"); } PyErr_Format(PyExc_TypeError, "Quaternion multiplication: " "not supported between '%.200s' and '%.200s' types", Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); return NULL; }