24#ifndef MATH_STANDALONE
58 if (
is_zero_v3(axis) || !isfinite(axis[0]) || !isfinite(axis[1]) || !isfinite(axis[2])) {
71 if (!isfinite(*angle)) {
94 PyTuple_SET_ITEM(
ret, i, PyFloat_FromDouble(
self->quat[i]));
107static PyObject *
Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
109 PyObject *seq =
nullptr;
114 if (kwds && PyDict_Size(kwds)) {
115 PyErr_SetString(PyExc_TypeError,
116 "mathutils.Quaternion(): "
117 "takes no keyword args");
121 if (!PyArg_ParseTuple(args,
"|Od:mathutils.Quaternion", &seq, &angle)) {
125 switch (PyTuple_GET_SIZE(args)) {
169 Quaternion_to_euler_doc,
170 ".. method:: to_euler(order, euler_compat)\n"
172 " Return Euler representation of the quaternion.\n"
174 " :arg order: Optional rotation order argument in\n"
175 " ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
176 " :type order: str\n"
177 " :arg euler_compat: Optional euler argument the new euler will be made\n"
178 " compatible with (no axis flipping between them).\n"
179 " Useful for converting a series of matrices to animation curves.\n"
180 " :type euler_compat: :class:`Euler`\n"
181 " :return: Euler representation of the quaternion.\n"
182 " :rtype: :class:`Euler`\n");
187 const char *order_str =
nullptr;
191 if (!PyArg_ParseTuple(args,
"|sO!:to_euler", &order_str, &
euler_Type, &eul_compat)) {
241 Quaternion_to_matrix_doc,
242 ".. method:: to_matrix()\n"
244 " Return a matrix representation of the quaternion.\n"
246 " :return: A 3x3 rotation matrix representation of the quaternion.\n"
247 " :rtype: :class:`Matrix`\n");
268 Quaternion_to_axis_angle_doc,
269 ".. method:: to_axis_angle()\n"
271 " Return the axis, angle representation of the quaternion.\n"
273 " :return: Axis, angle.\n"
274 " :rtype: tuple[:class:`Vector`, float]\n");
293 ret = PyTuple_New(2);
306 Quaternion_to_swing_twist_doc,
307 ".. method:: to_swing_twist(axis)\n"
309 " Split the rotation into a swing quaternion with the specified\n"
310 " axis fixed at zero, and the remaining twist rotation angle.\n"
312 " :arg axis: Twist axis as a string in ['X', 'Y', 'Z'].\n"
314 " :return: Swing, twist angle.\n"
315 " :rtype: tuple[:class:`Quaternion`, float]\n");
320 const char *axis_str =
nullptr;
321 float swing[4], twist;
324 if (axis_arg && PyUnicode_Check(axis_arg)) {
325 axis_str = PyUnicode_AsUTF8(axis_arg);
328 if (axis_str && axis_str[0] >=
'X' && axis_str[0] <=
'Z' && axis_str[1] == 0) {
329 axis = axis_str[0] -
'X';
332 PyErr_SetString(PyExc_ValueError,
333 "Quaternion.to_swing_twist(): "
334 "the axis argument must be "
335 "a string in 'X', 'Y', 'Z'");
345 ret = PyTuple_New(2);
359 Quaternion_to_exponential_map_doc,
360 ".. method:: to_exponential_map()\n"
362 " Return the exponential map representation of the quaternion.\n"
364 " This representation consist of the rotation axis multiplied by the rotation angle.\n"
365 " Such a representation is useful for interpolation between multiple orientations.\n"
367 " :return: exponential map.\n"
368 " :rtype: :class:`Vector` of size 3\n"
370 " To convert back to a quaternion, pass it to the :class:`Quaternion` constructor.\n");
391 Quaternion_cross_doc,
392 ".. method:: cross(other)\n"
394 " Return the cross product of this quaternion and another.\n"
396 " :arg other: The other quaternion to perform the cross product with.\n"
397 " :type other: :class:`Quaternion`\n"
398 " :return: The cross product.\n"
399 " :rtype: :class:`Quaternion`\n");
409 tquat,
QUAT_SIZE,
QUAT_SIZE, value,
"Quaternion.cross(other), invalid 'other' arg") ==
428 ".. method:: dot(other)\n"
430 " Return the dot product of this quaternion and another.\n"
432 " :arg other: The other quaternion to perform the dot product with.\n"
433 " :type other: :class:`Quaternion`\n"
434 " :return: The dot product.\n"
445 tquat,
QUAT_SIZE,
QUAT_SIZE, value,
"Quaternion.dot(other), invalid 'other' arg") == -1)
461 Quaternion_rotation_difference_doc,
462 ".. function:: rotation_difference(other)\n"
464 " Returns a quaternion representing the rotational difference.\n"
466 " :arg other: second quaternion.\n"
467 " :type other: :class:`Quaternion`\n"
468 " :return: the rotational difference between the two quat rotations.\n"
469 " :rtype: :class:`Quaternion`\n");
482 "Quaternion.rotation_difference(other), invalid 'other' arg") == -1)
500 Quaternion_slerp_doc,
501 ".. function:: slerp(other, factor)\n"
503 " Returns the interpolation of two quaternions.\n"
505 " :arg other: value to interpolate with.\n"
506 " :type other: :class:`Quaternion`\n"
507 " :arg factor: The interpolation value in [0.0, 1.0].\n"
508 " :type factor: float\n"
509 " :return: The interpolated rotation.\n"
510 " :rtype: :class:`Quaternion`\n");
516 if (!PyArg_ParseTuple(args,
"Of:slerp", &value, &fac)) {
517 PyErr_SetString(PyExc_TypeError,
519 "expected Quaternion types and float");
528 tquat,
QUAT_SIZE,
QUAT_SIZE, value,
"Quaternion.slerp(other), invalid 'other' arg") ==
534 if (fac > 1.0f || fac < 0.0f) {
535 PyErr_SetString(PyExc_ValueError,
537 "interpolation factor must be between 0.0 and 1.0");
554 Quaternion_rotate_doc,
555 ".. method:: rotate(other)\n"
557 " Rotates the quaternion by another mathutils value.\n"
559 " :arg other: rotation component of mathutils value\n"
560 " :type other: :class:`Euler` | :class:`Quaternion` | :class:`Matrix`\n");
563 float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
586 Quaternion_make_compatible_doc,
587 ".. method:: make_compatible(other)\n"
589 " Make this quaternion compatible with another,\n"
590 " so interpolating between them works as intended.\n");
604 "Quaternion.make_compatible(other), invalid 'other' arg") == -1)
630 Quaternion_normalize_doc,
631 ".. function:: normalize()\n"
633 " Normalize the quaternion.\n");
647 Quaternion_normalized_doc,
648 ".. function:: normalized()\n"
650 " Return a new normalized quaternion.\n"
652 " :return: a normalized copy.\n"
653 " :rtype: :class:`Quaternion`\n");
670 Quaternion_invert_doc,
671 ".. function:: invert()\n"
673 " Set the quaternion to its inverse.\n");
687 Quaternion_inverted_doc,
688 ".. function:: inverted()\n"
690 " Return a new, inverted quaternion.\n"
692 " :return: the inverted value.\n"
693 " :rtype: :class:`Quaternion`\n");
707 Quaternion_identity_doc,
708 ".. function:: identity()\n"
710 " Set the quaternion to an identity quaternion.\n");
731 Quaternion_negate_doc,
732 ".. function:: negate()\n"
734 " Set the quaternion to its negative.\n");
755 Quaternion_conjugate_doc,
756 ".. function:: conjugate()\n"
758 " Set the quaternion to its conjugate (negate x, y, z).\n");
772 Quaternion_conjugated_doc,
773 ".. function:: conjugated()\n"
775 " Return a new conjugated quaternion.\n"
777 " :return: a new quaternion.\n"
778 " :rtype: :class:`Quaternion`\n");
793 ".. function:: copy()\n"
795 " Returns a copy of this quaternion.\n"
797 " :return: A copy of the quaternion.\n"
798 " :rtype: :class:`Quaternion`\n"
800 " .. note:: use this to get a copy of a wrapped quaternion with\n"
801 " no reference to the original data.\n");
826 PyObject *
ret, *tuple;
834 ret = PyUnicode_FromFormat(
"Quaternion(%R)", tuple);
840#ifndef MATH_STANDALONE
852 "<Quaternion (w=%.4f, x=%.4f, y=%.4f, z=%.4f)>",
889 res = ok ? Py_False : Py_True;
896 res = Py_NotImplemented;
903 return Py_NewRef(res);
945 PyErr_SetString(PyExc_IndexError,
946 "quaternion[attribute]: "
947 "array index out of range");
955 return PyFloat_FromDouble(
self->quat[i]);
967 f =
float(PyFloat_AsDouble(ob));
969 if (f == -1.0f && PyErr_Occurred()) {
970 PyErr_SetString(PyExc_TypeError,
971 "quaternion[index] = x: "
972 "assigned value not a number");
981 PyErr_SetString(PyExc_IndexError,
982 "quaternion[attribute] = x: "
983 "array assignment index out of range");
1010 begin = std::min(begin, end);
1012 tuple = PyTuple_New(end - begin);
1014 PyTuple_SET_ITEM(tuple,
count - begin, PyFloat_FromDouble(
self->quat[
count]));
1035 begin = std::min(begin, end);
1038 quat, 0,
QUAT_SIZE, seq,
"mathutils.Quaternion[begin:end] = []")) == -1)
1043 if (size != (end - begin)) {
1044 PyErr_SetString(PyExc_ValueError,
1045 "quaternion[begin:end] = []: "
1046 "size mismatch in slice assignment");
1051 for (i = 0; i <
size; i++) {
1052 self->quat[begin + i] = quat[i];
1062 if (PyIndex_Check(item)) {
1064 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1065 if (i == -1 && PyErr_Occurred()) {
1073 if (PySlice_Check(item)) {
1074 Py_ssize_t start, stop, step, slicelength;
1076 if (PySlice_GetIndicesEx(item,
QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
1080 if (slicelength <= 0) {
1081 return PyTuple_New(0);
1087 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with quaternions");
1092 PyExc_TypeError,
"quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1099 if (PyIndex_Check(item)) {
1100 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1101 if (i == -1 && PyErr_Occurred()) {
1109 if (PySlice_Check(item)) {
1110 Py_ssize_t start, stop, step, slicelength;
1112 if (PySlice_GetIndicesEx(item,
QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
1120 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with quaternion");
1125 PyExc_TypeError,
"quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1142 PyErr_Format(PyExc_TypeError,
1143 "Quaternion addition: (%s + %s) "
1144 "invalid type for this operation",
1145 Py_TYPE(
q1)->tp_name,
1146 Py_TYPE(q2)->tp_name);
1156 add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f);
1168 PyErr_Format(PyExc_TypeError,
1169 "Quaternion subtraction: (%s - %s) "
1170 "invalid type for this operation",
1171 Py_TYPE(
q1)->tp_name,
1172 Py_TYPE(q2)->tp_name);
1184 quat[
x] = quat1->quat[
x] - quat2->quat[
x];
1217 if (quat1 && quat2) {
1224 if (((scalar = PyFloat_AsDouble(
q1)) == -1.0f && PyErr_Occurred()) == 0) {
1229 if (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0) {
1234 PyErr_Format(PyExc_TypeError,
1235 "Element-wise multiplication: "
1236 "not supported between '%.200s' and '%.200s' types",
1237 Py_TYPE(
q1)->tp_name,
1238 Py_TYPE(q2)->tp_name);
1261 if (quat1 && quat2) {
1264 else if (quat1 && (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
1269 PyErr_Format(PyExc_TypeError,
1270 "Element-wise multiplication: "
1271 "not supported between '%.200s' and '%.200s' types",
1272 Py_TYPE(
q1)->tp_name,
1273 Py_TYPE(q2)->tp_name);
1301 if (quat1 && quat2) {
1312 PyErr_SetString(PyExc_ValueError,
1313 "Vector multiplication: "
1314 "only 3D vector rotations (with quats) "
1315 "currently supported");
1329 PyErr_Format(PyExc_TypeError,
1330 "Quaternion multiplication: "
1331 "not supported between '%.200s' and '%.200s' types",
1332 Py_TYPE(
q1)->tp_name,
1333 Py_TYPE(q2)->tp_name);
1356 if (quat1 && quat2) {
1361 PyErr_Format(PyExc_TypeError,
1362 "In place quaternion multiplication: "
1363 "not supported between '%.200s' and '%.200s' types",
1364 Py_TYPE(
q1)->tp_name,
1365 Py_TYPE(q2)->tp_name);
1459 Quaternion_axis_doc,
1460 "Quaternion axis value.\n"
1475 Quaternion_magnitude_doc,
1476 "Size of the quaternion (read-only).\n"
1490 Quaternion_angle_doc,
1491 "Angle of the quaternion.\n"
1509 return PyFloat_FromDouble(angle);
1517 float axis[3], angle_dummy;
1527 angle = PyFloat_AsDouble(value);
1529 if (angle == -1.0f && PyErr_Occurred()) {
1530 PyErr_SetString(PyExc_TypeError,
"Quaternion.angle = value: float expected");
1550 Quaternion_axis_vector_doc,
1551 "Quaternion axis as a vector.\n"
1553 ":type: :class:`Vector`");
1614 Quaternion_axis_doc,
1619 Quaternion_axis_doc,
1624 Quaternion_axis_doc,
1629 Quaternion_axis_doc,
1634 Quaternion_magnitude_doc,
1639 Quaternion_angle_doc,
1644 Quaternion_axis_vector_doc,
1666 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
1675#if (defined(__GNUC__) && !defined(__clang__))
1676# pragma GCC diagnostic push
1677# pragma GCC diagnostic ignored "-Wcast-function-type"
1701 Quaternion_to_axis_angle_doc},
1705 Quaternion_to_swing_twist_doc},
1706 {
"to_exponential_map",
1709 Quaternion_to_exponential_map_doc},
1713 {
"dot", (PyCFunction)
Quaternion_dot, METH_O, Quaternion_dot_doc},
1714 {
"rotation_difference",
1717 Quaternion_rotation_difference_doc},
1718 {
"slerp", (PyCFunction)
Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc},
1723 Quaternion_make_compatible_doc},
1728 {
"copy", (PyCFunction)
Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
1729 {
"__copy__", (PyCFunction)
Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
1731 {
nullptr,
nullptr, 0,
nullptr},
1734#if (defined(__GNUC__) && !defined(__clang__))
1735# pragma GCC diagnostic pop
1744#ifdef MATH_STANDALONE
1745# define Quaternion_str nullptr
1751 ".. class:: Quaternion([seq, [angle]])\n"
1753 " This object gives access to Quaternions in Blender.\n"
1755 " :arg seq: size 3 or 4\n"
1756 " :type seq: :class:`Vector`\n"
1757 " :arg angle: rotation angle, in radians\n"
1758 " :type angle: float\n"
1760 " The constructor takes arguments in various forms:\n"
1763 " Create an identity quaternion\n"
1765 " Create a quaternion from a ``(w, x, y, z)`` vector.\n"
1766 " (*exponential_map*)\n"
1767 " Create a quaternion from a 3d exponential map vector.\n"
1769 " .. seealso:: :meth:`to_exponential_map`\n"
1770 " (*axis, angle*)\n"
1771 " Create a quaternion representing a rotation of *angle* radians over *axis*.\n"
1773 " .. seealso:: :meth:`to_axis_angle`\n");
1775 PyVarObject_HEAD_INIT(
nullptr, 0)
1794 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1826#ifdef MATH_STANDALONE
1827# undef Quaternion_str
1841 quat_alloc =
static_cast<float *
>(PyMem_Malloc(
QUAT_SIZE *
sizeof(
float)));
1842 if (
UNLIKELY(quat_alloc ==
nullptr)) {
1843 PyErr_SetString(PyExc_MemoryError,
1845 "problem allocating data");
1851 self->quat = quat_alloc;
1853 self->cb_user =
nullptr;
1854 self->cb_type =
self->cb_subtype = 0;
1866 PyMem_Free(quat_alloc);
1869 return (PyObject *)
self;
1879 self->cb_user =
nullptr;
1880 self->cb_type =
self->cb_subtype = 0;
1886 return (PyObject *)
self;
1894 self->cb_user = cb_user;
1895 self->cb_type = cb_type;
1896 self->cb_subtype = cb_subtype;
1898 PyObject_GC_Track(
self);
1901 return (PyObject *)
self;
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
double double_round(double x, int ndigits)
MINLINE float safe_acosf(float a)
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void quat_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float quat[4])
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4])
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void quat_to_mat3(float m[3][3], const float q[4])
void mat3_to_quat(float q[4], const float mat[3][3])
void quat_to_eulO(float e[3], short order, const float q[4])
float normalize_qt(float q[4])
void invert_qt(float q[4])
void mul_qt_fl(float q[4], float f)
void mul_qt_v3(const float q[4], float r[3])
void quat_to_eul(float eul[3], const float quat[4])
float normalize_qt_qt(float r[4], const float q[4])
float dot_qtqt(const float a[4], const float b[4])
float quat_split_swing_and_twist(const float q_in[4], int axis, float r_swing[4], float r_twist[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
void quat_to_expmap(float expmap[3], const float q[4])
void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void conjugate_qt(float q[4])
void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4])
void copy_qt_qt(float q[4], const float a[4])
float angle_wrap_rad(float angle)
void quat_to_compatible_quat(float q[4], const float a[4], const float old[4])
void expmap_to_quat(float r[4], const float expmap[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v4_v4(float r[4], const float a[4])
void mul_vn_vn(float *array_tar, const float *array_src, int size)
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
int BaseMathObject_is_gc(BaseMathObject *self)
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
void BaseMathObject_dealloc(BaseMathObject *self)
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
char BaseMathObject_is_valid_doc[]
char BaseMathObject_is_wrapped_doc[]
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *)
char BaseMathObject_is_frozen_doc[]
PyObject * mathutils_dynstr_to_py(DynStr *ds)
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *)
PyObject * BaseMathObject_freeze(BaseMathObject *self)
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *)
char BaseMathObject_owner_doc[]
char BaseMathObject_freeze_doc[]
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *)
int BaseMathObject_clear(BaseMathObject *self)
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
#define BaseMath_ReadCallback_ForWrite(_self)
#define BaseMath_ReadIndexCallback(_self, _index)
#define BaseMath_WriteCallback(_self)
#define BASE_MATH_NEW(struct_name, root_type, base_type)
#define BaseMathObject_Prepare_ForHash(_self)
#define BASE_MATH_FLAG_DEFAULT
#define BaseMath_Prepare_ForWrite(_self)
#define BaseMath_ReadCallback(_self)
#define BaseMath_WriteIndexCallback(_self, _index)
short euler_order_from_string(const char *str, const char *error_prefix)
PyObject * Euler_CreatePyObject(const float eul[3], const short order, PyTypeObject *base_type)
PyObject * Matrix_CreatePyObject(const float *mat, const ushort col_num, const ushort row_num, PyTypeObject *base_type)
static PyObject * Quaternion_add(PyObject *q1, PyObject *q2)
static PyObject * Quaternion_slice(QuaternionObject *self, int begin, int end)
static PyObject * Quaternion_angle_get(QuaternionObject *self, void *)
static PyObject * Quaternion_conjugate(QuaternionObject *self)
static PyObject * quat_mul_float(QuaternionObject *quat, const float scalar)
static PyObject * Quaternion_imatmul(PyObject *q1, PyObject *q2)
static PyObject * Quaternion_to_tuple_ext(QuaternionObject *self, int ndigits)
static PyObject * Quaternion_str(QuaternionObject *self)
static PyObject * Quaternion_rotate(QuaternionObject *self, PyObject *value)
static PyObject * Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
static PyObject * Quaternion_to_matrix(QuaternionObject *self)
static PySequenceMethods Quaternion_SeqMethods
static int Quaternion_axis_vector_set(QuaternionObject *self, PyObject *value, void *)
static PyObject * Quaternion_rotation_difference(QuaternionObject *self, PyObject *value)
static PyMethodDef Quaternion_methods[]
static PyMappingMethods Quaternion_AsMapping
static PyObject * Quaternion_axis_vector_get(QuaternionObject *self, void *)
static PyGetSetDef Quaternion_getseters[]
static PyObject * Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject * Quaternion_axis_get(QuaternionObject *self, void *type)
static PyObject * Quaternion_to_exponential_map(QuaternionObject *self)
static int Quaternion_ass_item(QuaternionObject *self, Py_ssize_t i, PyObject *ob)
static PyObject * Quaternion_matmul(PyObject *q1, PyObject *q2)
static PyObject * Quaternion_make_compatible(QuaternionObject *self, PyObject *value)
static PyObject * Quaternion_to_euler(QuaternionObject *self, PyObject *args)
static PyObject * Quaternion_sub(PyObject *q1, PyObject *q2)
PyDoc_STRVAR(Quaternion_to_euler_doc, ".. method:: to_euler(order, euler_compat)\n" "\n" " Return Euler representation of the quaternion.\n" "\n" " :arg order: Optional rotation order argument in\n" " ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n" " :type order: str\n" " :arg euler_compat: Optional euler argument the new euler will be made\n" " compatible with (no axis flipping between them).\n" " Useful for converting a series of matrices to animation curves.\n" " :type euler_compat: :class:`Euler`\n" " :return: Euler representation of the quaternion.\n" " :rtype: :class:`Euler`\n")
static PyObject * Quaternion_magnitude_get(QuaternionObject *self, void *)
static PyObject * Quaternion_conjugated(QuaternionObject *self)
static void quat__axis_angle_sanitize(float axis[3], float *angle)
static PyObject * Quaternion_neg(QuaternionObject *self)
static PyObject * Quaternion_cross(QuaternionObject *self, PyObject *value)
static PyObject * Quaternion_negate(QuaternionObject *self)
static PyObject * Quaternion_subscript(QuaternionObject *self, PyObject *item)
static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyObject *value)
static PyObject * Quaternion_inverted(QuaternionObject *self)
static PyObject * Quaternion_deepcopy(QuaternionObject *self, PyObject *args)
static int Quaternion_ass_slice(QuaternionObject *self, int begin, int end, PyObject *seq)
static PyObject * Quaternion_normalized(QuaternionObject *self)
static PyObject * Quaternion_mul(PyObject *q1, PyObject *q2)
static PyNumberMethods Quaternion_NumMethods
PyObject * Quaternion_CreatePyObject_wrap(float quat[4], PyTypeObject *base_type)
static PyObject * Quaternion_to_axis_angle(QuaternionObject *self)
static int Quaternion_angle_set(QuaternionObject *self, PyObject *value, void *)
PyObject * Quaternion_CreatePyObject_cb(PyObject *cb_user, uchar cb_type, uchar cb_subtype)
PyTypeObject quaternion_Type
static PyObject * Quaternion_repr(QuaternionObject *self)
static int Quaternion_axis_set(QuaternionObject *self, PyObject *value, void *type)
static PyObject * quat__apply_to_copy(PyObject *(*quat_func)(QuaternionObject *), QuaternionObject *self)
static PyObject * Quaternion_slerp(QuaternionObject *self, PyObject *args)
static PyObject * Quaternion_normalize(QuaternionObject *self)
static PyObject * Quaternion_identity(QuaternionObject *self)
static PyObject * Quaternion_to_swing_twist(QuaternionObject *self, PyObject *axis_arg)
static PyObject * Quaternion_invert(QuaternionObject *self)
static Py_hash_t Quaternion_hash(QuaternionObject *self)
PyObject * Quaternion_CreatePyObject(const float quat[4], PyTypeObject *base_type)
static PyObject * Quaternion_dot(QuaternionObject *self, PyObject *value)
static PyObject * Quaternion_copy(QuaternionObject *self)
static PyObject * Quaternion_item(QuaternionObject *self, Py_ssize_t i)
static Py_ssize_t Quaternion_len(QuaternionObject *)
static PyObject * Quaternion_imul(PyObject *q1, PyObject *q2)
#define QuaternionObject_Check(v)
PyObject * Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type)
#define VectorObject_Check(v)
int PyC_CheckArgs_DeepCopy(PyObject *args)
#define PyTuple_SET_ITEMS(op_arg,...)