Blender V4.5
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#include "DNA_vec_types.h"
15
16/* -------------------------------------------------------------------- */
20
21/* Initialize */
22
23/* Convenience, avoids setting Y axis everywhere. */
24
25void unit_axis_angle(float axis[3], float *angle);
26void unit_qt(float q[4]);
27void copy_qt_qt(float q[4], const float a[4]);
28
29/* Arithmetic. */
30
31void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
51void mul_qt_v3(const float q[4], float r[3]);
55void mul_qt_fl(float q[4], float f);
56
60void pow_qt_fl_normalized(float q[4], float fac);
61
62void sub_qt_qtqt(float q[4], const float a[4], const float b[4]);
63
64void invert_qt(float q[4]);
65void invert_qt_qt(float q1[4], const float q2[4]);
71void invert_qt_normalized(float q[4]);
72void invert_qt_qt_normalized(float q1[4], const float q2[4]);
73void conjugate_qt(float q[4]);
74void conjugate_qt_qt(float q1[4], const float q2[4]);
75float dot_qtqt(const float a[4], const float b[4]);
76float normalize_qt(float q[4]);
77float normalize_qt_qt(float r[4], const float q[4]);
78
79/* Comparison. */
80
81bool is_zero_qt(const float q[4]);
82
83/* interpolation */
92void interp_dot_slerp(float t, float cosom, float r_w[2]);
93void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
94void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
95
96/* Conversion. */
97
98void quat_to_mat3(float m[3][3], const float q[4]);
99void quat_to_mat4(float m[4][4], const float q[4]);
100
105void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]);
106
110void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]);
111
112void mat3_normalized_to_quat(float q[4], const float mat[3][3]);
113void mat4_normalized_to_quat(float q[4], const float mat[4][4]);
114void mat3_to_quat(float q[4], const float mat[3][3]);
115void mat4_to_quat(float q[4], const float mat[4][4]);
120void tri_to_quat_ex(float quat[4],
121 const float v1[3],
122 const float v2[3],
123 const float v3[3],
124 const float no_orig[3]);
128float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]);
129void vec_to_quat(float q[4], const float vec[3], short axis, short upflag);
134void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]);
138void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
139void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]);
140
151float quat_split_swing_and_twist(const float q_in[4],
152 int axis,
153 float r_swing[4],
154 float r_twist[4]);
155
156float angle_normalized_qt(const float q[4]);
157float angle_normalized_qtqt(const float q1[4], const float q2[4]);
158float angle_qt(const float q[4]);
159float angle_qtqt(const float q1[4], const float q2[4]);
160
161float angle_signed_normalized_qt(const float q[4]);
162float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]);
163float angle_signed_qt(const float q[4]);
164float angle_signed_qtqt(const float q1[4], const float q2[4]);
165
170void mat3_to_quat_legacy(float q[4], const float wmat[3][3]);
171
172/* Other. */
173
191void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos);
192
193void print_qt(const char *str, const float q[4]);
194
195#define print_qt_id(q) print_qt(STRINGIFY(q), q)
196
198
199/* -------------------------------------------------------------------- */
202
203/* Conversion. */
204
205void axis_angle_normalized_to_quat(float r[4], const float axis[3], float angle);
206void axis_angle_to_quat(float r[4], const float axis[3], float angle);
210void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle);
220void axis_angle_normalized_to_mat3_ex(float mat[3][3],
221 const float axis[3],
222 float angle_sin,
223 float angle_cos);
224void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle);
228void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle);
229
233void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
237void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
238void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
242void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
246void quat_to_axis_angle(float axis[3], float *angle, const float q[4]);
247
248void angle_to_mat2(float R[2][2], float angle);
252void axis_angle_to_mat3_single(float R[3][3], char axis, float angle);
256void axis_angle_to_mat4_single(float R[4][4], char axis, float angle);
257
258void axis_angle_to_quat_single(float q[4], char axis, float angle);
259
261
262/* -------------------------------------------------------------------- */
265
266void quat_to_expmap(float expmap[3], const float q[4]);
267void quat_normalized_to_expmap(float expmap[3], const float q[4]);
268void expmap_to_quat(float r[4], const float expmap[3]);
269
271
272/* -------------------------------------------------------------------- */
275
276void eul_to_quat(float quat[4], const float eul[3]);
277void eul_to_mat3(float mat[3][3], const float eul[3]);
278void eul_to_mat4(float mat[4][4], const float eul[3]);
279
280void mat3_normalized_to_eul(float eul[3], const float mat[3][3]);
281void mat4_normalized_to_eul(float eul[3], const float m[4][4]);
282void mat3_to_eul(float eul[3], const float mat[3][3]);
283void mat4_to_eul(float eul[3], const float mat[4][4]);
284void quat_to_eul(float eul[3], const float quat[4]);
285
286void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
287void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
288void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4]);
289void rotate_eul(float beul[3], char axis, float angle);
290
291/* Order independent. */
292
300void compatible_eul(float eul[3], const float oldrot[3]);
301
302void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
303void sub_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
304
306
307/* -------------------------------------------------------------------- */
310
311/* WARNING: must match the #eRotationModes in `DNA_action_types.h`
312 * order matters - types are saved to file. */
313
315 EULER_ORDER_DEFAULT = 1, /* blender classic = XYZ */
322 /* There are 6 more entries with duplicate entries included. */
324
328void eulO_to_quat(float q[4], const float e[3], short order);
332void eulO_to_mat3(float M[3][3], const float e[3], short order);
336void eulO_to_mat4(float mat[4][4], const float e[3], short order);
340void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], short order);
344void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], short order);
345
349void mat3_normalized_to_eulO(float eul[3], short order, const float m[3][3]);
353void mat4_normalized_to_eulO(float eul[3], short order, const float m[4][4]);
354void mat3_to_eulO(float eul[3], short order, const float m[3][3]);
355void mat4_to_eulO(float eul[3], short order, const float m[4][4]);
359void quat_to_eulO(float e[3], short order, const float q[4]);
363void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float angle);
364
365/* Uses 2 methods to retrieve eulers, and picks the closest. */
366
367void mat3_normalized_to_compatible_eulO(float eul[3],
368 const float oldrot[3],
369 short order,
370 const float mat[3][3]);
371void mat4_normalized_to_compatible_eulO(float eul[3],
372 const float oldrot[3],
373 short order,
374 const float mat[4][4]);
375void mat3_to_compatible_eulO(float eul[3],
376 const float oldrot[3],
377 short order,
378 const float mat[3][3]);
379void mat4_to_compatible_eulO(float eul[3],
380 const float oldrot[3],
381 short order,
382 const float mat[4][4]);
383void quat_to_compatible_eulO(float eul[3],
384 const float oldrot[3],
385 short order,
386 const float quat[4]);
387
388void rotate_eulO(float beul[3], short order, char axis, float angle);
389
391
392/* -------------------------------------------------------------------- */
395
396void copy_dq_dq(DualQuat *r, const DualQuat *dq);
397void normalize_dq(DualQuat *dq, float totweight);
398void add_weighted_dq_dq(DualQuat *dq_sum, const DualQuat *dq, float weight);
404 const DualQuat *dq,
405 const float pivot[3],
406 float weight,
407 bool compute_scale_matrix);
408void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
409
410void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4]);
411void dquat_to_mat4(float R[4][4], const DualQuat *dq);
412
416void quat_apply_track(float quat[4], short axis, short upflag);
417void vec_apply_track(float vec[3], short axis);
418
422float focallength_to_fov(float focal_length, float sensor);
423float fov_to_focallength(float hfov, float sensor);
424
425float angle_wrap_rad(float angle);
426float angle_wrap_deg(float angle);
427
431float angle_compat_rad(float angle, float angle_compat);
432
438 int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3]);
442bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3]);
443
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