141 lines
No EOL
2.9 KiB
JavaScript
141 lines
No EOL
2.9 KiB
JavaScript
const PI = Math.PI
|
|
const PI2 = PI * 2
|
|
const PIH = PI * 0.5
|
|
const cosFromSin = (sin, angle) => {
|
|
const pih = PI / 2;
|
|
const pi2 = PI * 2
|
|
const cos = Math.sqrt(1.0 - sin * sin);
|
|
const a = angle + PIH;
|
|
const b = a - parseInt(a / PI2) * PI2;
|
|
if (b < 0.0)
|
|
b = PIH + b;
|
|
if (b >= PI)
|
|
return -cos;
|
|
return cos;
|
|
}
|
|
|
|
export class Mat4 {
|
|
|
|
constructor() {
|
|
this.data = [
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0
|
|
]
|
|
}
|
|
|
|
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) {
|
|
this.rotX(v.x)
|
|
this.rotY(v.y)
|
|
this.rotZ(v.z)
|
|
|
|
return this
|
|
}
|
|
|
|
rotX(a) {
|
|
const s = Math.sin(a), c = cosFromSin(s, a);
|
|
const d = this.data;
|
|
|
|
d[5] = c
|
|
d[6] = s
|
|
d[9] = -s
|
|
d[10] = c
|
|
|
|
return this
|
|
}
|
|
|
|
rotY(a) {
|
|
const s = Math.sin(a), c = cosFromSin(s, a);
|
|
const d = this.data;
|
|
|
|
d[0] = c
|
|
d[3] = -s
|
|
d[8] = c
|
|
d[10] = c
|
|
|
|
return this
|
|
}
|
|
|
|
rotZ(a) {
|
|
const s = Math.sin(a), c = cosFromSin(s, a);
|
|
const d = this.data;
|
|
|
|
d[0] = c
|
|
d[1] = s
|
|
d[4] = -s
|
|
d[5] = c
|
|
|
|
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() {
|
|
return new Float32Array(this.data)
|
|
}
|
|
} |