Skip to main content

game_toolkit_gfx/
transform.rs

1//! Minimal column-major 4x4 matrix helpers for building 3D model transforms.
2//!
3//! Column-major matches WGSL's `mat4x4<f32>`: each inner `[f32; 4]` is a column, and the
4//! shader applies a matrix as `m * vec4(pos, 1.0)`.
5
6/// Column-major 4x4 matrix.
7pub type Mat4 = [[f32; 4]; 4];
8
9pub fn identity() -> Mat4 {
10    [
11        [1.0, 0.0, 0.0, 0.0],
12        [0.0, 1.0, 0.0, 0.0],
13        [0.0, 0.0, 1.0, 0.0],
14        [0.0, 0.0, 0.0, 1.0],
15    ]
16}
17
18/// Matrix product `a * b` (the transform `b` is applied first, then `a`).
19pub fn mul(a: &Mat4, b: &Mat4) -> Mat4 {
20    let mut out = [[0.0f32; 4]; 4];
21    for (col, out_col) in out.iter_mut().enumerate() {
22        for (row, slot) in out_col.iter_mut().enumerate() {
23            let mut s = 0.0;
24            for k in 0..4 {
25                s += a[k][row] * b[col][k];
26            }
27            *slot = s;
28        }
29    }
30    out
31}
32
33pub fn translation(t: [f32; 3]) -> Mat4 {
34    let mut m = identity();
35    m[3] = [t[0], t[1], t[2], 1.0];
36    m
37}
38
39pub fn scale(s: [f32; 3]) -> Mat4 {
40    [
41        [s[0], 0.0, 0.0, 0.0],
42        [0.0, s[1], 0.0, 0.0],
43        [0.0, 0.0, s[2], 0.0],
44        [0.0, 0.0, 0.0, 1.0],
45    ]
46}
47
48pub fn rotation_x(angle: f32) -> Mat4 {
49    let (s, c) = angle.sin_cos();
50    [
51        [1.0, 0.0, 0.0, 0.0],
52        [0.0, c, s, 0.0],
53        [0.0, -s, c, 0.0],
54        [0.0, 0.0, 0.0, 1.0],
55    ]
56}
57
58pub fn rotation_y(angle: f32) -> Mat4 {
59    let (s, c) = angle.sin_cos();
60    [
61        [c, 0.0, -s, 0.0],
62        [0.0, 1.0, 0.0, 0.0],
63        [s, 0.0, c, 0.0],
64        [0.0, 0.0, 0.0, 1.0],
65    ]
66}
67
68pub fn rotation_z(angle: f32) -> Mat4 {
69    let (s, c) = angle.sin_cos();
70    [
71        [c, s, 0.0, 0.0],
72        [-s, c, 0.0, 0.0],
73        [0.0, 0.0, 1.0, 0.0],
74        [0.0, 0.0, 0.0, 1.0],
75    ]
76}