346 lines
11 KiB
JavaScript
346 lines
11 KiB
JavaScript
// most of the functions are from https://webglfundamentals.org/webgl/resources/m4.js! but i doesnt want to use them all and make some adjustment to them!
|
|
class TDUtils {
|
|
static lastMatrix = {m: null};
|
|
|
|
static multiply(a, b) {
|
|
let b00 = b[0];
|
|
let b01 = b[1];
|
|
let b02 = b[2];
|
|
let b03 = b[3];
|
|
let b10 = b[4];
|
|
let b11 = b[5];
|
|
let b12 = b[6];
|
|
let b13 = b[7];
|
|
let b20 = b[8];
|
|
let b21 = b[9];
|
|
let b22 = b[10];
|
|
let b23 = b[11];
|
|
let b30 = b[12];
|
|
let b31 = b[13];
|
|
let b32 = b[14];
|
|
let b33 = b[15];
|
|
let a00 = a[0];
|
|
let a01 = a[1];
|
|
let a02 = a[2];
|
|
let a03 = a[3];
|
|
let a10 = a[4];
|
|
let a11 = a[5];
|
|
let a12 = a[6];
|
|
let a13 = a[7];
|
|
let a20 = a[8];
|
|
let a21 = a[9];
|
|
let a22 = a[10];
|
|
let a23 = a[11];
|
|
let a30 = a[12];
|
|
let a31 = a[13];
|
|
let a32 = a[14];
|
|
let a33 = a[15];
|
|
return [
|
|
b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
|
|
b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
|
|
b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
|
|
b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
|
|
b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
|
|
b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
|
|
b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
|
|
b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
|
|
b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
|
|
b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
|
|
b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
|
|
b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
|
|
b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
|
|
b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
|
|
b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
|
|
b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33
|
|
];
|
|
}
|
|
|
|
static translate(m, tx, ty, tz, dst) {
|
|
dst = dst || new Float32Array(16);
|
|
|
|
let m00 = m[0],
|
|
m01 = m[1],
|
|
m02 = m[2],
|
|
m03 = m[3],
|
|
m10 = m[4],
|
|
m11 = m[5],
|
|
m12 = m[6],
|
|
m13 = m[7],
|
|
m20 = m[8],
|
|
m21 = m[9],
|
|
m22 = m[10],
|
|
m23 = m[11],
|
|
m30 = m[12],
|
|
m31 = m[13],
|
|
m32 = m[14],
|
|
m33 = m[15];
|
|
dst[0] = m00;
|
|
dst[1] = m01;
|
|
dst[2] = m02;
|
|
dst[3] = m03;
|
|
dst[4] = m10;
|
|
dst[5] = m11;
|
|
dst[6] = m12;
|
|
dst[7] = m13;
|
|
dst[8] = m20;
|
|
dst[9] = m21;
|
|
dst[10] = m22;
|
|
dst[11] = m23;
|
|
|
|
dst[12] = m00 * tx + m10 * ty + m20 * tz + m30;
|
|
dst[13] = m01 * tx + m11 * ty + m21 * tz + m31;
|
|
dst[14] = m02 * tx + m12 * ty + m22 * tz + m32;
|
|
dst[15] = m03 * tx + m13 * ty + m23 * tz + m33;
|
|
|
|
return dst;
|
|
}
|
|
|
|
static xRotation(angle) {
|
|
angle = TDUtils.degToRad(angle);
|
|
let c = Math.cos(angle);
|
|
let s = Math.sin(angle);
|
|
|
|
return [
|
|
1, 0, 0, 0,
|
|
0, c, s, 0,
|
|
0, -s, c, 0,
|
|
0, 0, 0, 1,
|
|
];
|
|
}
|
|
|
|
static yRotation(angle) {
|
|
angle = TDUtils.degToRad(angle);
|
|
let c = Math.cos(angle);
|
|
let s = Math.sin(angle);
|
|
|
|
return [
|
|
c, 0, -s, 0,
|
|
0, 1, 0, 0,
|
|
s, 0, c, 0,
|
|
0, 0, 0, 1,
|
|
];
|
|
}
|
|
|
|
static zRotation(angle) {
|
|
angle = TDUtils.degToRad(angle);
|
|
let c = Math.cos(angle);
|
|
let s = Math.sin(angle);
|
|
|
|
return [
|
|
c, s, 0, 0,
|
|
-s, c, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1,
|
|
];
|
|
}
|
|
|
|
static degToRad(d) {
|
|
return d * Math.PI / 180;
|
|
}
|
|
|
|
static scale(sx, sy, sz, dst) {
|
|
dst = dst || new Float32Array(16);
|
|
dst[0] = sx;
|
|
dst[5] = sy;
|
|
dst[10] = sz;
|
|
return dst;
|
|
}
|
|
|
|
static lookAt(cameraPosition, target, up, dst) {
|
|
dst = dst || new Float32Array(16);
|
|
let zAxis = TDUtils.normalize(
|
|
TDUtils.subtractVectors(cameraPosition, target));
|
|
let xAxis = TDUtils.normalize(TDUtils.cross(up, zAxis));
|
|
let yAxis = TDUtils.normalize(TDUtils.cross(zAxis, xAxis));
|
|
|
|
dst[0] = xAxis[0];
|
|
dst[1] = xAxis[1];
|
|
dst[2] = xAxis[2];
|
|
dst[4] = yAxis[0];
|
|
dst[5] = yAxis[1];
|
|
dst[6] = yAxis[2];
|
|
dst[8] = zAxis[0];
|
|
dst[9] = zAxis[1];
|
|
dst[10] = zAxis[2];
|
|
dst[12] = cameraPosition[0];
|
|
dst[13] = cameraPosition[1];
|
|
dst[14] = cameraPosition[2];
|
|
dst[15] = 1;
|
|
|
|
return dst;
|
|
}
|
|
|
|
static cross(a, b, dst) {
|
|
dst = dst || new Float32Array(3);
|
|
dst[0] = a[1] * b[2] - a[2] * b[1];
|
|
dst[1] = a[2] * b[0] - a[0] * b[2];
|
|
dst[2] = a[0] * b[1] - a[1] * b[0];
|
|
return dst;
|
|
}
|
|
|
|
static normalize(v, dst) {
|
|
dst = dst || new Float32Array(3);
|
|
let length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
if (length > 0.00001) {
|
|
dst[0] = v[0] / length;
|
|
dst[1] = v[1] / length;
|
|
dst[2] = v[2] / length;
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
static subtractVectors(a, b, dst) {
|
|
dst = dst || new Float32Array(3);
|
|
dst[0] = a[0] - b[0];
|
|
dst[1] = a[1] - b[1];
|
|
dst[2] = a[2] - b[2];
|
|
return dst;
|
|
}
|
|
|
|
static perspective(fieldOfViewInRadians, aspect, near, far, dst) {
|
|
dst = dst || new Float32Array(16);
|
|
let f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewInRadians),
|
|
rangeInv = 1.0 / (near - far);
|
|
|
|
dst[0] = f / aspect;
|
|
dst[5] = f;
|
|
dst[10] = (near + far) * rangeInv;
|
|
dst[11] = -1;
|
|
dst[14] = near * far * rangeInv * 2;
|
|
return dst;
|
|
}
|
|
|
|
static inverse(m, dst) {
|
|
dst = dst || new Float32Array(16);
|
|
let m00 = m[0],
|
|
m01 = m[1],
|
|
m02 = m[2],
|
|
m03 = m[3],
|
|
m10 = m[4],
|
|
m11 = m[5],
|
|
m12 = m[6],
|
|
m13 = m[7],
|
|
m20 = m[8],
|
|
m21 = m[9],
|
|
m22 = m[10],
|
|
m23 = m[11],
|
|
m30 = m[12],
|
|
m31 = m[13],
|
|
m32 = m[14],
|
|
m33 = m[15],
|
|
tmp_0 = m22 * m33,
|
|
tmp_1 = m32 * m23,
|
|
tmp_2 = m12 * m33,
|
|
tmp_3 = m32 * m13,
|
|
tmp_4 = m12 * m23,
|
|
tmp_5 = m22 * m13,
|
|
tmp_6 = m02 * m33,
|
|
tmp_7 = m32 * m03,
|
|
tmp_8 = m02 * m23,
|
|
tmp_9 = m22 * m03,
|
|
tmp_10 = m02 * m13,
|
|
tmp_11 = m12 * m03,
|
|
tmp_12 = m20 * m31,
|
|
tmp_13 = m30 * m21,
|
|
tmp_14 = m10 * m31,
|
|
tmp_15 = m30 * m11,
|
|
tmp_16 = m10 * m21,
|
|
tmp_17 = m20 * m11,
|
|
tmp_18 = m00 * m31,
|
|
tmp_19 = m30 * m01,
|
|
tmp_20 = m00 * m21,
|
|
tmp_21 = m20 * m01,
|
|
tmp_22 = m00 * m11,
|
|
tmp_23 = m10 * m01,
|
|
|
|
t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) -
|
|
(tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31),
|
|
t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) -
|
|
(tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31),
|
|
t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) -
|
|
(tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31),
|
|
t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) -
|
|
(tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21),
|
|
|
|
d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
|
|
|
|
dst[0] = d * t0;
|
|
dst[1] = d * t1;
|
|
dst[2] = d * t2;
|
|
dst[3] = d * t3;
|
|
dst[4] = d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) -
|
|
(tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30));
|
|
dst[5] = d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) -
|
|
(tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30));
|
|
dst[6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) -
|
|
(tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30));
|
|
dst[7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) -
|
|
(tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20));
|
|
dst[8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) -
|
|
(tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33));
|
|
dst[9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) -
|
|
(tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33));
|
|
dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) -
|
|
(tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33));
|
|
dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) -
|
|
(tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23));
|
|
dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) -
|
|
(tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22));
|
|
dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) -
|
|
(tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02));
|
|
dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) -
|
|
(tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12));
|
|
dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) -
|
|
(tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02));
|
|
|
|
return dst;
|
|
}
|
|
|
|
static aspectView(aspect) {
|
|
return [
|
|
1 * aspect, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
]
|
|
}
|
|
|
|
static getMatrix(fov, aspect, near, far, camAngle, radius) {
|
|
let lMat = this.lastMatrix,
|
|
u = TDUtils;
|
|
if (!u.isSame('fov', fov)
|
|
|| !u.isSame('aspect', aspect)
|
|
|| !u.isSame('near', near)
|
|
|| !u.isSame('far', far)
|
|
|| !u.isSame('cam', camAngle)
|
|
|| !u.isSame('radius', radius)
|
|
) {
|
|
let matrix = TDUtils.perspective(TDUtils.degToRad(fov), aspect, near, far),
|
|
cameraMatrix = TDUtils.yRotation(TDUtils.degToRad(camAngle));
|
|
cameraMatrix = TDUtils.translate(cameraMatrix, 0, 0, radius * 1.5);
|
|
let viewMatrix = TDUtils.inverse(cameraMatrix);
|
|
matrix = TDUtils.multiply(matrix, viewMatrix)
|
|
lMat.m = matrix;
|
|
}
|
|
return lMat.m;
|
|
}
|
|
|
|
static isSame(key, value) {
|
|
let lMat = this.lastMatrix;
|
|
if (lMat[key] !== value) {
|
|
lMat[key] = value;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static updateRotate(rotation, def) {
|
|
let value = vConf.get(rotation, def) + vConf.get(rotation + '-inc', 0)
|
|
if (value > 360) {
|
|
value -= 360;
|
|
} else if (value < -360) {
|
|
value += 360;
|
|
}
|
|
vConf.set(rotation, value);
|
|
}
|
|
} |