1// Column-major 4x4 matrices in the WebGPU convention (clip z in [0, 1]).
3export type Mat4 = Float32Array;
4export type Vec3 = [number, number, number];
6export function perspective(fovY: number, aspect: number, near: number, far: number): Mat4 {
7 const f = 1 / Math.tan(fovY / 2);
8 const m = new Float32Array(16);
9 m[0] = f / aspect;
10 m[5] = f;
11 m[10] = far / (near - far);
12 m[11] = -1;
13 m[14] = (near * far) / (near - far);
14 return m;
15}
17export function ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Mat4 {
18 const m = new Float32Array(16);
19 m[0] = 2 / (right - left);
20 m[5] = 2 / (top - bottom);
21 m[10] = -1 / (far - near);
22 m[12] = -(right + left) / (right - left);
23 m[13] = -(top + bottom) / (top - bottom);
24 m[14] = -near / (far - near);
25 m[15] = 1;
26 return m;
27}
29export function lookAt(eye: Vec3, target: Vec3, up: Vec3): Mat4 {
30 const z = unit([eye[0] - target[0], eye[1] - target[1], eye[2] - target[2]]);
31 const x = unit(cross(up, z));
32 const y = cross(z, x);
33 const m = new Float32Array(16);
34 m[0] = x[0]; m[1] = y[0]; m[2] = z[0];
35 m[4] = x[1]; m[5] = y[1]; m[6] = z[1];
36 m[8] = x[2]; m[9] = y[2]; m[10] = z[2];
37 m[12] = -dot(x, eye); m[13] = -dot(y, eye); m[14] = -dot(z, eye);
38 m[15] = 1;
39 return m;
40}
42export function multiply(a: Mat4, b: Mat4): Mat4 {
43 const out = new Float32Array(16);
44 for (let c = 0; c < 4; c++) {
45 for (let r = 0; r < 4; r++) {
46 let s = 0;
47 for (let k = 0; k < 4; k++) s += a[k * 4 + r] * b[c * 4 + k];
48 out[c * 4 + r] = s;
49 }
50 }
51 return out;
52}
54export function cross(a: Vec3, b: Vec3): Vec3 {
55 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]];
56}
57export function dot(a: Vec3, b: Vec3): number {
58 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
59}
60export function unit(a: Vec3): Vec3 {
61 const l = Math.hypot(a[0], a[1], a[2]) || 1;
62 return [a[0] / l, a[1] / l, a[2] / l];
63}
64export function scale(a: Vec3, s: number): Vec3 {
65 return [a[0] * s, a[1] * s, a[2] * s];
66}
67export function add(a: Vec3, b: Vec3): Vec3 {
68 return [a[0] + b[0], a[1] + b[1], a[2] + b[2]];
69}