diff options
author | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:11:21 +0200 |
---|---|---|
committer | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:51:35 +0200 |
commit | ae44478b30d890fe0fb04022f44d474dcdcc3f9d (patch) | |
tree | 5f462459ae4b47d22114eed717d1382d08cf4dfe /glm |
Diffstat (limited to 'glm')
-rw-r--r-- | glm/LICENSE | 8 | ||||
-rw-r--r-- | glm/affine.ha | 80 | ||||
-rw-r--r-- | glm/camera.ha | 71 | ||||
-rw-r--r-- | glm/m4.ha | 105 | ||||
-rw-r--r-- | glm/types.ha | 7 | ||||
-rw-r--r-- | glm/util.ha | 9 | ||||
-rw-r--r-- | glm/v2.ha | 10 | ||||
-rw-r--r-- | glm/v3.ha | 127 | ||||
-rw-r--r-- | glm/v4.ha | 105 |
9 files changed, 522 insertions, 0 deletions
diff --git a/glm/LICENSE b/glm/LICENSE new file mode 100644 index 0000000..69b6947 --- /dev/null +++ b/glm/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2022 Vlad-Stefan Harbuz <vlad@vladh.net> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +The software is provided "as is" and the author disclaims all warranties +with regard to this software. diff --git a/glm/affine.ha b/glm/affine.ha new file mode 100644 index 0000000..e36cdd9 --- /dev/null +++ b/glm/affine.ha @@ -0,0 +1,80 @@ +use math; + +export fn translation_make(v: *v3) m4 = { + const mat = m4_new_ident(); + v3_copy_to(v, m4_col(&mat, 3): *v3); + return mat; +}; + +export fn translate(m: *m4, v: *v3) void = { + const mat = translation_make(v); + const orig = *m; + m4_mul_to(&mat, &orig, m); +}; + +export fn rotation_make(angle: f32, axis: *v3) m4 = { + const r = m4_new_ident(); + const c = math::cosf64(angle): f32; + + let axisn = v3_new_zero(); + let v = v3_new_zero(); + let vs = v3_new_zero(); + + v3_normalize_to(axis, &axisn); + v3_scale_to(&axisn, 1.0 - c, &v); + v3_scale_to(&axisn, math::sinf64(angle): f32, &vs); + + v3_scale_to(&axisn, v[0], m4_col(&r, 0): *v3); + v3_scale_to(&axisn, v[1], m4_col(&r, 1): *v3); + v3_scale_to(&axisn, v[2], m4_col(&r, 2): *v3); + + r[0][0] += c; + r[1][0] -= vs[2]; + r[2][0] += vs[1]; + + r[0][1] += vs[2]; + r[1][1] += c; + r[2][1] -= vs[0]; + + r[0][2] -= vs[1]; + r[1][2] += vs[0]; + r[2][2] += c; + + return r; +}; + +export fn rotate(m: *m4, angle: f32, axis: *v3) void = { + const rot = rotation_make(angle, axis); + const orig = *m; + m4_mul_to(&rot, &orig, m); +}; + +export fn rotate_at(m: *m4, pivot: *v3, angle: f32, axis: *v3) void = { + const pivot_inv = v3_new_fill(0.0); + v3_negate_to(pivot, &pivot_inv); + translate(m, &pivot_inv); + rotate(m, angle, axis); + translate(m, pivot); +}; + +export fn scale_make(v: *v3) m4 = { + let res = m4_new_ident(); + res[0][0] = v[0]; + res[1][1] = v[1]; + res[2][2] = v[2]; + return res; +}; + +export fn scale(m: *m4, v: *v3) void = { + const mat = scale_make(v); + const orig = *m; + m4_mul_to(&mat, &orig, m); +}; + +export fn affine_mul_v3(a: *m4, b: *v3) v3 = { + return v3_new( + a[0][0] * b[0] + a[1][0] * b[1] + a[2][0] * b[2] + a[3][0], + a[0][1] * b[0] + a[1][1] * b[1] + a[2][1] * b[2] + a[3][1], + a[0][2] * b[0] + a[1][2] * b[1] + a[2][2] * b[2] + a[3][2], + ); +}; diff --git a/glm/camera.ha b/glm/camera.ha new file mode 100644 index 0000000..b648232 --- /dev/null +++ b/glm/camera.ha @@ -0,0 +1,71 @@ +use math; + +export fn ortho( + m: *m4, + left: f32, + right: f32, + bottom: f32, + top: f32, + znear: f32, + zfar: f32, +) void = { + m4_set_zero(m); + + const rl = 1.0 / (right - left); + const tb = 1.0 / (top - bottom); + const nf = -1.0 / (zfar - znear); + + m[0][0] = 2.0 * rl; + m[1][1] = 2.0 * tb; + m[2][2] = 2.0 * nf; + m[3][0] =-(right + left) * rl; + m[3][1] =-(top + bottom) * tb; + m[3][2] = (zfar + znear) * nf; + m[3][3] = 1.0; +}; + +export fn lookat(eye: *v3, center: *v3, up: *v3) m4 = { + const f = v3_sub(center, eye); + v3_normalize(&f); + const s = v3_crossn(&f, up); + const u = v3_cross(&s, &f); + + const res = m4_new(1.0); + res[0][0] = s[0]; + res[0][1] = u[0]; + res[0][2] = -f[0]; + res[1][0] = s[1]; + res[1][1] = u[1]; + res[1][2] = -f[1]; + res[2][0] = s[2]; + res[2][1] = u[2]; + res[2][2] = -f[2]; + res[3][0] = -v3_dot(&s, eye); + res[3][1] = -v3_dot(&u, eye); + res[3][2] = v3_dot(&f, eye); + res[0][3] = 0.0; + res[1][3] = 0.0; + res[2][3] = 0.0; + res[3][3] = 1.0; + return res; +}; + + +export fn perspective( + m: *m4, + fovy_in_deg: f32, + aspect_ratio: f32, + znear: f32, + zfar: f32 +) void = { + m4_set_zero(m); + + const f = 1.0 / math::tanf64(fovy_in_deg * 0.5): f32; + const f1 = 1.0 / (znear - zfar); + + m[0][0] = f / aspect_ratio; + m[1][1] = f; + m[2][2] = (znear + zfar) * f1; + m[2][3] = -1.0; + m[3][2] = 2.0 * znear * zfar * f1; +}; diff --git a/glm/m4.ha b/glm/m4.ha new file mode 100644 index 0000000..6b283e2 --- /dev/null +++ b/glm/m4.ha @@ -0,0 +1,105 @@ +use fmt; +use rt; + +export def M4_IDENT: m4 = [ + [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, 1.0], +]; + +export def M4_ZERO: m4 = [ + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], +]; + +export fn m4_new(diag: f32) m4 = { + return [ + [diag, 0.0, 0.0, 0.0], + [0.0, diag, 0.0, 0.0], + [0.0, 0.0, diag, 0.0], + [0.0, 0.0, 0.0, diag], + ]; +}; + +export fn m4_new_ident() m4 = { + return m4_new(1.0); +}; + +export fn m4_new_zero() m4 = { + return m4_new(0.0); +}; + +export fn m4_valptr(m: *m4) *const f32 = { + return &m[0][0]; +}; + +export fn m4_print(m: *m4) void = { + fmt::printfln("[ {}, {}, {}, {}, ", m[0][0], m[1][0], m[2][0], m[3][0])!; + fmt::printfln(" {}, {}, {}, {}, ", m[0][1], m[1][1], m[2][1], m[3][1])!; + fmt::printfln(" {}, {}, {}, {}, ", m[0][2], m[1][2], m[2][2], m[3][2])!; + fmt::printfln(" {}, {}, {}, {} ]", m[0][3], m[1][3], m[2][3], m[3][3])!; +}; + +export fn m4_set_ident(m: *m4) *m4 = { + m4_set_zero(m); + m[0][0] = 1.0; + m[1][1] = 1.0; + m[2][2] = 1.0; + m[3][3] = 1.0; + return m; +}; + +export fn m4_set_zero(m: *m4) *m4 = { + rt::memset(m, 0, 4 * 4 * 4); + return m; +}; + +export fn m4_col(m: *m4, col: int) *v4 = { + return (&m[col]: *[4]f32): *v4; +}; + +export fn m4_mul_to(a: *m4, b: *m4, dest: *m4) void = { + const a = *a; + const b = *b; + dest[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + + a[2][0] * b[0][2] + a[3][0] * b[0][3]; + dest[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + + a[2][1] * b[0][2] + a[3][1] * b[0][3]; + dest[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + + a[2][2] * b[0][2] + a[3][2] * b[0][3]; + dest[0][3] = a[0][3] * b[0][0] + a[1][3] * b[0][1] + + a[2][3] * b[0][2] + a[3][3] * b[0][3]; + dest[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + + a[2][0] * b[1][2] + a[3][0] * b[1][3]; + dest[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + + a[2][1] * b[1][2] + a[3][1] * b[1][3]; + dest[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + + a[2][2] * b[1][2] + a[3][2] * b[1][3]; + dest[1][3] = a[0][3] * b[1][0] + a[1][3] * b[1][1] + + a[2][3] * b[1][2] + a[3][3] * b[1][3]; + dest[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + + a[2][0] * b[2][2] + a[3][0] * b[2][3]; + dest[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + + a[2][1] * b[2][2] + a[3][1] * b[2][3]; + dest[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + + a[2][2] * b[2][2] + a[3][2] * b[2][3]; + dest[2][3] = a[0][3] * b[2][0] + a[1][3] * b[2][1] + + a[2][3] * b[2][2] + a[3][3] * b[2][3]; + dest[3][0] = a[0][0] * b[3][0] + a[1][0] * b[3][1] + + a[2][0] * b[3][2] + a[3][0] * b[3][3]; + dest[3][1] = a[0][1] * b[3][0] + a[1][1] * b[3][1] + + a[2][1] * b[3][2] + a[3][1] * b[3][3]; + dest[3][2] = a[0][2] * b[3][0] + a[1][2] * b[3][1] + + a[2][2] * b[3][2] + a[3][2] * b[3][3]; + dest[3][3] = a[0][3] * b[3][0] + a[1][3] * b[3][1] + + a[2][3] * b[3][2] + a[3][3] * b[3][3]; +}; + +export fn m4_mul(a: *m4, b: *m4) m4 = { + let res = m4_new_zero(); + m4_mul_to(a, b, &res); + return res; +}; diff --git a/glm/types.ha b/glm/types.ha new file mode 100644 index 0000000..3b14a67 --- /dev/null +++ b/glm/types.ha @@ -0,0 +1,7 @@ +export type m2 = [2][2]f32; +export type m3 = [3][3]f32; +export type m4 = [4][4]f32; +export type v2 = [2]f32; +export type v3 = [3]f32; +export type v4 = [4]f32; +export type quat = [4]f32; diff --git a/glm/util.ha b/glm/util.ha new file mode 100644 index 0000000..02e4afc --- /dev/null +++ b/glm/util.ha @@ -0,0 +1,9 @@ +use math; + +export fn rad(deg: f32) f32 = { + return deg * math::PI: f32 / 180.0; +}; + +export fn deg(rad: f32) f32 = { + return rad * 180.0 / math::PI: f32; +}; diff --git a/glm/v2.ha b/glm/v2.ha new file mode 100644 index 0000000..d8b5d51 --- /dev/null +++ b/glm/v2.ha @@ -0,0 +1,10 @@ +export def V2_ZERO: v2 = [0.0, 0.0]; +export def V2_ONE: v2 = [1.0, 1.0]; + +export fn v2_new(x: f32, y: f32) v2 = { + return [x, y]; +}; + +export fn v2_new_fill(x: f32) v2 = { + return [x, x]; +}; diff --git a/glm/v3.ha b/glm/v3.ha new file mode 100644 index 0000000..e7f1a8e --- /dev/null +++ b/glm/v3.ha @@ -0,0 +1,127 @@ +use fmt; +use math; + +export def V3_ZERO: v3 = [0.0, 0.0, 0.0]; +export def V3_ONE: v3 = [1.0, 1.0, 1.0]; + +export fn v3_new(x: f32, y: f32, z: f32) v3 = { + return [x, y, z]; +}; + +export fn v3_new_fill(x: f32) v3 = { + return [x, x, x]; +}; + +export fn v3_new_zero() v3 = { + return [0.0, 0.0, 0.0]; +}; + +export fn v3_copy(v: *v3) v3 = { + return [v[0], v[1], v[2]]; +}; + +export fn v3_copy_to(v: *v3, dest: *v3) void = { + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; +}; + +export fn v3_valptr(v: *v3) *const f32 = { + return &v[0]; +}; + +export fn v3_print(v: *v3) void = { + fmt::printfln("[ {}, {}, {} ]", v[0], v[1], v[2])!; +}; + +export fn v3_negate(v: *v3) void = { + v[0] *= -1.0; + v[1] *= -1.0; + v[2] *= -1.0; +}; + +export fn v3_negate_to(v: *v3, dest: *v3) void = { + dest[0] = v[0] * -1.0; + dest[1] = v[1] * -1.0; + dest[2] = v[2] * -1.0; +}; + +export fn v3_add(a: *v3, b: *v3) v3 = { + return [ + a[0] + b[0], + a[1] + b[1], + a[2] + b[2], + ]; +}; + +export fn v3_sub(a: *v3, b: *v3) v3 = { + return [ + a[0] - b[0], + a[1] - b[1], + a[2] - b[2], + ]; +}; + +export fn v3_normalize(v: *v3) void = { + const norm = v3_norm(v); + + if (norm == 0.0) { + v[0] = 0.0; + v[1] = 0.0; + v[2] = 0.0; + return; + }; + + v3_scale(v, 1.0 / norm); +}; + +export fn v3_normalize_to(v: *v3, dest: *v3) void = { + const norm = v3_norm(v); + + if (norm == 0.0) { + dest[0] = 0.0; + dest[1] = 0.0; + dest[2] = 0.0; + return; + }; + + v3_scale_to(v, 1.0 / norm, dest); +}; + +export fn v3_dot(a: *v3, b: *v3) f32 = { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +}; + +export fn v3_norm2(v: *v3) f32 = { + return v3_dot(v, v); +}; + +export fn v3_norm(v: *v3) f32 = { + return math::sqrtf64(v3_norm2(v)): f32; +}; + +export fn v3_scale(v: *v3, s: f32) void = { + v[0] = v[0] * s; + v[1] = v[1] * s; + v[2] = v[2] * s; +}; + +export fn v3_scale_to(v: *v3, s: f32, dest: *v3) void = { + dest[0] = v[0] * s; + dest[1] = v[1] * s; + dest[2] = v[2] * s; +}; + +export fn v3_cross(a: *v3, b: *v3) v3 = { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0], + ]; +}; + +export fn v3_crossn(a: *v3, b: *v3) v3 = { + let res = v3_cross(a, b); + v3_normalize(&res); + return res; +}; diff --git a/glm/v4.ha b/glm/v4.ha new file mode 100644 index 0000000..659be04 --- /dev/null +++ b/glm/v4.ha @@ -0,0 +1,105 @@ +use fmt; +use math; + +export fn v4_new(x: f32, y: f32, z: f32, w: f32) v4 = { + return [x, y, z, w]; +}; + +export fn v4_new_fill(x: f32) v4 = { + return [x, x, x, x]; +}; + +export fn v4_new_zero() v4 = { + return [0.0, 0.0, 0.0, 0.0]; +}; + +export fn v4_copy(v: *v4) v4 = { + return [v[0], v[1], v[2], v[3]]; +}; + +export fn v4_copy_to(v: *v4, dest: *v4) void = { + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + dest[3] = v[3]; +}; + +export fn v4_valptr(v: *v4) *const f32 = { + return &v[0]; +}; + +export fn v4_print(v: v4) void = { + fmt::printfln("[ {}, {}, {}, {} ]", v[0], v[1], v[2], v[3])!; +}; + +export fn v4_negate(v: *v4) void = { + v[0] *= -1.0; + v[1] *= -1.0; + v[2] *= -1.0; + v[3] *= -1.0; +}; + +export fn v4_negate_to(v: *v4, dest: *v4) void = { + dest[0] = v[0] * -1.0; + dest[1] = v[1] * -1.0; + dest[2] = v[2] * -1.0; + dest[3] = v[3] * -1.0; +}; + +export fn v4_add(a: *v4, b: *v4) v4 = { + return [ + a[0] + b[0], + a[1] + b[1], + a[2] + b[2], + a[3] + b[3], + ]; +}; + +export fn v4_sub(a: *v4, b: *v4) v4 = { + return [ + a[0] - b[0], + a[1] - b[1], + a[2] - b[2], + a[3] - b[3], + ]; +}; + +export fn v4_normalize(v: *v4) void = { + const norm = v4_norm(v); + + if (norm == 0.0) { + v[0] = 0.0; + v[1] = 0.0; + v[2] = 0.0; + v[3] = 0.0; + return; + }; + + v4_scale(v, 1.0 / norm); +}; + +export fn v4_dot(a: *v4, b: *v4) f32 = { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; +}; + +export fn v4_norm2(v: *v4) f32 = { + return v4_dot(v, v); +}; + +export fn v4_norm(v: *v4) f32 = { + return math::sqrtf64(v4_norm2(v)): f32; +}; + +export fn v4_scale(v: *v4, s: f32) void = { + v[0] = v[0] * s; + v[1] = v[1] * s; + v[2] = v[2] * s; + v[3] = v[3] * s; +}; + +export fn v4_scale_to(v: *v4, s: f32, dest: *v4) void = { + dest[0] = v[0] * s; + dest[1] = v[1] * s; + dest[2] = v[2] * s; + dest[3] = v[3] * s; +}; |