diff options
| author | Marc Sunet <msunet@shellblade.net> | 2022-12-26 09:31:30 -0800 |
|---|---|---|
| committer | Marc Sunet <msunet@shellblade.net> | 2022-12-26 09:31:30 -0800 |
| commit | 60b9e875ae23cd93f87ed8ef16695d4eba14ca22 (patch) | |
| tree | f8282673299bd942f4d6306fcbefca83f5deef2f | |
| parent | 3a040b8b2edd66888a75447e7da69654950b9775 (diff) | |
Format.
| -rw-r--r-- | include/math/camera.h | 17 | ||||
| -rw-r--r-- | include/math/defs.h | 4 | ||||
| -rw-r--r-- | include/math/fwd.h | 10 | ||||
| -rw-r--r-- | include/math/mat4.h | 162 | ||||
| -rw-r--r-- | include/math/quat.h | 30 | ||||
| -rw-r--r-- | include/math/spatial3.h | 27 | ||||
| -rw-r--r-- | include/math/vec2.h | 20 | ||||
| -rw-r--r-- | include/math/vec3.h | 8 | ||||
| -rw-r--r-- | include/math/vec4.h | 4 |
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 | ||
| 6 | typedef struct Camera { | 6 | typedef 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. |
| 22 | static inline Camera camera_orthographic(R left, R right, R bottom, R top, | 22 | static 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. |
| 39 | static inline Camera camera_perspective(R fovy, R aspect, R near, R far) { | 39 | static 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 |
| 17 | typedef float R; | 17 | typedef 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 | ||
| 4 | typedef struct Camera Camera; | 4 | typedef struct Camera Camera; |
| 5 | typedef struct mat4 mat4; | 5 | typedef struct mat4 mat4; |
| 6 | typedef struct spatial3 spatial3; | 6 | typedef struct spatial3 spatial3; |
| 7 | typedef struct vec2 vec2; | 7 | typedef struct vec2 vec2; |
| 8 | typedef struct vec3 vec3; | 8 | typedef struct vec3 vec3; |
| 9 | typedef struct vec4 vec4; | 9 | typedef 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 ] |
| 23 | static inline mat4 mat4_make(R m00, R m01, R m02, R m03, R m10, R m11, R m12, | 23 | static 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. |
| 75 | static inline mat4 mat4_id() { | 75 | static 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. |
| 81 | static inline mat4 mat4_from_vec4(vec4 v0, vec4 v1, vec4 v2, vec4 v3) { | 82 | static 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. |
| 87 | static inline mat4 mat4_from_vec3(vec3 right, vec3 up, vec3 forward, | 89 | static 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. |
| 213 | static inline mat4 mat4_translation(mat4 m) { | 216 | static 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. |
| 220 | static inline mat4 mat4_rotation(mat4 m) { | 223 | static 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. |
| 249 | static inline mat4 mat4_rot(vec3 axis, R angle) { | 253 | static 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. |
| 303 | static inline mat4 mat4_lookat(vec3 position, vec3 target, vec3 up) { | 308 | static 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) { | |||
| 346 | static inline mat4 mat4_perspective_inverse(R fovy, R aspect, R near, R far) { | 354 | static 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. |
| 358 | static inline R mat4_det(mat4 m) { | 366 | static 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. |
| 475 | static inline bool mat4_eq(mat4 m, mat4 w, float eps) { | 484 | static 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. |
| 25 | static inline quat qmake_rot(R angle, R x, R y, R z) { | 25 | static 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. |
| 47 | static inline quat qinv(quat q) { | 47 | static 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. |
| 57 | static inline vec3 qrot(quat q, vec3 v) { | 57 | static 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. |
| 72 | static inline void spatial3_rotate(Spatial3* spatial, vec3 axis, R angle) { | 73 | static 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. |
| 134 | static inline void spatial3_lookat_spatial(Spatial3* spatial, | 135 | static 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. |
| 144 | static inline void spatial3_orbit(Spatial3* spatial, vec3 target, R radius, | 145 | static 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. |
| 159 | static inline void spatial3_orbit_spatial(Spatial3* spatial, | 161 | static 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. |
| 55 | static inline vec2 vec2_scale(vec2 v, R s) { | 55 | static 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. |
| 60 | static inline bool vec2_eq(vec2 a, vec2 b) { | 58 | static 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. |
| 65 | static inline vec2 vec2_abs(vec2 v) { | 61 | static 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. |
| 70 | static inline bool vec2_ne(vec2 a, vec2 b) { return !(vec2_eq(a, b)); } | 64 | static 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. |
| 95 | static inline R vec2_dot(vec2 a, vec2 b) { | 89 | static 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. |
| 100 | static inline vec2 vec2_reflect(vec2 v, vec2 n) { | 92 | static 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. |
| 100 | static inline vec3 vec3_cross(vec3 a, vec3 b) { | 100 | static 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. |
