Banjo API 0.0.1
C99 game development API
Loading...
Searching...
No Matches
quat.h
Go to the documentation of this file.
1
15#ifndef BJ_QUAT_H
16#define BJ_QUAT_H
17
18#include <banjo/api.h>
19#include <banjo/mat.h>
20#include <banjo/math.h>
21#include <banjo/vec.h>
22
27typedef bj_real bj_quat[4];
28
33#define bj_quat_add bj_vec4_add
34
39#define bj_quat_sub bj_vec4_sub
40
45#define bj_quat_norm bj_vec4_normalize
46
51#define bj_quat_scale bj_vec4_scale
52
57#define bj_quat_dot bj_vec4_dot
58
64{
65 q[0] = q[1] = q[2] = BJ_FZERO;
66 q[3] = BJ_F(1.0);
67}
68
76static BJ_INLINE void bj_quat_mul(bj_quat res, const bj_quat p, const bj_quat q)
77{
78 bj_vec3 w, tmp;
79
80 bj_vec3_cross(tmp, p, q);
81 bj_vec3_scale(w, p, q[3]);
82 bj_vec3_add(tmp, tmp, w);
83 bj_vec3_scale(w, q, p[3]);
84 bj_vec3_add(tmp, tmp, w);
85
86 bj_vec3_copy(res, tmp);
87 res[3] = p[3] * q[3] - bj_vec3_dot(p, q);
88}
89
95static BJ_INLINE void bj_quat_conjugate(bj_quat res, const bj_quat q)
96{
97 for (int i = 0; i < 3; ++i) {
98 res[i] = -q[i];
99 }
100 res[3] = q[3];
101}
102
111static BJ_INLINE void bj_quat_rotation(bj_quat res, bj_real angle, const bj_vec3 axis) {
112 bj_vec3 axis_norm;
113 bj_vec3_normalize(axis_norm, axis);
114 const bj_real s = bj_sin(angle / BJ_F(2.0));
115 const bj_real c = bj_cos(angle / BJ_F(2.0));
116 bj_vec3_scale(res, axis_norm, s);
117 res[3] = c;
118}
119
127static BJ_INLINE void bj_quat_mul_vec3(bj_vec3 res, const bj_quat q, const bj_vec3 v) {
128 bj_vec3 t;
129 bj_vec3 q_xyz = { q[0], q[1], q[2] };
130 bj_vec3 u = { q[0], q[1], q[2] };
131
132 bj_vec3_cross(t, q_xyz, v);
133 bj_vec3_scale(t, t, BJ_F(2));
134
135 bj_vec3_cross(u, q_xyz, t);
136 bj_vec3_scale(t, t, q[3]);
137
138 bj_vec3_add(res, v, t);
139 bj_vec3_add(res, res, u);
140}
141
148static BJ_INLINE void bj_mat4_from_quat(bj_mat4 res, const bj_quat q) {
149 bj_real a = q[3];
150 bj_real b = q[0];
151 bj_real c = q[1];
152 bj_real d = q[2];
153 bj_real a2 = a * a;
154 bj_real b2 = b * b;
155 bj_real c2 = c * c;
156 bj_real d2 = d * d;
157
158 res[0][0] = a2 + b2 - c2 - d2;
159 res[0][1] = BJ_F(2.0) * (b * c + a * d);
160 res[0][2] = BJ_F(2.0) * (b * d - a * c);
161 res[0][3] = BJ_FZERO;
162
163 res[1][0] = BJ_F(2) * (b * c - a * d);
164 res[1][1] = a2 - b2 + c2 - d2;
165 res[1][2] = BJ_F(2.0) * (c * d + a * b);
166 res[1][3] = BJ_FZERO;
167
168 res[2][0] = BJ_F(2.0) * (b * d + a * c);
169 res[2][1] = BJ_F(2.0) * (c * d - a * b);
170 res[2][2] = a2 - b2 - c2 + d2;
171 res[2][3] = BJ_FZERO;
172
173 res[3][0] = res[3][1] = res[3][2] = BJ_FZERO;
174 res[3][3] = BJ_F(1.0);
175}
176
184static BJ_INLINE void bj_mat4_rotate_from_quat(bj_mat4 R, const bj_mat4 M, const bj_quat q) {
185 bj_quat_mul_vec3(R[0], q, M[0]);
186 bj_quat_mul_vec3(R[1], q, M[1]);
187 bj_quat_mul_vec3(R[2], q, M[2]);
188
189 R[3][0] = R[3][1] = R[3][2] = BJ_FZERO;
190 R[0][3] = M[0][3];
191 R[1][3] = M[1][3];
192 R[2][3] = M[2][3];
193 R[3][3] = M[3][3];
194}
195
204 bj_real r = BJ_FZERO;
205 int i, j, k;
206
207 int perm[] = { 0, 1, 2, 0, 1 };
208 int* p = perm;
209
210 for (i = 0; i < 3; i++) {
211 bj_real m = M[i][i];
212 if (m > r) {
213 r = m;
214 p = &perm[i];
215 }
216 }
217
218 i = p[0];
219 j = p[1];
220 k = p[2];
221
222 r = bj_sqrt(BJ_F(1.0) + M[i][i] - M[j][j] - M[k][k]);
223
224 if (r < BJ_F(1e-6)) {
225 q[0] = BJ_FZERO;
226 q[1] = BJ_FZERO;
227 q[2] = BJ_FZERO;
228 q[3] = BJ_F(1.0);
229 return;
230 }
231
232 bj_real inv = BJ_F(0.5) / r;
233
234 q[i] = BJ_F(0.5) * r;
235 q[j] = (M[i][j] + M[j][i]) * inv;
236 q[k] = (M[k][i] + M[i][k]) * inv;
237 q[3] = (M[k][j] - M[j][k]) * inv;
238}
239
240
241
242#endif
243
245
246
General-purpose definitions for Banjo API.
#define BJ_INLINE
BJ_INLINE expands to an inline specifier appropriate for the toolchain.
Definition api.h:260
bj_real bj_vec3[3]
bj_vec3: 3D vector of bj_real values.
Definition vec.h:34
static void bj_mat4_from_quat(bj_mat4 res, const bj_quat q)
Convert unit quaternion to a 4×4 rotation matrix.
Definition quat.h:148
static void bj_vec3_add(bj_vec3 res, const bj_vec3 lhs, const bj_vec3 rhs)
Component-wise addition of two 3D vectors: res = lhs + rhs.
Definition vec.h:263
static void bj_quat_mul(bj_quat res, const bj_quat p, const bj_quat q)
Hamilton product: res = p * q.
Definition quat.h:76
static void bj_vec3_scale(bj_vec3 res, const bj_vec3 v, bj_real s)
Uniform scaling by scalar: res = v * s.
Definition vec.h:301
static void bj_quat_identity(bj_quat q)
Set quaternion to identity (no rotation).
Definition quat.h:63
static bj_real bj_vec3_dot(const bj_vec3 a, const bj_vec3 b)
Dot product of two 3D vectors.
Definition vec.h:313
#define bj_sin
Sine.
Definition math.h:221
bj_real bj_quat[4]
bj_quat: Quaternion stored as {x, y, z, w} with bj_real components.
Definition quat.h:27
bj_mat4x4 bj_mat4
bj_mat4: Alias for bj_mat4x4
Definition mat.h:50
#define BJ_FZERO
Zero constant in bj_real.
Definition math.h:64
static void bj_mat4_rotate_from_quat(bj_mat4 R, const bj_mat4 M, const bj_quat q)
Post-multiply matrix by rotation from quaternion: R = M * rot(q).
Definition quat.h:184
static void bj_quat_from_mat4(bj_quat q, const bj_mat4 M)
Extract a unit quaternion from a 4×4 rotation matrix.
Definition quat.h:203
#define bj_cos
Cosine.
Definition math.h:212
static void bj_quat_mul_vec3(bj_vec3 res, const bj_quat q, const bj_vec3 v)
Rotate a 3D vector by a unit quaternion.
Definition quat.h:127
static void bj_vec3_copy(bj_vec3 res, const bj_vec3 src)
Copy a 3D vector.
Definition vec.h:408
#define BJ_F(x)
Literal suffix helper for bj_real when float is selected.
Definition math.h:53
#define bj_sqrt
Square root.
Definition math.h:222
float bj_real
Selected real type for float configuration.
Definition math.h:51
static void bj_quat_rotation(bj_quat res, bj_real angle, const bj_vec3 axis)
Build a unit quaternion from axis-angle.
Definition quat.h:111
static void bj_vec3_cross(bj_vec3 res, const bj_vec3 l, const bj_vec3 r)
3D cross product: res = l × r (right-hand rule).
Definition vec.h:420
static void bj_quat_conjugate(bj_quat res, const bj_quat q)
Conjugate quaternion: (x,y,z,w) -> (-x,-y,-z,w).
Definition quat.h:95
static void bj_vec3_normalize(bj_vec3 res, const bj_vec3 v)
Normalize a 3D vector to unit length.
Definition vec.h:372
C99 math shim with bj_real precision type and scalar utilities.
C99 math shim with bj_real precision type and scalar utilities.
vector manipulation API