aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/math/camera.h17
-rw-r--r--include/math/defs.h4
-rw-r--r--include/math/fwd.h10
-rw-r--r--include/math/mat4.h162
-rw-r--r--include/math/quat.h30
-rw-r--r--include/math/spatial3.h27
-rw-r--r--include/math/vec2.h20
-rw-r--r--include/math/vec3.h8
-rw-r--r--include/math/vec4.h4
9 files changed, 143 insertions, 139 deletions
diff --git a/include/math/camera.h b/include/math/camera.h
index 1621927..cb2c50b 100644
--- a/include/math/camera.h
+++ b/include/math/camera.h
@@ -5,7 +5,7 @@
5 5
6typedef struct Camera { 6typedef struct Camera {
7 Spatial3 spatial; 7 Spatial3 spatial;
8 mat4 projection; 8 mat4 projection;
9} Camera; 9} Camera;
10 10
11/// Create an orthographic camera. 11/// Create an orthographic camera.
@@ -19,11 +19,11 @@ typedef struct Camera {
19/// \param top The coordinate for the top horizontal clipping plane. 19/// \param top The coordinate for the top horizontal clipping plane.
20/// \param near The distance to the near clipping plane. 20/// \param near The distance to the near clipping plane.
21/// \param far The distance to the far clipping plane. 21/// \param far The distance to the far clipping plane.
22static inline Camera camera_orthographic(R left, R right, R bottom, R top, 22static inline Camera camera_orthographic(
23 R near, R far) { 23 R left, R right, R bottom, R top, R near, R far) {
24 return (Camera){.spatial = spatial3_make(), 24 return (Camera){
25 .projection = 25 .spatial = spatial3_make(),
26 mat4_ortho(left, right, bottom, top, near, far)}; 26 .projection = mat4_ortho(left, right, bottom, top, near, far)};
27} 27}
28 28
29/// Create a perspective camera. 29/// Create a perspective camera.
@@ -37,6 +37,7 @@ static inline Camera camera_orthographic(R left, R right, R bottom, R top,
37/// \param near Distance to the near clipping plane. 37/// \param near Distance to the near clipping plane.
38/// \param far Distance to the far clipping plane. 38/// \param far Distance to the far clipping plane.
39static inline Camera camera_perspective(R fovy, R aspect, R near, R far) { 39static inline Camera camera_perspective(R fovy, R aspect, R near, R far) {
40 return (Camera){.spatial = spatial3_make(), 40 return (Camera){
41 .projection = mat4_perspective(fovy, aspect, near, far)}; 41 .spatial = spatial3_make(),
42 .projection = mat4_perspective(fovy, aspect, near, far)};
42} 43}
diff --git a/include/math/defs.h b/include/math/defs.h
index e3c3b55..f67ee97 100644
--- a/include/math/defs.h
+++ b/include/math/defs.h
@@ -14,12 +14,12 @@ typedef double R;
14#define R_MIN DBL_MIN 14#define R_MIN DBL_MIN
15#define R_MAX DBL_MAX 15#define R_MAX DBL_MAX
16#else // floats 16#else // floats
17typedef float R; 17typedef float R;
18#define R_MIN FLT_MIN 18#define R_MIN FLT_MIN
19#define R_MAX FLT_MAX 19#define R_MAX FLT_MAX
20#endif 20#endif
21 21
22#define PI 3.14159265359 22#define PI 3.14159265359
23#define INV_PI 0.31830988618 23#define INV_PI 0.31830988618
24 24
25/// Radians per degree. 25/// Radians per degree.
diff --git a/include/math/fwd.h b/include/math/fwd.h
index 6c72ded..952df4a 100644
--- a/include/math/fwd.h
+++ b/include/math/fwd.h
@@ -1,9 +1,9 @@
1/// Forward declarations for all math objects. 1/// Forward declarations for all math objects.
2#pragma once 2#pragma once
3 3
4typedef struct Camera Camera; 4typedef struct Camera Camera;
5typedef struct mat4 mat4; 5typedef struct mat4 mat4;
6typedef struct spatial3 spatial3; 6typedef struct spatial3 spatial3;
7typedef struct vec2 vec2; 7typedef struct vec2 vec2;
8typedef struct vec3 vec3; 8typedef struct vec3 vec3;
9typedef struct vec4 vec4; 9typedef struct vec4 vec4;
diff --git a/include/math/mat4.h b/include/math/mat4.h
index 3ceb75b..e808d73 100644
--- a/include/math/mat4.h
+++ b/include/math/mat4.h
@@ -20,9 +20,9 @@ typedef struct mat4 {
20/// [ m10 m11 m12 m13 ] 20/// [ m10 m11 m12 m13 ]
21/// [ m20 m21 m22 m23 ] 21/// [ m20 m21 m22 m23 ]
22/// [ m30 m31 m32 m33 ] 22/// [ m30 m31 m32 m33 ]
23static inline mat4 mat4_make(R m00, R m01, R m02, R m03, R m10, R m11, R m12, 23static inline mat4 mat4_make(
24 R m13, R m20, R m21, R m22, R m23, R m30, R m31, 24 R m00, R m01, R m02, R m03, R m10, R m11, R m12, R m13, R m20, R m21, R m22,
25 R m32, R m33) { 25 R m23, R m30, R m31, R m32, R m33) {
26 mat4 m; 26 mat4 m;
27 m.val[0][0] = m00; 27 m.val[0][0] = m00;
28 m.val[0][1] = m10; 28 m.val[0][1] = m10;
@@ -73,22 +73,24 @@ static inline mat4 mat4_from_array(const R M[16]) {
73 73
74/// Construct the identity matrix. 74/// Construct the identity matrix.
75static inline mat4 mat4_id() { 75static inline mat4 mat4_id() {
76 return mat4_make(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 76 return mat4_make(
77 0.0, 0.0, 0.0, 1.0); 77 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
78 1.0);
78} 79}
79 80
80/// Construct a matrix from 4 column vectors. 81/// Construct a matrix from 4 column vectors.
81static inline mat4 mat4_from_vec4(vec4 v0, vec4 v1, vec4 v2, vec4 v3) { 82static inline mat4 mat4_from_vec4(vec4 v0, vec4 v1, vec4 v2, vec4 v3) {
82 return mat4_make(v0.x, v0.y, v0.z, v0.w, v1.x, v1.y, v1.z, v1.w, v2.x, v2.y, 83 return mat4_make(
83 v2.z, v2.w, v3.x, v3.y, v3.z, v3.w); 84 v0.x, v0.y, v0.z, v0.w, v1.x, v1.y, v1.z, v1.w, v2.x, v2.y, v2.z, v2.w,
85 v3.x, v3.y, v3.z, v3.w);
84} 86}
85 87
86/// Construct a transformation matrix from 4 vectors. 88/// Construct a transformation matrix from 4 vectors.
87static inline mat4 mat4_from_vec3(vec3 right, vec3 up, vec3 forward, 89static inline mat4 mat4_from_vec3(
88 vec3 position) { 90 vec3 right, vec3 up, vec3 forward, vec3 position) {
89 return mat4_make(right.x, right.y, right.z, 0.0, up.x, up.y, up.z, 0.0, 91 return mat4_make(
90 forward.x, forward.y, forward.z, 0.0, position.x, position.y, 92 right.x, right.y, right.z, 0.0, up.x, up.y, up.z, 0.0, forward.x,
91 position.z, 1.0); 93 forward.y, forward.z, 0.0, position.x, position.y, position.z, 1.0);
92} 94}
93 95
94/// Return the value at the specified position. 96/// Return the value at the specified position.
@@ -205,23 +207,25 @@ static inline mat4 mat4_mul(mat4 A, mat4 B) {
205 mat4_at(A, 3, 2) * mat4_at(B, 2, 3) + 207 mat4_at(A, 3, 2) * mat4_at(B, 2, 3) +
206 mat4_at(A, 3, 3) * mat4_at(B, 3, 3); 208 mat4_at(A, 3, 3) * mat4_at(B, 3, 3);
207 209
208 return mat4_make(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, 210 return mat4_make(
209 m30, m31, m32, m33); 211 m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32,
212 m33);
210} 213}
211 214
212/// Return the translation component of the matrix. 215/// Return the translation component of the matrix.
213static inline mat4 mat4_translation(mat4 m) { 216static inline mat4 mat4_translation(mat4 m) {
214 return mat4_make(1.0, 0.0, 0.0, mat4_at(m, 0, 3), 0.0, 1.0, 0.0, 217 return mat4_make(
215 mat4_at(m, 1, 3), 0.0, 0.0, 1.0, mat4_at(m, 2, 3), 0.0, 0.0, 218 1.0, 0.0, 0.0, mat4_at(m, 0, 3), 0.0, 1.0, 0.0, mat4_at(m, 1, 3), 0.0,
216 0.0, 1.0); 219 0.0, 1.0, mat4_at(m, 2, 3), 0.0, 0.0, 0.0, 1.0);
217} 220}
218 221
219/// Return the rotation component of the matrix. 222/// Return the rotation component of the matrix.
220static inline mat4 mat4_rotation(mat4 m) { 223static inline mat4 mat4_rotation(mat4 m) {
221 return mat4_make(mat4_at(m, 0, 0), mat4_at(m, 0, 1), mat4_at(m, 0, 2), 0.0, 224 return mat4_make(
222 mat4_at(m, 1, 0), mat4_at(m, 1, 1), mat4_at(m, 1, 2), 0.0, 225 mat4_at(m, 0, 0), mat4_at(m, 0, 1), mat4_at(m, 0, 2), 0.0,
223 mat4_at(m, 2, 0), mat4_at(m, 2, 1), mat4_at(m, 2, 2), 0.0, 226 mat4_at(m, 1, 0), mat4_at(m, 1, 1), mat4_at(m, 1, 2), 0.0,
224 0.0, 0.0, 0.0, 1.0); 227 mat4_at(m, 2, 0), mat4_at(m, 2, 1), mat4_at(m, 2, 2), 0.0, 0.0, 0.0, 0.0,
228 1.0);
225} 229}
226 230
227/// Create an X-axis rotation matrix. 231/// Create an X-axis rotation matrix.
@@ -247,22 +251,22 @@ static inline mat4 mat4_rotz(R angle) {
247 251
248/// Create a rotation matrix. 252/// Create a rotation matrix.
249static inline mat4 mat4_rot(vec3 axis, R angle) { 253static inline mat4 mat4_rot(vec3 axis, R angle) {
250 const R s = sin(angle); 254 const R s = sin(angle);
251 const R c = cos(angle); 255 const R c = cos(angle);
252 const R x = axis.x; 256 const R x = axis.x;
253 const R y = axis.y; 257 const R y = axis.y;
254 const R z = axis.z; 258 const R z = axis.z;
255 const R xy = x * y; 259 const R xy = x * y;
256 const R xz = x * z; 260 const R xz = x * z;
257 const R yz = y * z; 261 const R yz = y * z;
258 const R sx = s * x; 262 const R sx = s * x;
259 const R sy = s * y; 263 const R sy = s * y;
260 const R sz = s * z; 264 const R sz = s * z;
261 const R omc = 1.0 - c; 265 const R omc = 1.0 - c;
262 return mat4_make(c + omc * x * x, omc * xy - sz, omc * xz + sy, 0, 266 return mat4_make(
263 omc * xy + sz, c + omc * y * y, omc * yz - sx, 0, 267 c + omc * x * x, omc * xy - sz, omc * xz + sy, 0, omc * xy + sz,
264 omc * xz - sy, omc * yz + sx, c + omc * z * z, 0, 0, 0, 0, 268 c + omc * y * y, omc * yz - sx, 0, omc * xz - sy, omc * yz + sx,
265 1); 269 c + omc * z * z, 0, 0, 0, 0, 1);
266} 270}
267 271
268/// Create a scaling matrix. 272/// Create a scaling matrix.
@@ -295,15 +299,16 @@ static inline mat4 mat4_from_forward(vec3 forward) {
295 const vec3 f = vec3_normalize(forward); 299 const vec3 f = vec3_normalize(forward);
296 const vec3 r = vec3_normalize(vec3_cross(f, up3())); 300 const vec3 r = vec3_normalize(vec3_cross(f, up3()));
297 const vec3 u = vec3_normalize(vec3_cross(r, f)); 301 const vec3 u = vec3_normalize(vec3_cross(r, f));
298 return mat4_make(r.x, u.x, -f.x, 0.0, r.y, u.y, -f.y, 0.0, r.z, u.z, -f.z, 302 return mat4_make(
299 0.0, 0.0, 0.0, 0.0, 1.0); 303 r.x, u.x, -f.x, 0.0, r.y, u.y, -f.y, 0.0, r.z, u.z, -f.z, 0.0, 0.0, 0.0,
304 0.0, 1.0);
300} 305}
301 306
302/// Create a transformation matrix. 307/// Create a transformation matrix.
303static inline mat4 mat4_lookat(vec3 position, vec3 target, vec3 up) { 308static inline mat4 mat4_lookat(vec3 position, vec3 target, vec3 up) {
304 const vec3 fwd = vec3_normalize(vec3_sub(target, position)); 309 const vec3 fwd = vec3_normalize(vec3_sub(target, position));
305 const vec3 right = vec3_normalize(vec3_cross(fwd, up)); 310 const vec3 right = vec3_normalize(vec3_cross(fwd, up));
306 up = vec3_normalize(vec3_cross(right, fwd)); 311 up = vec3_normalize(vec3_cross(right, fwd));
307 return mat4_from_vec3(right, up, fwd, position); 312 return mat4_from_vec3(right, up, fwd, position);
308} 313}
309 314
@@ -318,8 +323,9 @@ static inline mat4 mat4_ortho(R left, R right, R bottom, R top, R near, R far) {
318 const R tx = -(right + left) / (right - left); 323 const R tx = -(right + left) / (right - left);
319 const R ty = -(top + bottom) / (top - bottom); 324 const R ty = -(top + bottom) / (top - bottom);
320 const R tz = -(far + near) / (far - near); 325 const R tz = -(far + near) / (far - near);
321 return mat4_make(2 / (right - left), 0, 0, tx, 0, 2 / (top - bottom), 0, ty, 326 return mat4_make(
322 0, 0, -2 / (far - near), tz, 0, 0, 0, 1); 327 2 / (right - left), 0, 0, tx, 0, 2 / (top - bottom), 0, ty, 0, 0,
328 -2 / (far - near), tz, 0, 0, 0, 1);
323} 329}
324 330
325/// Create a perspective projection matrix. 331/// Create a perspective projection matrix.
@@ -332,9 +338,11 @@ static inline mat4 mat4_perspective(R fovy, R aspect, R near, R far) {
332 R f = tan(fovy / 2.0); 338 R f = tan(fovy / 2.0);
333 assert(f > 0.0); 339 assert(f > 0.0);
334 f = 1.0 / f; 340 f = 1.0 / f;
341
335 const R a = near - far; 342 const R a = near - far;
336 return mat4_make(f / aspect, 0, 0, 0, 0, f, 0, 0, 0, 0, (far + near) / a, 343 return mat4_make(
337 (2 * far * near / a), 0, 0, -1, 0); 344 f / aspect, 0, 0, 0, 0, f, 0, 0, 0, 0, (far + near) / a,
345 (2 * far * near / a), 0, 0, -1, 0);
338} 346}
339 347
340/// Create the inverse of a perspective projection matrix. 348/// Create the inverse of a perspective projection matrix.
@@ -346,18 +354,18 @@ static inline mat4 mat4_perspective(R fovy, R aspect, R near, R far) {
346static inline mat4 mat4_perspective_inverse(R fovy, R aspect, R near, R far) { 354static inline mat4 mat4_perspective_inverse(R fovy, R aspect, R near, R far) {
347 R f = tan(fovy / 2.0); 355 R f = tan(fovy / 2.0);
348 assert(f > 0.0); 356 assert(f > 0.0);
349 f = 1.0 / f; 357 f = 1.0 / f;
350 const R a = far * near; 358 const R a = far * near;
351 const R P32 = 0.5 * (near - far) / a; 359 const R P32 = 0.5 * (near - far) / a;
352 const R P33 = 0.5 * (far + near) / a; 360 const R P33 = 0.5 * (far + near) / a;
353 return mat4_make(aspect / f, 0, 0, 0, 0, 1.0f / f, 0, 0, 0, 0, 0, -1, 0, 0, 361 return mat4_make(
354 P32, P33); 362 aspect / f, 0, 0, 0, 0, 1.0f / f, 0, 0, 0, 0, 0, -1, 0, 0, P32, P33);
355} 363}
356 364
357/// Return the matrix's determinant. 365/// Return the matrix's determinant.
358static inline R mat4_det(mat4 m) { 366static inline R mat4_det(mat4 m) {
359 const R* M = (const R*)(m.val); 367 const R* M = (const R*)(m.val);
360 const R inv0 = M[5] * M[10] * M[15] - M[5] * M[11] * M[14] - 368 const R inv0 = M[5] * M[10] * M[15] - M[5] * M[11] * M[14] -
361 M[9] * M[6] * M[15] + M[9] * M[7] * M[14] + 369 M[9] * M[6] * M[15] + M[9] * M[7] * M[14] +
362 M[13] * M[6] * M[11] - M[13] * M[7] * M[10]; 370 M[13] * M[6] * M[11] - M[13] * M[7] * M[10];
363 const R inv1 = -M[4] * M[10] * M[15] + M[4] * M[11] * M[14] + 371 const R inv1 = -M[4] * M[10] * M[15] + M[4] * M[11] * M[14] +
@@ -413,10 +421,11 @@ static inline mat4 mat4_inverse(mat4 m) {
413 R det = M[0] * inv[0] + M[1] * inv[4] + M[2] * inv[8] + M[3] * inv[12]; 421 R det = M[0] * inv[0] + M[1] * inv[4] + M[2] * inv[8] + M[3] * inv[12];
414 assert(det != 0.0); 422 assert(det != 0.0);
415 det = 1.0 / det; 423 det = 1.0 / det;
416 return mat4_make(inv[0] * det, inv[4] * det, inv[8] * det, inv[12] * det, 424 return mat4_make(
417 inv[1] * det, inv[5] * det, inv[9] * det, inv[13] * det, 425 inv[0] * det, inv[4] * det, inv[8] * det, inv[12] * det, inv[1] * det,
418 inv[2] * det, inv[6] * det, inv[10] * det, inv[14] * det, 426 inv[5] * det, inv[9] * det, inv[13] * det, inv[2] * det, inv[6] * det,
419 inv[3] * det, inv[7] * det, inv[11] * det, inv[15] * det); 427 inv[10] * det, inv[14] * det, inv[3] * det, inv[7] * det, inv[11] * det,
428 inv[15] * det);
420} 429}
421 430
422/// Invert the transformation matrix. 431/// Invert the transformation matrix.
@@ -428,9 +437,9 @@ static inline mat4 mat4_inverse_transform(mat4 m) {
428 const vec3 u = mat4_v1(m); 437 const vec3 u = mat4_v1(m);
429 const vec3 f = mat4_v2(m); 438 const vec3 f = mat4_v2(m);
430 const vec3 t = mat4_v3(m); 439 const vec3 t = mat4_v3(m);
431 return mat4_make(r.x, r.y, r.z, -vec3_dot(r, t), u.x, u.y, u.z, 440 return mat4_make(
432 -vec3_dot(u, t), f.x, f.y, f.z, -vec3_dot(f, t), 0.0, 0.0, 441 r.x, r.y, r.z, -vec3_dot(r, t), u.x, u.y, u.z, -vec3_dot(u, t), f.x, f.y,
433 0.0, 1.0); 442 f.z, -vec3_dot(f, t), 0.0, 0.0, 0.0, 1.0);
434} 443}
435 444
436/// Transpose the matrix. 445/// Transpose the matrix.
@@ -473,23 +482,24 @@ static inline vec4 mat4_mul_vec4(mat4 m, vec4 v) {
473/// within |eps|, false if there is at least one ij-value difference that is 482/// within |eps|, false if there is at least one ij-value difference that is
474/// greater than eps. 483/// greater than eps.
475static inline bool mat4_eq(mat4 m, mat4 w, float eps) { 484static inline bool mat4_eq(mat4 m, mat4 w, float eps) {
476 return (float_eq(mat4_at(m, 0, 0), mat4_at(w, 0, 0), eps) && 485 return (
477 float_eq(mat4_at(m, 0, 1), mat4_at(w, 0, 1), eps) && 486 float_eq(mat4_at(m, 0, 0), mat4_at(w, 0, 0), eps) &&
478 float_eq(mat4_at(m, 0, 2), mat4_at(w, 0, 2), eps) && 487 float_eq(mat4_at(m, 0, 1), mat4_at(w, 0, 1), eps) &&
479 float_eq(mat4_at(m, 0, 3), mat4_at(w, 0, 3), eps) && 488 float_eq(mat4_at(m, 0, 2), mat4_at(w, 0, 2), eps) &&
480 489 float_eq(mat4_at(m, 0, 3), mat4_at(w, 0, 3), eps) &&
481 float_eq(mat4_at(m, 1, 0), mat4_at(w, 1, 0), eps) && 490
482 float_eq(mat4_at(m, 1, 1), mat4_at(w, 1, 1), eps) && 491 float_eq(mat4_at(m, 1, 0), mat4_at(w, 1, 0), eps) &&
483 float_eq(mat4_at(m, 1, 2), mat4_at(w, 1, 2), eps) && 492 float_eq(mat4_at(m, 1, 1), mat4_at(w, 1, 1), eps) &&
484 float_eq(mat4_at(m, 1, 3), mat4_at(w, 1, 3), eps) && 493 float_eq(mat4_at(m, 1, 2), mat4_at(w, 1, 2), eps) &&
485 494 float_eq(mat4_at(m, 1, 3), mat4_at(w, 1, 3), eps) &&
486 float_eq(mat4_at(m, 2, 0), mat4_at(w, 2, 0), eps) && 495
487 float_eq(mat4_at(m, 2, 1), mat4_at(w, 2, 1), eps) && 496 float_eq(mat4_at(m, 2, 0), mat4_at(w, 2, 0), eps) &&
488 float_eq(mat4_at(m, 2, 2), mat4_at(w, 2, 2), eps) && 497 float_eq(mat4_at(m, 2, 1), mat4_at(w, 2, 1), eps) &&
489 float_eq(mat4_at(m, 2, 3), mat4_at(w, 2, 3), eps) && 498 float_eq(mat4_at(m, 2, 2), mat4_at(w, 2, 2), eps) &&
490 499 float_eq(mat4_at(m, 2, 3), mat4_at(w, 2, 3), eps) &&
491 float_eq(mat4_at(m, 3, 0), mat4_at(w, 3, 0), eps) && 500
492 float_eq(mat4_at(m, 3, 1), mat4_at(w, 3, 1), eps) && 501 float_eq(mat4_at(m, 3, 0), mat4_at(w, 3, 0), eps) &&
493 float_eq(mat4_at(m, 3, 2), mat4_at(w, 3, 2), eps) && 502 float_eq(mat4_at(m, 3, 1), mat4_at(w, 3, 1), eps) &&
494 float_eq(mat4_at(m, 3, 3), mat4_at(w, 3, 3), eps)); 503 float_eq(mat4_at(m, 3, 2), mat4_at(w, 3, 2), eps) &&
504 float_eq(mat4_at(m, 3, 3), mat4_at(w, 3, 3), eps));
495} 505}
diff --git a/include/math/quat.h b/include/math/quat.h
index 4503abd..b284567 100644
--- a/include/math/quat.h
+++ b/include/math/quat.h
@@ -23,14 +23,14 @@ static inline quat quat_from_array(const R xyzw[4]) {
23 23
24/// Construct a rotation quaternion. 24/// Construct a rotation quaternion.
25static inline quat qmake_rot(R angle, R x, R y, R z) { 25static inline quat qmake_rot(R angle, R x, R y, R z) {
26 const R a = angle * 0.5; 26 const R a = angle * 0.5;
27 const R sa = sin(a); 27 const R sa = sin(a);
28 const R w = cos(a); 28 const R w = cos(a);
29 R mag = sqrt(x * x + y * y + z * z); 29 R mag = sqrt(x * x + y * y + z * z);
30 mag = mag == 0.0 ? 1.0 : mag; 30 mag = mag == 0.0 ? 1.0 : mag;
31 x = x * sa; 31 x = x * sa;
32 y = y * sa; 32 y = y * sa;
33 z = z * sa; 33 z = z * sa;
34 return (quat){x / mag, y / mag, z / mag, w}; 34 return (quat){x / mag, y / mag, z / mag, w};
35} 35}
36 36
@@ -46,7 +46,7 @@ static inline quat qmul(quat q1, quat q2) {
46/// Invert the quaternion. 46/// Invert the quaternion.
47static inline quat qinv(quat q) { 47static inline quat qinv(quat q) {
48 R magsq = q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z; 48 R magsq = q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z;
49 magsq = magsq == 0.0f ? 1.0f : magsq; 49 magsq = magsq == 0.0f ? 1.0f : magsq;
50 return (quat){-q.x / magsq, -q.y / magsq, -q.z / magsq, q.w / magsq}; 50 return (quat){-q.x / magsq, -q.y / magsq, -q.z / magsq, q.w / magsq};
51} 51}
52 52
@@ -55,9 +55,9 @@ static inline quat qconj(quat q) { return (quat){-q.x, -q.y, -q.z, q.w}; }
55 55
56/// Rotate the given vector by the given unit quaternion. 56/// Rotate the given vector by the given unit quaternion.
57static inline vec3 qrot(quat q, vec3 v) { 57static inline vec3 qrot(quat q, vec3 v) {
58 const quat p = qconj(q); 58 const quat p = qconj(q);
59 const quat qv = (quat){v.x, v.y, v.z, 0}; 59 const quat qv = (quat){v.x, v.y, v.z, 0};
60 const quat u = qmul(qmul(q, qv), p); 60 const quat u = qmul(qmul(q, qv), p);
61 return vec3_make(u.x, u.y, u.z); 61 return vec3_make(u.x, u.y, u.z);
62} 62}
63 63
@@ -72,8 +72,8 @@ static inline mat4 mat4_from_quat(quat q) {
72 const R wx = q.w * q.x; 72 const R wx = q.w * q.x;
73 const R wy = q.w * q.y; 73 const R wy = q.w * q.y;
74 const R wz = q.w * q.z; 74 const R wz = q.w * q.z;
75 return mat4_make(1 - 2 * yy - 2 * zz, 2 * xy - 2 * wz, 2 * xz + 2 * wy, 0, 75 return mat4_make(
76 2 * xy + 2 * wz, 1 - 2 * xx - 2 * zz, 2 * yz - 2 * wx, 0, 76 1 - 2 * yy - 2 * zz, 2 * xy - 2 * wz, 2 * xz + 2 * wy, 0, 2 * xy + 2 * wz,
77 2 * xz - 2 * wy, 2 * yz + 2 * wx, 1 - 2 * xx - 2 * yy, 0, 0, 77 1 - 2 * xx - 2 * zz, 2 * yz - 2 * wx, 0, 2 * xz - 2 * wy, 2 * yz + 2 * wx,
78 0, 0, 1); 78 1 - 2 * xx - 2 * yy, 0, 0, 0, 0, 1);
79} 79}
diff --git a/include/math/spatial3.h b/include/math/spatial3.h
index f8caf5d..8de38bf 100644
--- a/include/math/spatial3.h
+++ b/include/math/spatial3.h
@@ -23,8 +23,9 @@ static inline mat4 spatial3_transform(const Spatial3* spatial) {
23 const vec3 r = spatial->r; 23 const vec3 r = spatial->r;
24 const vec3 u = spatial->u; 24 const vec3 u = spatial->u;
25 const vec3 f = spatial->f; 25 const vec3 f = spatial->f;
26 return mat4_make(r.x, u.x, -f.x, p.x, r.y, u.y, -f.y, p.y, r.z, u.z, -f.z, 26 return mat4_make(
27 p.z, 0.0, 0.0, 0.0, 1.0f); 27 r.x, u.x, -f.x, p.x, r.y, u.y, -f.y, p.y, r.z, u.z, -f.z, p.z, 0.0, 0.0,
28 0.0, 1.0f);
28} 29}
29 30
30/// Return the spatial's inverse transformation matrix (from world to local 31/// Return the spatial's inverse transformation matrix (from world to local
@@ -70,10 +71,10 @@ static inline void spatial3_move_down(Spatial3* spatial, R speed) {
70 71
71/// Rotate the spatial about the given axis by the given angle. 72/// Rotate the spatial about the given axis by the given angle.
72static inline void spatial3_rotate(Spatial3* spatial, vec3 axis, R angle) { 73static inline void spatial3_rotate(Spatial3* spatial, vec3 axis, R angle) {
73 mat4 transf = spatial3_transform(spatial); 74 mat4 transf = spatial3_transform(spatial);
74 const vec3 local_axis = 75 const vec3 local_axis =
75 vec3_normalize(mat4_mul_vec3(mat4_inverse_transform(transf), axis, 0.0)); 76 vec3_normalize(mat4_mul_vec3(mat4_inverse_transform(transf), axis, 0.0));
76 transf = mat4_mul(transf, mat4_rot(local_axis, angle)); 77 transf = mat4_mul(transf, mat4_rot(local_axis, angle));
77 spatial->r = vec3_normalize(mat4_v0(transf)); 78 spatial->r = vec3_normalize(mat4_v0(transf));
78 spatial->u = vec3_normalize(mat4_v1(transf)); 79 spatial->u = vec3_normalize(mat4_v1(transf));
79 spatial->f = vec3_normalize(vec3_neg(mat4_v2(transf))); 80 spatial->f = vec3_normalize(vec3_neg(mat4_v2(transf)));
@@ -131,8 +132,8 @@ static inline void spatial3_lookat(Spatial3* spatial, vec3 target) {
131} 132}
132 133
133/// Make the spatial look at the given target. 134/// Make the spatial look at the given target.
134static inline void spatial3_lookat_spatial(Spatial3* spatial, 135static inline void spatial3_lookat_spatial(
135 const Spatial3* target) { 136 Spatial3* spatial, const Spatial3* target) {
136 spatial3_set_forward(spatial, vec3_sub(target->p, spatial->p)); 137 spatial3_set_forward(spatial, vec3_sub(target->p, spatial->p));
137} 138}
138 139
@@ -141,14 +142,15 @@ static inline void spatial3_lookat_spatial(Spatial3* spatial,
141/// \param radius Radial distance. 142/// \param radius Radial distance.
142/// \param azimuth Azimuthal (horizontal) angle. 143/// \param azimuth Azimuthal (horizontal) angle.
143/// \param zenith Polar (vertical) angle. 144/// \param zenith Polar (vertical) angle.
144static inline void spatial3_orbit(Spatial3* spatial, vec3 target, R radius, 145static inline void spatial3_orbit(
145 R azimuth, R zenith) { 146 Spatial3* spatial, vec3 target, R radius, R azimuth, R zenith) {
146 const R sx = sin(azimuth); 147 const R sx = sin(azimuth);
147 const R sy = sin(zenith); 148 const R sy = sin(zenith);
148 const R cx = cos(azimuth); 149 const R cx = cos(azimuth);
149 const R cy = cos(zenith); 150 const R cy = cos(zenith);
150 spatial->p = (vec3){target.x + radius * cy * sx, target.y + radius * sy, 151 spatial->p = (vec3){
151 target.z + radius * cx * cy}; 152 target.x + radius * cy * sx, target.y + radius * sy,
153 target.z + radius * cx * cy};
152} 154}
153 155
154/// Make the spatial orbit around the given target. 156/// Make the spatial orbit around the given target.
@@ -156,9 +158,8 @@ static inline void spatial3_orbit(Spatial3* spatial, vec3 target, R radius,
156/// \param radius Radial distance. 158/// \param radius Radial distance.
157/// \param azimuth Azimuthal (horizontal) angle. 159/// \param azimuth Azimuthal (horizontal) angle.
158/// \param zenith Polar (vertical) angle. 160/// \param zenith Polar (vertical) angle.
159static inline void spatial3_orbit_spatial(Spatial3* spatial, 161static inline void spatial3_orbit_spatial(
160 const Spatial3* target, R radius, 162 Spatial3* spatial, const Spatial3* target, R radius, R azimuth, R zenith) {
161 R azimuth, R zenith) {
162 spatial3_orbit(spatial, target->p, radius, azimuth, zenith); 163 spatial3_orbit(spatial, target->p, radius, azimuth, zenith);
163} 164}
164 165
diff --git a/include/math/vec2.h b/include/math/vec2.h
index dc51c17..5a74705 100644
--- a/include/math/vec2.h
+++ b/include/math/vec2.h
@@ -52,19 +52,13 @@ static inline vec2 vec2_div(vec2 a, vec2 b) {
52} 52}
53 53
54/// Scale a vector by a scalar value. 54/// Scale a vector by a scalar value.
55static inline vec2 vec2_scale(vec2 v, R s) { 55static inline vec2 vec2_scale(vec2 v, R s) { return (vec2){v.x * s, v.y * s}; }
56 return (vec2){v.x * s, v.y * s};
57}
58 56
59/// Compare two vectors for equality. 57/// Compare two vectors for equality.
60static inline bool vec2_eq(vec2 a, vec2 b) { 58static inline bool vec2_eq(vec2 a, vec2 b) { return a.x == b.x && a.y == b.y; }
61 return a.x == b.x && a.y == b.y;
62}
63 59
64/// Return the absolute value of the vector. 60/// Return the absolute value of the vector.
65static inline vec2 vec2_abs(vec2 v) { 61static inline vec2 vec2_abs(vec2 v) { return (vec2){rabs(v.x), rabs(v.y)}; }
66 return (vec2){rabs(v.x), rabs(v.y)};
67}
68 62
69/// Compare two vectors for inequality. 63/// Compare two vectors for inequality.
70static inline bool vec2_ne(vec2 a, vec2 b) { return !(vec2_eq(a, b)); } 64static inline bool vec2_ne(vec2 a, vec2 b) { return !(vec2_eq(a, b)); }
@@ -92,9 +86,7 @@ static inline vec2 vec2_normalize(vec2 v) {
92} 86}
93 87
94/// Return the dot product of two vectors. 88/// Return the dot product of two vectors.
95static inline R vec2_dot(vec2 a, vec2 b) { 89static inline R vec2_dot(vec2 a, vec2 b) { return a.x * b.x + a.y * b.y; }
96 return a.x * b.x + a.y * b.y;
97}
98 90
99/// Reflect the vector about the normal. 91/// Reflect the vector about the normal.
100static inline vec2 vec2_reflect(vec2 v, vec2 n) { 92static inline vec2 vec2_reflect(vec2 v, vec2 n) {
@@ -108,8 +100,8 @@ static inline vec2 vec2_refract(vec2 v, vec2 n, R e) {
108 const R k = 1.0 - e * e * (1.0 - vec2_dot(n, v) * vec2_dot(n, v)); 100 const R k = 1.0 - e * e * (1.0 - vec2_dot(n, v) * vec2_dot(n, v));
109 assert(k >= 0); 101 assert(k >= 0);
110 // r = e*v - (e * dot(n,v) + sqrt(k)) * n 102 // r = e*v - (e * dot(n,v) + sqrt(k)) * n
111 return vec2_sub(vec2_scale(v, e), 103 return vec2_sub(
112 vec2_scale(n, e * vec2_dot(n, v) * sqrt(k))); 104 vec2_scale(v, e), vec2_scale(n, e * vec2_dot(n, v) * sqrt(k)));
113} 105}
114 106
115/// Elevate the vector to a power. 107/// Elevate the vector to a power.
diff --git a/include/math/vec3.h b/include/math/vec3.h
index caa212e..641c02f 100644
--- a/include/math/vec3.h
+++ b/include/math/vec3.h
@@ -98,8 +98,8 @@ static inline R vec3_dot(vec3 a, vec3 b) {
98 98
99/// Return the cross product of two vectors. 99/// Return the cross product of two vectors.
100static inline vec3 vec3_cross(vec3 a, vec3 b) { 100static inline vec3 vec3_cross(vec3 a, vec3 b) {
101 return (vec3){a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, 101 return (vec3){
102 a.x * b.y - a.y * b.x}; 102 a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
103} 103}
104 104
105/// Reflect the vector about the normal. 105/// Reflect the vector about the normal.
@@ -114,8 +114,8 @@ static inline vec3 vec3_refract(vec3 v, vec3 n, R e) {
114 const R k = 1.0 - e * e * (1.0 - vec3_dot(n, v) * vec3_dot(n, v)); 114 const R k = 1.0 - e * e * (1.0 - vec3_dot(n, v) * vec3_dot(n, v));
115 assert(k >= 0); 115 assert(k >= 0);
116 // r = e*v - (e * dot(n,v) + sqrt(k)) * n 116 // r = e*v - (e * dot(n,v) + sqrt(k)) * n
117 return vec3_sub(vec3_scale(v, e), 117 return vec3_sub(
118 vec3_scale(n, e * vec3_dot(n, v) * sqrt(k))); 118 vec3_scale(v, e), vec3_scale(n, e * vec3_dot(n, v) * sqrt(k)));
119} 119}
120 120
121/// Elevate the vector to a power. 121/// Elevate the vector to a power.
diff --git a/include/math/vec4.h b/include/math/vec4.h
index 60da464..5a797f6 100644
--- a/include/math/vec4.h
+++ b/include/math/vec4.h
@@ -112,8 +112,8 @@ static inline vec4 vec4_refract(vec4 v, vec4 n, R e) {
112 const R k = 1.0 - e * e * (1.0 - vec4_dot(n, v) * vec4_dot(n, v)); 112 const R k = 1.0 - e * e * (1.0 - vec4_dot(n, v) * vec4_dot(n, v));
113 assert(k >= 0); 113 assert(k >= 0);
114 // r = e*v - (e * dot(n,v) + sqrt(k)) * n 114 // r = e*v - (e * dot(n,v) + sqrt(k)) * n
115 return vec4_sub(vec4_scale(v, e), 115 return vec4_sub(
116 vec4_scale(n, e * vec4_dot(n, v) * sqrt(k))); 116 vec4_scale(v, e), vec4_scale(n, e * vec4_dot(n, v) * sqrt(k)));
117} 117}
118 118
119/// Elevate the vector to a power. 119/// Elevate the vector to a power.