2023-05-31 16:19:06 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2012-02-17 19:59:41 +01:00
|
|
|
#pragma once
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2019-02-17 22:08:12 +01:00
|
|
|
/** \file
|
|
|
|
* \ingroup bli
|
2011-02-18 14:58:08 +01:00
|
|
|
*/
|
|
|
|
|
2022-05-11 15:28:48 +02:00
|
|
|
#include "BLI_math_base.h"
|
2020-03-06 16:45:06 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2019-04-18 22:17:04 +02:00
|
|
|
#include "DNA_vec_types.h"
|
|
|
|
|
2009-11-09 23:42:41 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2021-12-14 05:49:31 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Conversion Defines
|
|
|
|
* \{ */
|
|
|
|
|
2012-05-12 22:39:39 +02:00
|
|
|
#define RAD2DEG(_rad) ((_rad) * (180.0 / M_PI))
|
|
|
|
#define DEG2RAD(_deg) ((_deg) * (M_PI / 180.0))
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2012-05-12 22:39:39 +02:00
|
|
|
#define RAD2DEGF(_rad) ((_rad) * (float)(180.0 / M_PI))
|
|
|
|
#define DEG2RADF(_deg) ((_deg) * (float)(M_PI / 180.0))
|
2011-03-27 16:52:16 +02:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Quaternions
|
|
|
|
* Stored in (w, x, y, z) order.
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
/* Initialize */
|
|
|
|
|
|
|
|
/* Convenience, avoids setting Y axis everywhere. */
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2011-02-02 01:40:55 +01:00
|
|
|
void unit_axis_angle(float axis[3], float *angle);
|
2009-11-09 23:42:41 +01:00
|
|
|
void unit_qt(float q[4]);
|
2010-07-26 02:11:14 +02:00
|
|
|
void copy_qt_qt(float q[4], const float a[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-20 09:01:14 +01:00
|
|
|
/* Arithmetic. */
|
|
|
|
|
2010-07-26 02:11:14 +02:00
|
|
|
void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* \note
|
|
|
|
* Assumes a unit quaternion?
|
|
|
|
*
|
|
|
|
* in fact not, but you may want to use a unit quaternion read on...
|
|
|
|
*
|
|
|
|
* Shortcut for 'q v q*' when \a v is actually a quaternion.
|
|
|
|
* This removes the need for converting a vector to a quaternion,
|
|
|
|
* calculating q's conjugate and converting back to a vector.
|
|
|
|
* It also happens to be faster (17+,24* vs * 24+,32*).
|
|
|
|
* If \a q is not a unit quaternion, then \a v will be both rotated by
|
|
|
|
* the same amount as if q was a unit quaternion, and scaled by the square of
|
|
|
|
* the length of q.
|
|
|
|
*
|
|
|
|
* For people used to python mathutils, its like:
|
|
|
|
* def mul_qt_v3(q, v): (q * Quaternion((0.0, v[0], v[1], v[2])) * q.conjugated())[1:]
|
|
|
|
*
|
|
|
|
* \note Multiplying by 3x3 matrix is ~25% faster.
|
|
|
|
*/
|
2010-08-02 02:08:01 +02:00
|
|
|
void mul_qt_v3(const float q[4], float r[3]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Simple multiply.
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void mul_qt_fl(float q[4], float f);
|
2018-12-23 13:25:40 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Raise a unit quaternion to the specified power.
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void pow_qt_fl_normalized(float q[4], float fac);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2010-10-22 05:56:50 +02:00
|
|
|
void sub_qt_qtqt(float q[4], const float a[4], const float b[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
|
|
|
void invert_qt(float q[4]);
|
2010-12-07 02:56:32 +01:00
|
|
|
void invert_qt_qt(float q1[4], const float q2[4]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* This is just conjugate_qt for cases we know \a q is unit-length.
|
|
|
|
* we could use #conjugate_qt directly, but use this function to show intent,
|
|
|
|
* and assert if its ever becomes non-unit-length.
|
|
|
|
*/
|
2015-10-23 18:51:00 +02:00
|
|
|
void invert_qt_normalized(float q[4]);
|
|
|
|
void invert_qt_qt_normalized(float q1[4], const float q2[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
void conjugate_qt(float q[4]);
|
2012-08-25 19:42:15 +02:00
|
|
|
void conjugate_qt_qt(float q1[4], const float q2[4]);
|
2010-10-22 05:56:50 +02:00
|
|
|
float dot_qtqt(const float a[4], const float b[4]);
|
2010-12-07 02:56:32 +01:00
|
|
|
float normalize_qt(float q[4]);
|
2020-09-04 20:59:13 +02:00
|
|
|
float normalize_qt_qt(float r[4], const float q[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-20 09:01:14 +01:00
|
|
|
/* Comparison. */
|
|
|
|
|
2013-08-23 11:46:11 +02:00
|
|
|
bool is_zero_qt(const float q[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
|
|
|
/* interpolation */
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Generic function for implementing slerp
|
|
|
|
* (quaternions and spherical vector coords).
|
|
|
|
*
|
|
|
|
* \param t: factor in [0..1]
|
|
|
|
* \param cosom: dot product from normalized vectors/quats.
|
|
|
|
* \param r_w: calculated weights.
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void interp_dot_slerp(float t, float cosom, float r_w[2]);
|
|
|
|
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
|
|
|
|
void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-20 09:01:14 +01:00
|
|
|
/* Conversion. */
|
|
|
|
|
2022-08-21 07:06:28 +02:00
|
|
|
void quat_to_mat3(float m[3][3], const float q[4]);
|
|
|
|
void quat_to_mat4(float m[4][4], const float q[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Apply the rotation of \a a to \a q keeping the values compatible with \a old.
|
|
|
|
* Avoid axis flipping for animated f-curves for eg.
|
|
|
|
*/
|
2019-03-19 06:50:18 +01:00
|
|
|
void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]);
|
|
|
|
|
2022-08-25 04:45:43 +02:00
|
|
|
/**
|
|
|
|
* A version of #mat3_normalized_to_quat that skips error checking.
|
|
|
|
*/
|
|
|
|
void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]);
|
|
|
|
|
2019-02-25 13:14:48 +01:00
|
|
|
void mat3_normalized_to_quat(float q[4], const float mat[3][3]);
|
|
|
|
void mat4_normalized_to_quat(float q[4], const float mat[4][4]);
|
|
|
|
void mat3_to_quat(float q[4], const float mat[3][3]);
|
|
|
|
void mat4_to_quat(float q[4], const float mat[4][4]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Same as tri_to_quat() but takes pre-computed normal from the triangle
|
|
|
|
* used for ngons when we know their normal.
|
|
|
|
*/
|
2012-09-25 02:20:42 +02:00
|
|
|
void tri_to_quat_ex(float quat[4],
|
|
|
|
const float v1[3],
|
|
|
|
const float v2[3],
|
|
|
|
const float v3[3],
|
|
|
|
const float no_orig[3]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* \return the length of the normal, use to test for degenerate triangles.
|
|
|
|
*/
|
2014-02-27 02:28:40 +01:00
|
|
|
float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]);
|
2022-01-07 01:38:08 +01:00
|
|
|
void vec_to_quat(float q[4], const float vec[3], short axis, short upflag);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Calculate a rotation matrix from 2 normalized vectors.
|
|
|
|
* \note `v1` and `v2` must be normalized.
|
|
|
|
*/
|
2014-04-19 07:36:47 +02:00
|
|
|
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* \note Expects vectors to be normalized.
|
|
|
|
*/
|
2009-12-27 02:32:58 +01:00
|
|
|
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
|
2010-07-26 02:11:14 +02:00
|
|
|
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Decompose a quaternion into a swing rotation (quaternion with the selected
|
|
|
|
* axis component locked at zero), followed by a twist rotation around the axis.
|
|
|
|
*
|
|
|
|
* \param q: input quaternion.
|
|
|
|
* \param axis: twist axis in [0,1,2]
|
|
|
|
* \param r_swing: if not NULL, receives the swing quaternion.
|
|
|
|
* \param r_twist: if not NULL, receives the twist quaternion.
|
|
|
|
* \returns twist angle.
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
float quat_split_swing_and_twist(const float q_in[4],
|
|
|
|
int axis,
|
|
|
|
float r_swing[4],
|
|
|
|
float r_twist[4]);
|
2019-09-01 16:21:22 +02:00
|
|
|
|
2014-03-20 04:39:32 +01:00
|
|
|
float angle_normalized_qt(const float q[4]);
|
|
|
|
float angle_normalized_qtqt(const float q1[4], const float q2[4]);
|
|
|
|
float angle_qt(const float q[4]);
|
|
|
|
float angle_qtqt(const float q1[4], const float q2[4]);
|
|
|
|
|
2017-12-19 03:59:18 +01:00
|
|
|
float angle_signed_normalized_qt(const float q[4]);
|
|
|
|
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]);
|
|
|
|
float angle_signed_qt(const float q[4]);
|
|
|
|
float angle_signed_qtqt(const float q1[4], const float q2[4]);
|
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
2022-08-25 06:27:44 +02:00
|
|
|
* Legacy matrix to quaternion conversion, keep to prevent changes to existing
|
|
|
|
* boids & particle-system behavior. Use #mat3_to_quat for new code.
|
2021-12-09 10:01:44 +01:00
|
|
|
*/
|
2022-08-25 06:27:44 +02:00
|
|
|
void mat3_to_quat_legacy(float q[4], const float wmat[3][3]);
|
2009-11-10 21:40:18 +01:00
|
|
|
|
2021-12-20 09:01:14 +01:00
|
|
|
/* Other. */
|
|
|
|
|
2022-07-22 05:57:04 +02:00
|
|
|
/**
|
2022-07-27 11:48:17 +02:00
|
|
|
* Utility that performs `sinf` & `cosf` intended for plotting a 2D circle,
|
|
|
|
* where the values of the coordinates with are exactly symmetrical although this
|
|
|
|
* favors even numbers as odd numbers can only be symmetrical on a single axis.
|
2022-07-22 05:57:04 +02:00
|
|
|
*
|
|
|
|
* Besides adjustments to precision, this function is the equivalent of:
|
|
|
|
* \code {.c}
|
|
|
|
* float phi = (2 * M_PI) * (float)i / (float)denominator;
|
|
|
|
* *r_sin = sinf(phi);
|
|
|
|
* *r_cos = cosf(phi);
|
|
|
|
* \endcode
|
|
|
|
*
|
|
|
|
* \param numerator: An integer factor in [0..denominator] (inclusive).
|
2022-08-03 19:27:23 +02:00
|
|
|
* \param denominator: The fraction denominator (typically the number of segments of the circle).
|
2022-07-22 05:57:04 +02:00
|
|
|
* \param r_sin: The resulting sine.
|
|
|
|
* \param r_cos: The resulting cosine.
|
|
|
|
*/
|
2022-07-27 11:48:17 +02:00
|
|
|
void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos);
|
2022-07-22 05:57:04 +02:00
|
|
|
|
2011-03-08 08:31:42 +01:00
|
|
|
void print_qt(const char *str, const float q[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2014-03-30 04:03:30 +02:00
|
|
|
#define print_qt_id(q) print_qt(STRINGIFY(q), q)
|
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Axis Angle
|
|
|
|
* \{ */
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-20 09:01:14 +01:00
|
|
|
/* Conversion. */
|
|
|
|
|
2022-01-07 01:38:08 +01:00
|
|
|
void axis_angle_normalized_to_quat(float r[4], const float axis[3], float angle);
|
|
|
|
void axis_angle_to_quat(float r[4], const float axis[3], float angle);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Axis angle to 3x3 matrix - safer version (normalization of axis performed).
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* axis angle to 3x3 matrix
|
|
|
|
*
|
|
|
|
* This takes the angle with sin/cos applied so we can avoid calculating it in some cases.
|
|
|
|
*
|
|
|
|
* \param axis: rotation axis (must be normalized).
|
|
|
|
* \param angle_sin: sin(angle)
|
|
|
|
* \param angle_cos: cos(angle)
|
|
|
|
*/
|
2014-04-20 12:56:09 +02:00
|
|
|
void axis_angle_normalized_to_mat3_ex(float mat[3][3],
|
|
|
|
const float axis[3],
|
2022-01-07 01:38:08 +01:00
|
|
|
float angle_sin,
|
|
|
|
float angle_cos);
|
|
|
|
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Axis angle to 4x4 matrix - safer version (normalization of axis performed).
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* 3x3 matrix to axis angle.
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* 4x4 matrix to axis angle.
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
|
|
|
|
void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* 4x4 matrix to axis angle.
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Quaternions to Axis Angle.
|
|
|
|
*/
|
2015-10-23 22:02:51 +02:00
|
|
|
void quat_to_axis_angle(float axis[3], float *angle, const float q[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2022-01-07 01:38:08 +01:00
|
|
|
void angle_to_mat2(float R[2][2], float angle);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Create a 3x3 rotation matrix from a single axis.
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void axis_angle_to_mat3_single(float R[3][3], char axis, float angle);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Create a 4x4 rotation matrix from a single axis.
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void axis_angle_to_mat4_single(float R[4][4], char axis, float angle);
|
2011-09-19 15:08:01 +02:00
|
|
|
|
2022-01-07 01:38:08 +01:00
|
|
|
void axis_angle_to_quat_single(float q[4], char axis, float angle);
|
2015-10-22 18:08:17 +02:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Exponential Map
|
|
|
|
* \{ */
|
|
|
|
|
2015-02-01 11:58:10 +01:00
|
|
|
void quat_to_expmap(float expmap[3], const float q[4]);
|
|
|
|
void quat_normalized_to_expmap(float expmap[3], const float q[4]);
|
|
|
|
void expmap_to_quat(float r[4], const float expmap[3]);
|
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name XYZ Eulers
|
|
|
|
* \{ */
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2010-10-22 05:56:50 +02:00
|
|
|
void eul_to_quat(float quat[4], const float eul[3]);
|
|
|
|
void eul_to_mat3(float mat[3][3], const float eul[3]);
|
|
|
|
void eul_to_mat4(float mat[4][4], const float eul[3]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2019-02-25 13:14:48 +01:00
|
|
|
void mat3_normalized_to_eul(float eul[3], const float mat[3][3]);
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat4_normalized_to_eul(float eul[3], const float m[4][4]);
|
2019-02-25 13:14:48 +01:00
|
|
|
void mat3_to_eul(float eul[3], const float mat[3][3]);
|
|
|
|
void mat4_to_eul(float eul[3], const float mat[4][4]);
|
2015-10-23 22:02:51 +02:00
|
|
|
void quat_to_eul(float eul[3], const float quat[4]);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
|
|
|
|
void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
|
2015-10-23 22:02:51 +02:00
|
|
|
void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4]);
|
2022-08-21 07:06:28 +02:00
|
|
|
void rotate_eul(float beul[3], char axis, float angle);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-20 09:01:14 +01:00
|
|
|
/* Order independent. */
|
|
|
|
|
2023-02-20 11:51:16 +01:00
|
|
|
/**
|
|
|
|
* Manipulate `eul` so it's close to `oldrot` while representing the same rotation
|
|
|
|
* with the aim of having the minimum difference between all axes.
|
|
|
|
*
|
|
|
|
* This is typically done so interpolating the values between two euler rotations
|
|
|
|
* doesn't add undesired rotation (even rotating multiple times around one axis).
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void compatible_eul(float eul[3], const float oldrot[3]);
|
2021-12-20 09:01:14 +01:00
|
|
|
|
2022-01-07 01:38:08 +01:00
|
|
|
void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
|
|
|
|
void sub_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
|
2021-06-21 19:24:23 +02:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/** \} */
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Arbitrary Order Eulers
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
/* WARNING: must match the #eRotationModes in `DNA_action_types.h`
|
2009-11-09 23:42:41 +01:00
|
|
|
* order matters - types are saved to file. */
|
|
|
|
|
|
|
|
typedef enum eEulerRotationOrders {
|
|
|
|
EULER_ORDER_DEFAULT = 1, /* blender classic = XYZ */
|
|
|
|
EULER_ORDER_XYZ = 1,
|
|
|
|
EULER_ORDER_XZY,
|
|
|
|
EULER_ORDER_YXZ,
|
|
|
|
EULER_ORDER_YZX,
|
|
|
|
EULER_ORDER_ZXY,
|
2019-04-16 16:40:47 +02:00
|
|
|
EULER_ORDER_ZYX,
|
2021-02-05 06:23:34 +01:00
|
|
|
/* There are 6 more entries with duplicate entries included. */
|
2009-11-09 23:42:41 +01:00
|
|
|
} eEulerRotationOrders;
|
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Construct quaternion from Euler angles (in radians).
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void eulO_to_quat(float q[4], const float e[3], short order);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Construct 3x3 matrix from Euler angles (in radians).
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void eulO_to_mat3(float M[3][3], const float e[3], short order);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Construct 4x4 matrix from Euler angles (in radians).
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void eulO_to_mat4(float mat[4][4], const float e[3], short order);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Euler Rotation to Axis Angle.
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], short order);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* The matrix is written to as 3 axis vectors.
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], short order);
|
2015-10-23 22:02:51 +02:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Convert 3x3 matrix to Euler angles (in radians).
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat3_normalized_to_eulO(float eul[3], short order, const float m[3][3]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Convert 4x4 matrix to Euler angles (in radians).
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat4_normalized_to_eulO(float eul[3], short order, const float m[4][4]);
|
|
|
|
void mat3_to_eulO(float eul[3], short order, const float m[3][3]);
|
|
|
|
void mat4_to_eulO(float eul[3], short order, const float m[4][4]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Convert quaternion to Euler angles (in radians).
|
|
|
|
*/
|
2022-08-21 07:06:28 +02:00
|
|
|
void quat_to_eulO(float e[3], short order, const float q[4]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Axis Angle to Euler Rotation.
|
|
|
|
*/
|
2022-01-07 01:38:08 +01:00
|
|
|
void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float angle);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/* Uses 2 methods to retrieve eulers, and picks the closest. */
|
|
|
|
|
2019-02-25 13:14:48 +01:00
|
|
|
void mat3_normalized_to_compatible_eulO(float eul[3],
|
2022-08-21 07:06:28 +02:00
|
|
|
const float oldrot[3],
|
2022-01-07 01:38:08 +01:00
|
|
|
short order,
|
2019-02-25 13:14:48 +01:00
|
|
|
const float mat[3][3]);
|
|
|
|
void mat4_normalized_to_compatible_eulO(float eul[3],
|
2022-08-21 07:06:28 +02:00
|
|
|
const float oldrot[3],
|
2022-01-07 01:38:08 +01:00
|
|
|
short order,
|
2019-02-25 13:14:48 +01:00
|
|
|
const float mat[4][4]);
|
2022-08-21 07:06:28 +02:00
|
|
|
void mat3_to_compatible_eulO(float eul[3],
|
|
|
|
const float oldrot[3],
|
|
|
|
short order,
|
|
|
|
const float mat[3][3]);
|
|
|
|
void mat4_to_compatible_eulO(float eul[3],
|
|
|
|
const float oldrot[3],
|
|
|
|
short order,
|
|
|
|
const float mat[4][4]);
|
|
|
|
void quat_to_compatible_eulO(float eul[3],
|
|
|
|
const float oldrot[3],
|
|
|
|
short order,
|
|
|
|
const float quat[4]);
|
|
|
|
|
|
|
|
void rotate_eulO(float beul[3], short order, char axis, float angle);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Dual Quaternions
|
|
|
|
* \{ */
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2013-08-23 11:46:11 +02:00
|
|
|
void copy_dq_dq(DualQuat *r, const DualQuat *dq);
|
2022-08-21 07:06:28 +02:00
|
|
|
void normalize_dq(DualQuat *dq, float totweight);
|
2020-09-04 20:59:13 +02:00
|
|
|
void add_weighted_dq_dq(DualQuat *dq_sum, const DualQuat *dq, float weight);
|
2023-08-31 19:32:47 +02:00
|
|
|
void add_weighted_dq_dq_pivot(DualQuat *dq_sum,
|
|
|
|
const DualQuat *dq,
|
|
|
|
const float pivot[3],
|
|
|
|
float weight,
|
|
|
|
bool compute_scale_matrix);
|
2013-03-26 08:29:01 +01:00
|
|
|
void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2020-09-04 20:59:13 +02:00
|
|
|
void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4]);
|
2013-08-23 11:46:11 +02:00
|
|
|
void dquat_to_mat4(float R[4][4], const DualQuat *dq);
|
2009-11-09 23:42:41 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Axis matches #eTrackToAxis_Modes.
|
|
|
|
*/
|
2010-10-08 09:29:08 +02:00
|
|
|
void quat_apply_track(float quat[4], short axis, short upflag);
|
2010-10-08 04:08:11 +02:00
|
|
|
void vec_apply_track(float vec[3], short axis);
|
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Lens/angle conversion (radians).
|
|
|
|
*/
|
2011-11-04 15:36:06 +01:00
|
|
|
float focallength_to_fov(float focal_length, float sensor);
|
2022-08-21 07:06:28 +02:00
|
|
|
float fov_to_focallength(float hfov, float sensor);
|
2010-04-17 10:55:31 +02:00
|
|
|
|
2011-04-02 05:05:49 +02:00
|
|
|
float angle_wrap_rad(float angle);
|
|
|
|
float angle_wrap_deg(float angle);
|
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Returns an angle compatible with angle_compat.
|
|
|
|
*/
|
2013-02-19 05:37:28 +01:00
|
|
|
float angle_compat_rad(float angle, float angle_compat);
|
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Each argument us an axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z']
|
|
|
|
* where the first 2 are a source and the second 2 are the target.
|
|
|
|
*/
|
2017-06-09 11:31:27 +02:00
|
|
|
bool mat3_from_axis_conversion(
|
|
|
|
int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3]);
|
2021-12-09 10:01:44 +01:00
|
|
|
/**
|
|
|
|
* Use when the second axis can be guessed.
|
|
|
|
*/
|
2017-06-09 11:31:27 +02:00
|
|
|
bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3]);
|
2013-01-21 16:41:00 +01:00
|
|
|
|
2021-12-09 10:01:44 +01:00
|
|
|
/** \} */
|
|
|
|
|
2009-11-09 23:42:41 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|