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]));
108 PyObject *
const *args,
112 if (
UNLIKELY(kwnames && PyTuple_GET_SIZE(kwnames))) {
113 PyErr_SetString(PyExc_TypeError,
114 "mathutils.Quaternion(): "
115 "takes no keyword args");
123 const size_t nargs = PyVectorcall_NARGS(nargsf);
130 quat, 3,
QUAT_SIZE, args[0],
"mathutils.Quaternion()");
152 angle = PyFloat_AsDouble(args[1]);
154 PyErr_Format(PyExc_TypeError,
155 "mathutils.Quaternion(): "
156 "angle must be a real number, not '%.200s'",
157 Py_TYPE(args[1])->tp_name);
165 PyErr_Format(PyExc_TypeError,
166 "mathutils.Quaternion() "
167 "takes at most 2 arguments (%zd given)",
175static PyObject *
Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
178 if (
UNLIKELY(kwds && PyDict_GET_SIZE(kwds))) {
179 PyErr_SetString(PyExc_TypeError,
180 "mathutils.Quaternion(): "
181 "takes no keyword args");
184 PyObject *
const *args_array = &PyTuple_GET_ITEM(args, 0);
185 const size_t args_array_num = PyTuple_GET_SIZE(args);
187 reinterpret_cast<PyObject *
>(type), args_array, args_array_num,
nullptr);
198 Quaternion_to_euler_doc,
199 ".. method:: to_euler(order='XYZ', euler_compat=None, /)\n"
201 " Return Euler representation of the quaternion.\n"
203 " :arg order: Rotation order.\n"
204 " :type order: Literal['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']\n"
205 " :arg euler_compat: Optional euler argument the new euler will be made\n"
206 " compatible with (no axis flipping between them).\n"
207 " Useful for converting a series of matrices to animation curves.\n"
208 " :type euler_compat: :class:`Euler`\n"
209 " :return: Euler representation of the quaternion.\n"
210 " :rtype: :class:`Euler`\n");
215 const char *order_str =
nullptr;
219 if (!PyArg_ParseTuple(args,
"|sO!:to_euler", &order_str, &
euler_Type, &eul_compat)) {
269 Quaternion_to_matrix_doc,
270 ".. method:: to_matrix()\n"
272 " Return a matrix representation of the quaternion.\n"
274 " :return: A 3x3 rotation matrix representation of the quaternion.\n"
275 " :rtype: :class:`Matrix`\n");
296 Quaternion_to_axis_angle_doc,
297 ".. method:: to_axis_angle()\n"
299 " Return the axis, angle representation of the quaternion.\n"
301 " :return: Axis, angle.\n"
302 " :rtype: tuple[:class:`Vector`, float]\n");
321 ret = PyTuple_New(2);
334 Quaternion_to_swing_twist_doc,
335 ".. method:: to_swing_twist(axis, /)\n"
337 " Split the rotation into a swing quaternion with the specified\n"
338 " axis fixed at zero, and the remaining twist rotation angle.\n"
340 " :arg axis: Twist axis as a string.\n"
341 " :type axis: Literal['X', 'Y', 'Z']\n"
342 " :return: Swing, twist angle.\n"
343 " :rtype: tuple[:class:`Quaternion`, float]\n");
348 const char *axis_str =
nullptr;
349 float swing[4], twist;
352 if (axis_arg && PyUnicode_Check(axis_arg)) {
353 axis_str = PyUnicode_AsUTF8(axis_arg);
356 if (axis_str && axis_str[0] >=
'X' && axis_str[0] <=
'Z' && axis_str[1] == 0) {
357 axis = axis_str[0] -
'X';
360 PyErr_SetString(PyExc_ValueError,
361 "Quaternion.to_swing_twist(): "
362 "the axis argument must be "
363 "a string in 'X', 'Y', 'Z'");
373 ret = PyTuple_New(2);
387 Quaternion_to_exponential_map_doc,
388 ".. method:: to_exponential_map()\n"
390 " Return the exponential map representation of the quaternion.\n"
392 " This representation consist of the rotation axis multiplied by the rotation angle.\n"
393 " Such a representation is useful for interpolation between multiple orientations.\n"
395 " :return: exponential map.\n"
396 " :rtype: :class:`Vector` of size 3\n"
398 " To convert back to a quaternion, pass it to the :class:`Quaternion` constructor.\n");
419 Quaternion_cross_doc,
420 ".. method:: cross(other, /)\n"
422 " Return the cross product of this quaternion and another.\n"
424 " :arg other: The other quaternion to perform the cross product with.\n"
425 " :type other: :class:`Quaternion`\n"
426 " :return: The cross product.\n"
427 " :rtype: :class:`Quaternion`\n");
437 tquat,
QUAT_SIZE,
QUAT_SIZE, value,
"Quaternion.cross(other), invalid 'other' arg") ==
456 ".. method:: dot(other, /)\n"
458 " Return the dot product of this quaternion and another.\n"
460 " :arg other: The other quaternion to perform the dot product with.\n"
461 " :type other: :class:`Quaternion`\n"
462 " :return: The dot product.\n"
473 tquat,
QUAT_SIZE,
QUAT_SIZE, value,
"Quaternion.dot(other), invalid 'other' arg") == -1)
489 Quaternion_rotation_difference_doc,
490 ".. function:: rotation_difference(other, /)\n"
492 " Returns a quaternion representing the rotational difference.\n"
494 " :arg other: second quaternion.\n"
495 " :type other: :class:`Quaternion`\n"
496 " :return: the rotational difference between the two quat rotations.\n"
497 " :rtype: :class:`Quaternion`\n");
510 "Quaternion.rotation_difference(other), invalid 'other' arg") == -1)
528 Quaternion_slerp_doc,
529 ".. function:: slerp(other, factor, /)\n"
531 " Returns the interpolation of two quaternions.\n"
533 " :arg other: value to interpolate with.\n"
534 " :type other: :class:`Quaternion`\n"
535 " :arg factor: The interpolation value in [0.0, 1.0].\n"
536 " :type factor: float\n"
537 " :return: The interpolated rotation.\n"
538 " :rtype: :class:`Quaternion`\n");
544 if (!PyArg_ParseTuple(args,
"Of:slerp", &value, &fac)) {
545 PyErr_SetString(PyExc_TypeError,
547 "expected Quaternion types and float");
556 tquat,
QUAT_SIZE,
QUAT_SIZE, value,
"Quaternion.slerp(other), invalid 'other' arg") ==
562 if (fac > 1.0f || fac < 0.0f) {
563 PyErr_SetString(PyExc_ValueError,
565 "interpolation factor must be between 0.0 and 1.0");
582 Quaternion_rotate_doc,
583 ".. method:: rotate(other, /)\n"
585 " Rotates the quaternion by another mathutils value.\n"
587 " :arg other: rotation component of mathutils value\n"
588 " :type other: :class:`Euler` | :class:`Quaternion` | :class:`Matrix`\n");
591 float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
614 Quaternion_make_compatible_doc,
615 ".. method:: make_compatible(other, /)\n"
617 " Make this quaternion compatible with another,\n"
618 " so interpolating between them works as intended.\n"
620 " :arg other: The other quaternion to make compatible with.\n"
621 " :type other: :class:`Quaternion`\n");
635 "Quaternion.make_compatible(other), invalid 'other' arg") == -1)
661 Quaternion_normalize_doc,
662 ".. function:: normalize()\n"
664 " Normalize the quaternion.\n");
678 Quaternion_normalized_doc,
679 ".. function:: normalized()\n"
681 " Return a new normalized quaternion.\n"
683 " :return: a normalized copy.\n"
684 " :rtype: :class:`Quaternion`\n");
701 Quaternion_invert_doc,
702 ".. function:: invert()\n"
704 " Set the quaternion to its inverse.\n");
718 Quaternion_inverted_doc,
719 ".. function:: inverted()\n"
721 " Return a new, inverted quaternion.\n"
723 " :return: the inverted value.\n"
724 " :rtype: :class:`Quaternion`\n");
738 Quaternion_identity_doc,
739 ".. function:: identity()\n"
741 " Set the quaternion to an identity quaternion.\n");
762 Quaternion_negate_doc,
763 ".. function:: negate()\n"
765 " Set the quaternion to its negative.\n");
786 Quaternion_conjugate_doc,
787 ".. function:: conjugate()\n"
789 " Set the quaternion to its conjugate (negate x, y, z).\n");
803 Quaternion_conjugated_doc,
804 ".. function:: conjugated()\n"
806 " Return a new conjugated quaternion.\n"
808 " :return: a new quaternion.\n"
809 " :rtype: :class:`Quaternion`\n");
824 ".. function:: copy()\n"
826 " Returns a copy of this quaternion.\n"
828 " :return: A copy of the quaternion.\n"
829 " :rtype: :class:`Quaternion`\n"
831 " .. note:: use this to get a copy of a wrapped quaternion with\n"
832 " no reference to the original data.\n");
857 PyObject *
ret, *tuple;
865 ret = PyUnicode_FromFormat(
"Quaternion(%R)", tuple);
871#ifndef MATH_STANDALONE
883 "<Quaternion (w=%.4f, x=%.4f, y=%.4f, z=%.4f)>",
916 if ((flags & PyBUF_WRITABLE) == 0) {
919 if (flags & PyBUF_FORMAT) {
920 view->format = (
char *)
"f";
934 if (
view->readonly == 0) {
974 res = ok ? Py_False : Py_True;
981 res = Py_NotImplemented;
990 return Py_NewRef(res);
1032 PyErr_SetString(PyExc_IndexError,
1033 "quaternion[attribute]: "
1034 "array index out of range");
1042 return PyFloat_FromDouble(
self->quat[
i]);
1054 f =
float(PyFloat_AsDouble(ob));
1056 if (f == -1.0f && PyErr_Occurred()) {
1057 PyErr_SetString(PyExc_TypeError,
1058 "quaternion[index] = x: "
1059 "assigned value not a number");
1068 PyErr_SetString(PyExc_IndexError,
1069 "quaternion[attribute] = x: "
1070 "array assignment index out of range");
1099 tuple = PyTuple_New(end -
begin);
1125 quat, 0,
QUAT_SIZE, seq,
"mathutils.Quaternion[begin:end] = []")) == -1)
1131 PyErr_SetString(PyExc_ValueError,
1132 "quaternion[begin:end] = []: "
1133 "size mismatch in slice assignment");
1149 if (PyIndex_Check(item)) {
1151 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1152 if (
i == -1 && PyErr_Occurred()) {
1160 if (PySlice_Check(item)) {
1161 Py_ssize_t start, stop,
step, slicelength;
1163 if (PySlice_GetIndicesEx(item,
QUAT_SIZE, &start, &stop, &
step, &slicelength) < 0) {
1167 if (slicelength <= 0) {
1168 return PyTuple_New(0);
1174 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with quaternions");
1179 PyExc_TypeError,
"quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1186 if (PyIndex_Check(item)) {
1187 Py_ssize_t
i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1188 if (
i == -1 && PyErr_Occurred()) {
1196 if (PySlice_Check(item)) {
1197 Py_ssize_t start, stop,
step, slicelength;
1199 if (PySlice_GetIndicesEx(item,
QUAT_SIZE, &start, &stop, &
step, &slicelength) < 0) {
1207 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with quaternion");
1212 PyExc_TypeError,
"quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1229 PyErr_Format(PyExc_TypeError,
1230 "Quaternion addition: (%s + %s) "
1231 "invalid type for this operation",
1232 Py_TYPE(q1)->tp_name,
1233 Py_TYPE(q2)->tp_name);
1243 add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f);
1255 PyErr_Format(PyExc_TypeError,
1256 "Quaternion subtraction: (%s - %s) "
1257 "invalid type for this operation",
1258 Py_TYPE(q1)->tp_name,
1259 Py_TYPE(q2)->tp_name);
1271 quat[
x] = quat1->quat[
x] - quat2->quat[
x];
1304 if (quat1 && quat2) {
1311 if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) {
1316 if (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0) {
1321 PyErr_Format(PyExc_TypeError,
1322 "Element-wise multiplication: "
1323 "not supported between '%.200s' and '%.200s' types",
1324 Py_TYPE(q1)->tp_name,
1325 Py_TYPE(q2)->tp_name);
1348 if (quat1 && quat2) {
1351 else if (quat1 && (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
1356 PyErr_Format(PyExc_TypeError,
1357 "Element-wise multiplication: "
1358 "not supported between '%.200s' and '%.200s' types",
1359 Py_TYPE(q1)->tp_name,
1360 Py_TYPE(q2)->tp_name);
1388 if (quat1 && quat2) {
1399 PyErr_SetString(PyExc_ValueError,
1400 "Vector multiplication: "
1401 "only 3D vector rotations (with quats) "
1402 "currently supported");
1416 PyErr_Format(PyExc_TypeError,
1417 "Quaternion multiplication: "
1418 "not supported between '%.200s' and '%.200s' types",
1419 Py_TYPE(q1)->tp_name,
1420 Py_TYPE(q2)->tp_name);
1443 if (quat1 && quat2) {
1448 PyErr_Format(PyExc_TypeError,
1449 "In place quaternion multiplication: "
1450 "not supported between '%.200s' and '%.200s' types",
1451 Py_TYPE(q1)->tp_name,
1452 Py_TYPE(q2)->tp_name);
1546 Quaternion_axis_doc,
1547 "Quaternion axis value.\n"
1562 Quaternion_magnitude_doc,
1563 "Size of the quaternion (read-only).\n"
1577 Quaternion_angle_doc,
1578 "Angle of the quaternion.\n"
1596 return PyFloat_FromDouble(
angle);
1604 float axis[3], angle_dummy;
1614 angle = PyFloat_AsDouble(value);
1616 if (
angle == -1.0f && PyErr_Occurred()) {
1617 PyErr_SetString(PyExc_TypeError,
"Quaternion.angle = value: float expected");
1637 Quaternion_axis_vector_doc,
1638 "Quaternion axis as a vector.\n"
1640 ":type: :class:`Vector`\n");
1701 Quaternion_axis_doc,
1706 Quaternion_axis_doc,
1711 Quaternion_axis_doc,
1716 Quaternion_axis_doc,
1721 Quaternion_magnitude_doc,
1726 Quaternion_angle_doc,
1731 Quaternion_axis_vector_doc,
1753 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
1764# pragma clang diagnostic push
1765# pragma clang diagnostic ignored "-Wcast-function-type"
1767# pragma GCC diagnostic push
1768# pragma GCC diagnostic ignored "-Wcast-function-type"
1793 Quaternion_to_axis_angle_doc},
1797 Quaternion_to_swing_twist_doc},
1798 {
"to_exponential_map",
1801 Quaternion_to_exponential_map_doc},
1805 {
"dot", (PyCFunction)
Quaternion_dot, METH_O, Quaternion_dot_doc},
1806 {
"rotation_difference",
1809 Quaternion_rotation_difference_doc},
1810 {
"slerp", (PyCFunction)
Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc},
1815 Quaternion_make_compatible_doc},
1820 {
"copy", (PyCFunction)
Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
1821 {
"__copy__", (PyCFunction)
Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
1823 {
nullptr,
nullptr, 0,
nullptr},
1828# pragma clang diagnostic pop
1830# pragma GCC diagnostic pop
1840#ifdef MATH_STANDALONE
1841# define Quaternion_str nullptr
1847 ".. class:: Quaternion(seq=(1.0, 0.0, 0.0, 0.0), angle=0.0, /)\n"
1849 " This object gives access to Quaternions in Blender.\n"
1851 " :arg seq: size 3 or 4\n"
1852 " :type seq: :class:`Vector`\n"
1853 " :arg angle: rotation angle, in radians\n"
1854 " :type angle: float\n"
1856 " The constructor takes arguments in various forms:\n"
1859 " Create an identity quaternion\n"
1861 " Create a quaternion from a ``(w, x, y, z)`` vector.\n"
1862 " (*exponential_map*)\n"
1863 " Create a quaternion from a 3d exponential map vector.\n"
1865 " .. seealso:: :meth:`to_exponential_map`\n"
1866 " (*axis, angle*)\n"
1867 " Create a quaternion representing a rotation of *angle* radians over *axis*.\n"
1869 " .. seealso:: :meth:`to_axis_angle`\n");
1871 PyVarObject_HEAD_INIT(
nullptr, 0)
1890 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1922#ifdef MATH_STANDALONE
1923# undef Quaternion_str
1937 quat_alloc =
static_cast<float *
>(PyMem_Malloc(
QUAT_SIZE *
sizeof(
float)));
1938 if (
UNLIKELY(quat_alloc ==
nullptr)) {
1939 PyErr_SetString(PyExc_MemoryError,
1941 "problem allocating data");
1947 self->quat = quat_alloc;
1949 self->cb_user =
nullptr;
1950 self->cb_type =
self->cb_subtype = 0;
1962 PyMem_Free(quat_alloc);
1965 return (PyObject *)
self;
1975 self->cb_user =
nullptr;
1976 self->cb_type =
self->cb_subtype = 0;
1982 return (PyObject *)
self;
1990 self->cb_user = cb_user;
1991 self->cb_type = cb_type;
1992 self->cb_subtype = cb_subtype;
1994 PyObject_GC_Track(
self);
1997 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)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float length(VecOp< float, D >) RET
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_Prepare_ForBufferAccess(_self, _view, _flags)
#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)
@ BASE_MATH_FLAG_HAS_BUFFER_VIEW
#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 void Quaternion_releasebuffer(PyObject *, Py_buffer *view)
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)
static int Quaternion_getbuffer(PyObject *obj, Py_buffer *view, int flags)
static PyObject * Quaternion_magnitude_get(QuaternionObject *self, void *)
static PyObject * Quaternion_conjugated(QuaternionObject *self)
static PyBufferProcs Quaternion_as_buffer
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_vectorcall(PyObject *type, PyObject *const *args, const size_t nargsf, PyObject *kwnames)
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)
PyDoc_STRVAR(Quaternion_to_euler_doc, ".. method:: to_euler(order='XYZ', euler_compat=None, /)\n" "\n" " Return Euler representation of the quaternion.\n" "\n" " :arg order: Rotation order.\n" " :type order: Literal['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']\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")
#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,...)