Blender V4.3
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
11#include "BLI_math_base.h"
12#include "BLI_utildefines.h"
13#include "DNA_vec_types.h"
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
19/* -------------------------------------------------------------------- */
23#define RAD2DEG(_rad) ((_rad) * (180.0 / M_PI))
24#define DEG2RAD(_deg) ((_deg) * (M_PI / 180.0))
25
26#define RAD2DEGF(_rad) ((_rad) * (float)(180.0 / M_PI))
27#define DEG2RADF(_deg) ((_deg) * (float)(M_PI / 180.0))
28
31/* -------------------------------------------------------------------- */
36/* Initialize */
37
38/* Convenience, avoids setting Y axis everywhere. */
39
40void unit_axis_angle(float axis[3], float *angle);
41void unit_qt(float q[4]);
42void copy_qt_qt(float q[4], const float a[4]);
43
44/* Arithmetic. */
45
46void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
66void mul_qt_v3(const float q[4], float r[3]);
70void mul_qt_fl(float q[4], float f);
71
75void pow_qt_fl_normalized(float q[4], float fac);
76
77void sub_qt_qtqt(float q[4], const float a[4], const float b[4]);
78
79void invert_qt(float q[4]);
80void invert_qt_qt(float q1[4], const float q2[4]);
86void invert_qt_normalized(float q[4]);
87void invert_qt_qt_normalized(float q1[4], const float q2[4]);
88void conjugate_qt(float q[4]);
89void conjugate_qt_qt(float q1[4], const float q2[4]);
90float dot_qtqt(const float a[4], const float b[4]);
91float normalize_qt(float q[4]);
92float normalize_qt_qt(float r[4], const float q[4]);
93
94/* Comparison. */
95
96bool is_zero_qt(const float q[4]);
97
98/* interpolation */
107void interp_dot_slerp(float t, float cosom, float r_w[2]);
108void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
109void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
110
111/* Conversion. */
112
113void quat_to_mat3(float m[3][3], const float q[4]);
114void quat_to_mat4(float m[4][4], const float q[4]);
115
120void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]);
121
125void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]);
126
127void mat3_normalized_to_quat(float q[4], const float mat[3][3]);
128void mat4_normalized_to_quat(float q[4], const float mat[4][4]);
129void mat3_to_quat(float q[4], const float mat[3][3]);
130void mat4_to_quat(float q[4], const float mat[4][4]);
135void tri_to_quat_ex(float quat[4],
136 const float v1[3],
137 const float v2[3],
138 const float v3[3],
139 const float no_orig[3]);
143float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]);
144void vec_to_quat(float q[4], const float vec[3], short axis, short upflag);
149void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]);
153void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
154void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]);
155
166float quat_split_swing_and_twist(const float q_in[4],
167 int axis,
168 float r_swing[4],
169 float r_twist[4]);
170
171float angle_normalized_qt(const float q[4]);
172float angle_normalized_qtqt(const float q1[4], const float q2[4]);
173float angle_qt(const float q[4]);
174float angle_qtqt(const float q1[4], const float q2[4]);
175
176float angle_signed_normalized_qt(const float q[4]);
177float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]);
178float angle_signed_qt(const float q[4]);
179float angle_signed_qtqt(const float q1[4], const float q2[4]);
180
185void mat3_to_quat_legacy(float q[4], const float wmat[3][3]);
186
187/* Other. */
188
206void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos);
207
208void print_qt(const char *str, const float q[4]);
209
210#define print_qt_id(q) print_qt(STRINGIFY(q), q)
211
214/* -------------------------------------------------------------------- */
218/* Conversion. */
219
220void axis_angle_normalized_to_quat(float r[4], const float axis[3], float angle);
221void axis_angle_to_quat(float r[4], const float axis[3], float angle);
225void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle);
235void axis_angle_normalized_to_mat3_ex(float mat[3][3],
236 const float axis[3],
237 float angle_sin,
238 float angle_cos);
239void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle);
243void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle);
244
248void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
252void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
253void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
257void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
261void quat_to_axis_angle(float axis[3], float *angle, const float q[4]);
262
263void angle_to_mat2(float R[2][2], float angle);
267void axis_angle_to_mat3_single(float R[3][3], char axis, float angle);
271void axis_angle_to_mat4_single(float R[4][4], char axis, float angle);
272
273void axis_angle_to_quat_single(float q[4], char axis, float angle);
274
277/* -------------------------------------------------------------------- */
281void quat_to_expmap(float expmap[3], const float q[4]);
282void quat_normalized_to_expmap(float expmap[3], const float q[4]);
283void expmap_to_quat(float r[4], const float expmap[3]);
284
287/* -------------------------------------------------------------------- */
291void eul_to_quat(float quat[4], const float eul[3]);
292void eul_to_mat3(float mat[3][3], const float eul[3]);
293void eul_to_mat4(float mat[4][4], const float eul[3]);
294
295void mat3_normalized_to_eul(float eul[3], const float mat[3][3]);
296void mat4_normalized_to_eul(float eul[3], const float m[4][4]);
297void mat3_to_eul(float eul[3], const float mat[3][3]);
298void mat4_to_eul(float eul[3], const float mat[4][4]);
299void quat_to_eul(float eul[3], const float quat[4]);
300
301void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
302void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
303void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4]);
304void rotate_eul(float beul[3], char axis, float angle);
305
306/* Order independent. */
307
315void compatible_eul(float eul[3], const float oldrot[3]);
316
317void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
318void sub_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
319
322/* -------------------------------------------------------------------- */
326/* WARNING: must match the #eRotationModes in `DNA_action_types.h`
327 * order matters - types are saved to file. */
328
330 EULER_ORDER_DEFAULT = 1, /* blender classic = XYZ */
337 /* There are 6 more entries with duplicate entries included. */
339
343void eulO_to_quat(float q[4], const float e[3], short order);
347void eulO_to_mat3(float M[3][3], const float e[3], short order);
351void eulO_to_mat4(float mat[4][4], const float e[3], short order);
355void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], short order);
359void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], short order);
360
364void mat3_normalized_to_eulO(float eul[3], short order, const float m[3][3]);
368void mat4_normalized_to_eulO(float eul[3], short order, const float m[4][4]);
369void mat3_to_eulO(float eul[3], short order, const float m[3][3]);
370void mat4_to_eulO(float eul[3], short order, const float m[4][4]);
374void quat_to_eulO(float e[3], short order, const float q[4]);
378void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float angle);
379
380/* Uses 2 methods to retrieve eulers, and picks the closest. */
381
382void mat3_normalized_to_compatible_eulO(float eul[3],
383 const float oldrot[3],
384 short order,
385 const float mat[3][3]);
386void mat4_normalized_to_compatible_eulO(float eul[3],
387 const float oldrot[3],
388 short order,
389 const float mat[4][4]);
390void mat3_to_compatible_eulO(float eul[3],
391 const float oldrot[3],
392 short order,
393 const float mat[3][3]);
394void mat4_to_compatible_eulO(float eul[3],
395 const float oldrot[3],
396 short order,
397 const float mat[4][4]);
398void quat_to_compatible_eulO(float eul[3],
399 const float oldrot[3],
400 short order,
401 const float quat[4]);
402
403void rotate_eulO(float beul[3], short order, char axis, float angle);
404
407/* -------------------------------------------------------------------- */
411void copy_dq_dq(DualQuat *r, const DualQuat *dq);
412void normalize_dq(DualQuat *dq, float totweight);
413void add_weighted_dq_dq(DualQuat *dq_sum, const DualQuat *dq, float weight);
415 const DualQuat *dq,
416 const float pivot[3],
417 float weight,
418 bool compute_scale_matrix);
419void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
420
421void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4]);
422void dquat_to_mat4(float R[4][4], const DualQuat *dq);
423
427void quat_apply_track(float quat[4], short axis, short upflag);
428void vec_apply_track(float vec[3], short axis);
429
433float focallength_to_fov(float focal_length, float sensor);
434float fov_to_focallength(float hfov, float sensor);
435
436float angle_wrap_rad(float angle);
437float angle_wrap_deg(float angle);
438
442float angle_compat_rad(float angle, float angle_compat);
443
449 int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3]);
453bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3]);
454
457#ifdef __cplusplus
458}
459#endif
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])
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
local_group_size(16, 16) .push_constant(Type b
#define str(s)
#define M
#define R