audio-vis/raw/javascript/gl/glUtils.js

391 lines
12 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 projection(width, height, depth) {
return [
2 / width, 0, 0, 0,
0, -2 / height, 0, 0,
0, 0, 2 / depth, 0,
-1, 1, 0, 1,
];
}
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 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);
}
static makeZToWMatrix(fudgeFactor) {
return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, fudgeFactor,
0, 0, 0, 1,
];
}
}
class GLHelper {
constructor(program) {
this.matrix = new Float32Array(16);
this.program = program;
}
static uniform4fv(program, name, data) {
let uniform = gl.getUniformLocation(program, name);
gl.uniform4fv(uniform, data);
}
static uniform3fv(program, name, data) {
let uniform = gl.getUniformLocation(program, name);
gl.uniform3fv(uniform, data);
}
static uniform1f(program, name, data) {
let uniform = gl.getUniformLocation(program, name);
gl.uniform1f(uniform, data);
}
rotateX(deg) {
this.matrix = TDUtils.multiply(this.matrix, TDUtils.xRotation(deg));
}
rotateY(deg) {
this.matrix = TDUtils.multiply(this.matrix, TDUtils.yRotation(deg));
}
rotateZ(deg) {
this.matrix = TDUtils.multiply(this.matrix, TDUtils.zRotation(deg));
}
scale(scaling) {
this.matrix = TDUtils.multiply(this.matrix, TDUtils.scale(scaling[0], scaling[1], scaling[2]))
}
project(depth) {
depth = depth || (c.width > c.height) ? c.width : c.height;
this.matrix = TDUtils.projection(c.width, c.height, depth)
}
translate(t) {
this.matrix = TDUtils.translate(this.matrix, t[0] || 0, t[1] || 0, t[2] || 0);
}
addFudgeFactor(fudgeFactor) {
this.matrix = TDUtils.multiply(TDUtils.makeZToWMatrix(fudgeFactor), this.matrix);
}
applyMatrix() {
let matrix = gl.getUniformLocation(this.program, "u_matrix");
gl.uniformMatrix4fv(matrix, false, this.matrix);
}
}