summaryrefslogtreecommitdiff
path: root/glm/affine.ha
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/affine.ha
Initial commit (import old repo)HEADmain
Diffstat (limited to 'glm/affine.ha')
-rw-r--r--glm/affine.ha80
1 files changed, 80 insertions, 0 deletions
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],
+ );
+};