summaryrefslogtreecommitdiff
path: root/glm
diff options
context:
space:
mode:
authorLassi Pulkkinen <lassi@pulk.fi>2024-10-31 03:11:21 +0200
committerLassi Pulkkinen <lassi@pulk.fi>2024-10-31 03:51:35 +0200
commitae44478b30d890fe0fb04022f44d474dcdcc3f9d (patch)
tree5f462459ae4b47d22114eed717d1382d08cf4dfe /glm
Initial commit (import old repo)HEADmain
Diffstat (limited to 'glm')
-rw-r--r--glm/LICENSE8
-rw-r--r--glm/affine.ha80
-rw-r--r--glm/camera.ha71
-rw-r--r--glm/m4.ha105
-rw-r--r--glm/types.ha7
-rw-r--r--glm/util.ha9
-rw-r--r--glm/v2.ha10
-rw-r--r--glm/v3.ha127
-rw-r--r--glm/v4.ha105
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;
+};