export function mat4_mul(a, b) { const out = new Float32Array(16); for (let c = 0; c < 4; c++) { for (let r = 0; r < 4; r++) { let s = 0; for (let k = 0; k < 4; k++) { s += a[k*4+r] * b[c*4+k]; } out[c*4+r] = s; } } return out; } export function mat4_perspective(fov, aspect, near, far) { const f = 1 / Math.tan(fov / 2), nf = 1 / (near - far); return new Float32Array([f/aspect,0,0,0, 0,f,0,0, 0,0,(far+near)*nf,-1, 0,0,2*far*near*nf,0]); } export function mat4_translate_z(z) { return new Float32Array([1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,z,1]); } export function quat_identity() { return [0, 0, 0, 1]; } export function quat_from_axis_angle(ax, ay, az, a) { const s = Math.sin(a/2); return [ax*s, ay*s, az*s, Math.cos(a/2)]; } export function quat_mul([ax,ay,az,aw], [bx,by,bz,bw]) { return [aw*bx+ax*bw+ay*bz-az*by, aw*by-ax*bz+ay*bw+az*bx, aw*bz+ax*by-ay*bx+az*bw, aw*bw-ax*bx-ay*by-az*bz]; } export function quat_conj([x,y,z,w]) { return [-x,-y,-z,w]; } export function quat_rotate_vec([qx,qy,qz,qw], [vx,vy,vz]) { const tx = 2*(qy*vz - qz*vy); const ty = 2*(qz*vx - qx*vz); const tz = 2*(qx*vy - qy*vx); return [vx + qw*tx + qy*tz - qz*ty, vy + qw*ty + qz*tx - qx*tz, vz + qw*tz + qx*ty - qy*tx]; } export function mat4_from_quat([x,y,z,w]) { return new Float32Array([ 1-2*(y*y+z*z), 2*(x*y+w*z), 2*(x*z-w*y), 0, 2*(x*y-w*z), 1-2*(x*x+z*z), 2*(y*z+w*x), 0, 2*(x*z+w*y), 2*(y*z-w*x), 1-2*(x*x+y*y), 0, 0, 0, 0, 1, ]); } export function mat3_from_mat4(m) { return new Float32Array([m[0],m[1],m[2], m[4],m[5],m[6], m[8],m[9],m[10]]); }