LibGame  v0.4.0
The LG Game Engine - Copyright (C) 2024-2025 ETMSoftware
lg_quaternions.h
1 /*
2  * LibGame - Copyright (C) Emmanuel Thomas-Maurin 2011-2025
3  * All rights reserved
4  */
5 
6 #ifndef LG_QUATERNIONS_H
7 #define LG_QUATERNIONS_H
8 
9 #define POW2(x) (x * x)
10 #define POW3(x) (x * x * x)
11 
12 #define RAD_TO_DEG 57.295779513 /* or (180.0 / (float)M_PI) */
13 #define DEG_TO_RAD 0.017453293 /* or ((float)M_PI / 180.0) */
14 
15 #define EULER_ANGLES_DEFAULT_ROT_ORDER "XYZ" /* What should it be ? */
16 
17 /* Quaternion */
18 typedef struct {
19  double x; /* Vector part */
20  double y;
21  double z;
22  double w; /* Scalar part */
23 } LG_Quat;
24 
25 /* Euler angles */
26 typedef struct {
27  double x_rot; /* Rotation around X axis in radians - Use DEG_TO_RAD macro when necessary */
28  double y_rot;
29  double z_rot;
30 } LG_EulerAng;
31 
32 /* Axis and angle */
33 typedef struct {
34  vec3_t axis; /* Unit vector - should/must always be normalized ? */
35  double angle; /* In radians */
36 } LG_AxAng;
37 
38 /* 3 x 3, column-major order matrix -> move that to math_3d.h ? */
39 typedef union {
40  float m[3][3];
41  struct {
42  float m00, m01, m02;
43  float m10, m11, m12;
44  float m20, m21, m22;
45  };
46 } mat3_t;
47 
48 typedef struct {
49  float x;
50  float y;
51  float z;
52  float w;
53 } vec4_t;
54 
55 #define q_id lg_quat(0, 0, 0, 1)
56 
57 /*
58  * Convenient precomputed quat values
59  *
60  * half_pi_up = -(M_PI / 2.0) * 0.925
61  * half_pi_down = -(M_PI / 2.0) * 1.15
62  */
63 typedef struct {
64  LG_Quat id;
65  LG_Quat x_pi;
66  LG_Quat x_2_pi;
67  LG_Quat x_half_pi;
68  LG_Quat x_half_pi_inv;
69  LG_Quat x_half_pi_up;
70  LG_Quat x_half_pi_down;
71  LG_Quat x_quarter_pi;
72  LG_Quat y_pi;
73  LG_Quat y_2_pi;
74  LG_Quat y_half_pi;
75  LG_Quat y_half_pi_inv;
76  LG_Quat y_half_pi_up;
77  LG_Quat y_half_pi_down;
78  LG_Quat y_quarter_pi;
79  LG_Quat z_pi;
80  LG_Quat z_2_pi;
81  LG_Quat z_half_pi;
82  LG_Quat z_half_pi_inv;
83  LG_Quat z_half_pi_up;
84  LG_Quat z_half_pi_down;
85  LG_Quat z_quarter_pi;
86  LG_Quat x_small;
87  LG_Quat x_small_inv;
88  LG_Quat y_small;
89  LG_Quat y_small_inv;
90  LG_Quat z_small;
91  LG_Quat z_small_inv;
92  LG_Quat xyz_quarter_pi;
93 } LG_QuatV;
94 
95 LG_Quat lg_quat(double, double, double, double);
96 
98 
100 
102 
104 
106 
108 
110 
112 
114 
116 
118 
120 
121 int lg_quat_copy(LG_Quat *, const LG_Quat *);
122 
123 zboolean lg_quats_are_equal(LG_Quat *, LG_Quat *);
124 
125 void lg_quat_conjugate(LG_Quat *);
126 
128 
129 void lg_quat_invert(LG_Quat *);
130 
132 
133 double lg_quat_magnitude(LG_Quat);
134 
135 double lg_quats_dot(LG_Quat *, LG_Quat *);
136 
138 
140 
141 LG_Quat lg_quat_slerp(LG_Quat *, LG_Quat *, float);
142 
143 LG_EulerAng lg_euler_ang(double, double, double);
144 
146 
148 
150 
151 LG_AxAng lg_axis_ang(vec3_t, double);
152 
154 
155 mat3_t mat3(float, float, float, float, float, float, float, float, float);
156 
158 
159 LG_QuatV *lg_quatv();
160 
161 zboolean lg_set_euler_ang_rot_order(const char *);
162 
163 vec3_t lg_quat_get_yaw_pitch_roll(LG_Quat *, const char *);
164 
165 float lg_quat_get_yaw(LG_Quat *, const char *);
166 
167 float lg_quat_get_pitch(LG_Quat *, const char *);
168 
169 float lg_quat_get_roll(LG_Quat *, const char *);
170 
171 #endif /* LG_QUATERNIONS_H */
lg_axis_ang
LG_AxAng lg_axis_ang(vec3_t axis, double angle)
Definition: lg_quaternions.c:714
lg_euler_ang_from_rot_matrix
LG_EulerAng lg_euler_ang_from_rot_matrix(mat4_t m, const char *rot_order)
Definition: lg_quaternions.c:592
mat3_t
Definition: lg_quaternions.h:39
lg_euler_ang
LG_EulerAng lg_euler_ang(double x_rot, double y_rot, double z_rot)
Definition: lg_quaternions.c:560
lg_quat_normalize
void lg_quat_normalize(LG_Quat *q)
Definition: lg_quaternions.c:50
lg_quat_get_yaw
float lg_quat_get_yaw(LG_Quat *q, const char *rot_order)
Definition: lg_quaternions.c:960
lg_set_euler_ang_rot_order
zboolean lg_set_euler_ang_rot_order(const char *seq)
Definition: lg_quaternions.c:920
LG_Quat
Definition: lg_quaternions.h:18
lg_quat_as_vec4
vec4_t lg_quat_as_vec4(LG_Quat q)
Definition: lg_quaternions.c:40
mat3
mat3_t mat3(float m00, float m10, float m20, float m01, float m11, float m21, float m02, float m12, float m22)
Definition: lg_quaternions.c:808
lg_quat_to_axis_angle
void lg_quat_to_axis_angle(LG_Quat q, LG_AxAng *axis_ang)
Definition: lg_quaternions.c:219
lg_quat_from_euler_ang
LG_Quat lg_quat_from_euler_ang(LG_EulerAng an, const char *rot_order)
Definition: lg_quaternions.c:127
lg_quat_to_euler_ang
LG_EulerAng lg_quat_to_euler_ang(LG_Quat q, const char *rot_order)
Definition: lg_quaternions.c:185
lg_quat_conjugate
void lg_quat_conjugate(LG_Quat *q)
Definition: lg_quaternions.c:393
LG_EulerAng
Definition: lg_quaternions.h:26
lg_quat
LG_Quat lg_quat(double x, double y, double z, double w)
Definition: lg_quaternions.c:27
LG_QuatV
Definition: lg_quaternions.h:63
lg_quat_get_yaw_pitch_roll
vec3_t lg_quat_get_yaw_pitch_roll(LG_Quat *q, const char *rot_order)
Definition: lg_quaternions.c:947
vec4_t
Definition: lg_quaternions.h:48
lg_quat_get_conjugate
LG_Quat lg_quat_get_conjugate(LG_Quat q)
Definition: lg_quaternions.c:406
lg_quat_rotate_vec3
vec3_t lg_quat_rotate_vec3(LG_Quat q, vec3_t v)
Definition: lg_quaternions.c:336
lg_quat_magnitude
double lg_quat_magnitude(LG_Quat q)
Definition: lg_quaternions.c:447
lg_quat_slerp
LG_Quat lg_quat_slerp(LG_Quat *q_1, LG_Quat *q_2, float slerp_k)
Definition: lg_quaternions.c:503
lg_quat_get_roll
float lg_quat_get_roll(LG_Quat *q, const char *rot_order)
Definition: lg_quaternions.c:986
lg_quat_to_rot_matrix
mat4_t lg_quat_to_rot_matrix(LG_Quat q2)
Definition: lg_quaternions.c:312
vec3_t
Definition: math_3d.h:123
lg_quat_set_identity
void lg_quat_set_identity(LG_Quat *q)
Definition: lg_quaternions.c:471
lg_quat_get_identity
LG_Quat lg_quat_get_identity()
Definition: lg_quaternions.c:484
lg_quatv
LG_QuatV * lg_quatv()
Definition: lg_quaternions.c:861
lg_axis_angle_to_euler_ang
LG_EulerAng lg_axis_angle_to_euler_ang(LG_AxAng axis_ang)
Definition: lg_quaternions.c:747
m3_transpose
mat3_t m3_transpose(mat3_t matrix)
Definition: lg_quaternions.c:828
lg_quats_multiply
LG_Quat lg_quats_multiply(LG_Quat q1, LG_Quat q2)
Definition: lg_quaternions.c:95
lg_quat_get_normalized
LG_Quat lg_quat_get_normalized(LG_Quat q)
Definition: lg_quaternions.c:75
lg_euler_ang_as_v3
vec3_t lg_euler_ang_as_v3(LG_EulerAng an)
Definition: lg_quaternions.c:577
lg_quat_copy
int lg_quat_copy(LG_Quat *q_dest, const LG_Quat *q_src)
Definition: lg_quaternions.c:354
lg_quat_from_3x3_rot_matrix
LG_Quat lg_quat_from_3x3_rot_matrix(mat3_t m)
Definition: lg_quaternions.c:251
lg_quat_get_invert
LG_Quat lg_quat_get_invert(LG_Quat q)
Definition: lg_quaternions.c:433
lg_quat_get_pitch
float lg_quat_get_pitch(LG_Quat *q, const char *rot_order)
Definition: lg_quaternions.c:973
LG_AxAng
Definition: lg_quaternions.h:33
lg_quats_dot
double lg_quats_dot(LG_Quat *q1, LG_Quat *q2)
Definition: lg_quaternions.c:459
lg_quats_are_equal
zboolean lg_quats_are_equal(LG_Quat *q1, LG_Quat *q2)
Definition: lg_quaternions.c:377
lg_quat_to_3x3_rot_matrix
mat3_t lg_quat_to_3x3_rot_matrix(LG_Quat q2)
Definition: lg_quaternions.c:290
lg_euler_ang_from_TRS_matrix
LG_EulerAng lg_euler_ang_from_TRS_matrix(mat4_t *TRS_matrix, const char *euler_ang_rot_order)
Definition: lg_quaternions.c:666
lg_quat_from_axis_angle
LG_Quat lg_quat_from_axis_angle(LG_AxAng axis_ang)
Definition: lg_quaternions.c:197
lg_quat_invert
void lg_quat_invert(LG_Quat *q)
Definition: lg_quaternions.c:421
mat4_t
Definition: math_3d.h:179