export class Mat4 { constructor() { this.data = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] } set(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { const d = this.data d[0] = m00; d[1] = m01; d[2] = m02; d[3] = m03; d[4] = m10; d[5] = m11; d[6] = m12; d[7] = m13; d[8] = m20; d[9] = m21; d[10] = m22; d[11] = m23; d[12] = m30; d[13] = m31; d[14] = m32; d[15] = m33; return this } clone() { return new Mat4().arr(this.da) } arr(arr, offset = 0) { for(let i = 0; i < 16; i++) { this.data[i] = arr[i + offset] } return this } identity() { this.set( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ) return this } copy(m) { const d = this.data const o = m.data d[0] = o[0]; d[1] = o[1]; d[2] = o[2]; d[3] = o[3]; d[4] = o[4]; d[5] = o[5]; d[6] = o[6]; d[7] = o[7]; d[8] = o[8]; d[9] = o[9]; d[10] = o[10]; d[11] = o[11]; d[12] = o[12]; d[13] = o[13]; d[14] = o[14]; d[15] = o[15]; return this } pos(v) { const d = this.data const m30 = d[0] * v.x + d[4] * v.y + d[8] * v.z; const m31 = d[1] * v.x + d[5] * v.y + d[9] * v.z; const m32 = d[2] * v.x + d[6] * v.y + d[10] * v.z; const m33 = d[3] * v.x + d[7] * v.y + d[11] * v.z; d[3] += m30; d[7] += m31; d[11] += m32; d[15] += m33; return this; } rot(v) { const da = this.data; const c3 = Math.cos(v.z) const s3 = Math.sin(v.z) const c2 = Math.cos(v.x) const s2 = Math.sin(v.x) const c1 = Math.cos(v.y) const s1 = Math.sin(v.y) da[0] = c1 * c3 + s1 * s2 * s3 da[4] = c2 * s3 da[8] = c1 * s2 * s3 - c3 * s1 da[1] = c3 * s1 * s2 - c1 * s3 da[5] = c2 * c3 da[9] = c1 * c3 * s2 + s1 * s3 da[2] = c2 * s1 da[6] = -s2 da[10] = c1 * c2 return this } scale(v) { const d = this.data; d[0] *= v.x; d[1] *= v.y; d[2] *= v.z; d[4] *= v.x; d[5] *= v.y; d[6] *= v.z; d[8] *= v.x; d[9] *= v.y; d[10] *= v.z; d[12] *= v.x; d[13] *= v.y; d[14] *= v.z; return this; } get() { const d = this.data return new Float32Array([ d[0], d[4], d[8], d[12], d[1], d[5], d[9], d[13], d[2], d[6], d[10], d[14], d[3], d[7], d[11], d[15] ]) } }