Blender V5.0
BLI_math_rotation.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
10
11#include "BLI_math_base.h" // IWYU pragma: keep
12#include "BLI_math_constants.h" // IWYU pragma: keep
13#include "BLI_utildefines.h"
14
15#include "DNA_vec_types.h"
16
17/* -------------------------------------------------------------------- */
21
22/* Initialize */
23
24/* Convenience, avoids setting Y axis everywhere. */
25
26void unit_axis_angle(float axis[3], float *angle);
27void unit_qt(float q[4]);
28void copy_qt_qt(float q[4], const float a[4]);
29
30/* Arithmetic. */
31
32void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
52void mul_qt_v3(const float q[4], float r[3]);
56void mul_qt_fl(float q[4], float f);
57
61void pow_qt_fl_normalized(float q[4], float fac);
62
63void sub_qt_qtqt(float q[4], const float a[4], const float b[4]);
64
65void invert_qt(float q[4]);
66void invert_qt_qt(float q1[4], const float q2[4]);
72void invert_qt_normalized(float q[4]);
73void invert_qt_qt_normalized(float q1[4], const float q2[4]);
74void conjugate_qt(float q[4]);
75void conjugate_qt_qt(float q1[4], const float q2[4]);
76float dot_qtqt(const float a[4], const float b[4]);
77float normalize_qt(float q[4]);
78float normalize_qt_qt(float r[4], const float q[4]);
79
80/* Comparison. */
81
82bool is_zero_qt(const float q[4]);
83
84/* interpolation */
93void interp_dot_slerp(float t, float cosom, float r_w[2]);
94void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
95void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
96
97/* Conversion. */
98
99void quat_to_mat3(float m[3][3], const float q[4]);
100void quat_to_mat4(float m[4][4], const float q[4]);
101
106void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]);
107
111void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]);
112
113void mat3_normalized_to_quat(float q[4], const float mat[3][3]);
114void mat4_normalized_to_quat(float q[4], const float mat[4][4]);
115void mat3_to_quat(float q[4], const float mat[3][3]);
116void mat4_to_quat(float q[4], const float mat[4][4]);
121void tri_to_quat_ex(float quat[4],
122 const float v1[3],
123 const float v2[3],
124 const float v3[3],
125 const float no_orig[3]);
129float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]);
130void vec_to_quat(float q[4], const float vec[3], short axis, short upflag);
135void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]);
139void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
140void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]);
141
152float quat_split_swing_and_twist(const float q_in[4],
153 int axis,
154 float r_swing[4],
155 float r_twist[4]);
156
157float angle_normalized_qt(const float q[4]);
158float angle_normalized_qtqt(const float q1[4], const float q2[4]);
159float angle_qt(const float q[4]);
160float angle_qtqt(const float q1[4], const float q2[4]);
161
162float angle_signed_normalized_qt(const float q[4]);
163float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]);
164float angle_signed_qt(const float q[4]);
165float angle_signed_qtqt(const float q1[4], const float q2[4]);
166
171void mat3_to_quat_legacy(float q[4], const float wmat[3][3]);
172
173/* Other. */
174
192void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos);
193
194void print_qt(const char *str, const float q[4]);
195
196#define print_qt_id(q) print_qt(STRINGIFY(q), q)
197
199
200/* -------------------------------------------------------------------- */
203
204/* Conversion. */
205
206void axis_angle_normalized_to_quat(float r[4], const float axis[3], float angle);
207void axis_angle_to_quat(float r[4], const float axis[3], float angle);
211void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle);
221void axis_angle_normalized_to_mat3_ex(float mat[3][3],
222 const float axis[3],
223 float angle_sin,
224 float angle_cos);
225void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle);
229void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle);
230
234void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
238void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
239void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
243void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
247void quat_to_axis_angle(float axis[3], float *angle, const float q[4]);
248
249void angle_to_mat2(float R[2][2], float angle);
253void axis_angle_to_mat3_single(float R[3][3], char axis, float angle);
257void axis_angle_to_mat4_single(float R[4][4], char axis, float angle);
258
259void axis_angle_to_quat_single(float q[4], char axis, float angle);
260
262
263/* -------------------------------------------------------------------- */
266
267void quat_to_expmap(float expmap[3], const float q[4]);
268void quat_normalized_to_expmap(float expmap[3], const float q[4]);
269void expmap_to_quat(float r[4], const float expmap[3]);
270
272
273/* -------------------------------------------------------------------- */
276
277void eul_to_quat(float quat[4], const float eul[3]);
278void eul_to_mat3(float mat[3][3], const float eul[3]);
279void eul_to_mat4(float mat[4][4], const float eul[3]);
280
281void mat3_normalized_to_eul(float eul[3], const float mat[3][3]);
282void mat4_normalized_to_eul(float eul[3], const float m[4][4]);
283void mat3_to_eul(float eul[3], const float mat[3][3]);
284void mat4_to_eul(float eul[3], const float mat[4][4]);
285void quat_to_eul(float eul[3], const float quat[4]);
286
287void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
288void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
289void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4]);
290void rotate_eul(float beul[3], char axis, float angle);
291
292/* Order independent. */
293
301void compatible_eul(float eul[3], const float oldrot[3]);
302
303void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
304void sub_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
305
307
308/* -------------------------------------------------------------------- */
311
312/* WARNING: must match the #eRotationModes in `DNA_action_types.h`
313 * order matters - types are saved to file. */
314
316 EULER_ORDER_DEFAULT = 1, /* blender classic = XYZ */
323 /* There are 6 more entries with duplicate entries included. */
325
329void eulO_to_quat(float q[4], const float e[3], short order);
333void eulO_to_mat3(float M[3][3], const float e[3], short order);
337void eulO_to_mat4(float mat[4][4], const float e[3], short order);
341void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], short order);
345void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], short order);
346
350void mat3_normalized_to_eulO(float eul[3], short order, const float m[3][3]);
354void mat4_normalized_to_eulO(float eul[3], short order, const float m[4][4]);
355void mat3_to_eulO(float eul[3], short order, const float m[3][3]);
356void mat4_to_eulO(float eul[3], short order, const float m[4][4]);
360void quat_to_eulO(float e[3], short order, const float q[4]);
364void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float angle);
365
366/* Uses 2 methods to retrieve eulers, and picks the closest. */
367
368void mat3_normalized_to_compatible_eulO(float eul[3],
369 const float oldrot[3],
370 short order,
371 const float mat[3][3]);
372void mat4_normalized_to_compatible_eulO(float eul[3],
373 const float oldrot[3],
374 short order,
375 const float mat[4][4]);
376void mat3_to_compatible_eulO(float eul[3],
377 const float oldrot[3],
378 short order,
379 const float mat[3][3]);
380void mat4_to_compatible_eulO(float eul[3],
381 const float oldrot[3],
382 short order,
383 const float mat[4][4]);
384void quat_to_compatible_eulO(float eul[3],
385 const float oldrot[3],
386 short order,
387 const float quat[4]);
388
389void rotate_eulO(float beul[3], short order, char axis, float angle);
390
392
393/* -------------------------------------------------------------------- */
396
397void copy_dq_dq(DualQuat *r, const DualQuat *dq);
398void normalize_dq(DualQuat *dq, float totweight);
399void add_weighted_dq_dq(DualQuat *dq_sum, const DualQuat *dq, float weight);
405 const DualQuat *dq,
406 const float pivot[3],
407 float weight,
408 bool compute_scale_matrix);
409void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
410
411void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4]);
412void dquat_to_mat4(float R[4][4], const DualQuat *dq);
413
417void quat_apply_track(float quat[4], short axis, short upflag);
418void vec_apply_track(float vec[3], short axis);
419
423float focallength_to_fov(float focal_length, float sensor);
424float fov_to_focallength(float hfov, float sensor);
425
426float angle_wrap_rad(float angle);
427float angle_wrap_deg(float angle);
428
432float angle_compat_rad(float angle, float angle_compat);
433
439 int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3]);
443bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3]);
444
float angle_compat_rad(float angle, float angle_compat)
void pow_qt_fl_normalized(float q[4], float fac)
void mat4_normalized_to_eulO(float eul[3], short order, const float m[4][4])
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 rotate_eulO(float beul[3], short order, char axis, float angle)
void sub_eul_euleul(float r_eul[3], float a[3], float b[3], short order)
float angle_qtqt(const float q1[4], const float q2[4])
void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], short order)
void axis_angle_to_mat3_single(float R[3][3], char axis, float angle)
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void print_qt(const char *str, const float q[4])
void vec_apply_track(float vec[3], short axis)
float angle_normalized_qt(const float q[4])
float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3])
void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3])
float angle_signed_qt(const float q[4])
void invert_qt_normalized(float q[4])
void invert_qt_qt(float q1[4], const float q2[4])
void conjugate_qt_qt(float q1[4], const float q2[4])
void axis_angle_normalized_to_mat3_ex(float mat[3][3], const float axis[3], float angle_sin, float angle_cos)
void eul_to_mat3(float mat[3][3], const float eul[3])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void add_weighted_dq_dq(DualQuat *dq_sum, const DualQuat *dq, float weight)
void quat_to_mat3(float m[3][3], const float q[4])
void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos)
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle)
eEulerRotationOrders
@ EULER_ORDER_ZXY
@ EULER_ORDER_XZY
@ EULER_ORDER_XYZ
@ EULER_ORDER_DEFAULT
@ EULER_ORDER_YZX
@ EULER_ORDER_ZYX
@ EULER_ORDER_YXZ
void sub_qt_qtqt(float q[4], const float a[4], const float b[4])
void axis_angle_to_quat_single(float q[4], char axis, float angle)
void mat3_to_quat(float q[4], const float mat[3][3])
void vec_to_quat(float q[4], const float vec[3], short axis, short upflag)
void quat_to_eulO(float e[3], short order, const float q[4])
void mat4_to_eul(float eul[3], const float mat[4][4])
float normalize_qt(float q[4])
void invert_qt(float q[4])
void quat_normalized_to_expmap(float expmap[3], const float q[4])
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], short order)
void quat_to_mat4(float m[4][4], const float q[4])
void dquat_to_mat4(float R[4][4], const DualQuat *dq)
void mul_qt_fl(float q[4], float f)
void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4])
void mul_qt_v3(const float q[4], float r[3])
void angle_to_mat2(float R[2][2], float angle)
void unit_qt(float q[4])
void eulO_to_quat(float q[4], const float e[3], short order)
void axis_angle_normalized_to_quat(float r[4], const float axis[3], float angle)
void mat4_normalized_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float mat[4][4])
void eul_to_quat(float quat[4], const float eul[3])
void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle)
float fov_to_focallength(float hfov, float sensor)
void eulO_to_mat4(float mat[4][4], const float e[3], short order)
void mat3_to_quat_legacy(float q[4], const float wmat[3][3])
void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4])
void mat4_normalized_to_eul(float eul[3], const float m[4][4])
float angle_signed_normalized_qt(const float q[4])
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])
void invert_qt_qt_normalized(float q1[4], const float q2[4])
void mat4_to_eulO(float eul[3], short order, const float m[4][4])
bool is_zero_qt(const float q[4])
float quat_split_swing_and_twist(const float q_in[4], int axis, float r_swing[4], float r_twist[4])
void mat3_normalized_to_eul(float eul[3], const float mat[3][3])
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 mat3_to_eul(float eul[3], const float mat[3][3])
void quat_to_expmap(float expmap[3], const float q[4])
void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4])
void copy_dq_dq(DualQuat *r, const DualQuat *dq)
void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3])
void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float angle)
void mat4_to_quat(float q[4], const float mat[4][4])
void mat3_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float mat[3][3])
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3])
bool mat3_from_axis_conversion(int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3])
void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
float focallength_to_fov(float focal_length, float sensor)
void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq)
void conjugate_qt(float q[4])
void compatible_eul(float eul[3], const float oldrot[3])
void quat_apply_track(float quat[4], short axis, short upflag)
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])
void mat4_normalized_to_quat(float q[4], const float mat[4][4])
void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3])
void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4])
void eulO_to_mat3(float M[3][3], const float e[3], short order)
void add_weighted_dq_dq_pivot(DualQuat *dq_sum, const DualQuat *dq, const float pivot[3], float weight, bool compute_scale_matrix)
float angle_wrap_deg(float angle)
void unit_axis_angle(float axis[3], float *angle)
void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order)
void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3])
float angle_qt(const float q[4])
void mat3_normalized_to_eulO(float eul[3], short order, const float m[3][3])
void copy_qt_qt(float q[4], const float a[4])
void axis_angle_to_mat4_single(float R[4][4], char axis, float angle)
float angle_wrap_rad(float angle)
void normalize_dq(DualQuat *dq, float totweight)
void quat_to_compatible_quat(float q[4], const float a[4], const float old[4])
void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle)
void expmap_to_quat(float r[4], const float expmap[3])
void interp_dot_slerp(float t, float cosom, float r_w[2])
void mat3_to_eulO(float eul[3], short order, const float m[3][3])
void mat3_normalized_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float mat[3][3])
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
float angle_signed_qtqt(const float q1[4], const float q2[4])
void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3])
float angle_normalized_qtqt(const float q1[4], const float q2[4])
void rotate_eul(float beul[3], char axis, float angle)
void eul_to_mat4(float mat[4][4], const float eul[3])
void mat4_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float mat[4][4])
bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3])
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
#define str(s)
#define M
#define R