431 lines
10 KiB
JavaScript
431 lines
10 KiB
JavaScript
|
class VTUtils {
|
||
|
static random(min, max) {
|
||
|
let rand = Math.random();
|
||
|
if (typeof min === 'undefined') {
|
||
|
return rand;
|
||
|
} else if (typeof max === 'undefined') {
|
||
|
if (min instanceof Array) {
|
||
|
return min[Math.floor(rand * min.length)];
|
||
|
} else {
|
||
|
return rand * min;
|
||
|
}
|
||
|
} else {
|
||
|
if (min > max) {
|
||
|
let tmp = min;
|
||
|
min = max;
|
||
|
max = tmp;
|
||
|
}
|
||
|
return rand * (max - min) + min;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
static randomInt(min, max) {
|
||
|
return Math.floor(VTUtils.random(min, max));
|
||
|
}
|
||
|
|
||
|
static normalize(val, max, min) {
|
||
|
return (val - min) / (max - min);
|
||
|
};
|
||
|
|
||
|
static distance(x, y, x2, y2) {
|
||
|
let a = x - x2;
|
||
|
let b = y - y2;
|
||
|
|
||
|
return Math.sqrt(a * a + b * b);
|
||
|
}
|
||
|
|
||
|
static map(n, start1, stop1, start2, stop2, withinBounds) {
|
||
|
let newVal = (n - start1) / (stop1 - start1) * (stop2 - start2) + start2;
|
||
|
if (!withinBounds) {
|
||
|
return newVal;
|
||
|
}
|
||
|
if (start2 < stop2) {
|
||
|
return this.constrain(newVal, start2, stop2);
|
||
|
} else {
|
||
|
return this.constrain(newVal, stop2, start2);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
static constrain(n, low, high) {
|
||
|
return Math.max(Math.min(n, high), low);
|
||
|
}
|
||
|
|
||
|
static hsvToRgb(h, s, v) {
|
||
|
var r, g, b;
|
||
|
|
||
|
var i = Math.floor(h * 6);
|
||
|
var f = h * 6 - i;
|
||
|
var p = v * (1 - s);
|
||
|
var q = v * (1 - f * s);
|
||
|
var t = v * (1 - (1 - f) * s);
|
||
|
|
||
|
switch (i % 6) {
|
||
|
case 0:
|
||
|
r = v, g = t, b = p;
|
||
|
break;
|
||
|
case 1:
|
||
|
r = q, g = v, b = p;
|
||
|
break;
|
||
|
case 2:
|
||
|
r = p, g = v, b = t;
|
||
|
break;
|
||
|
case 3:
|
||
|
r = p, g = q, b = v;
|
||
|
break;
|
||
|
case 4:
|
||
|
r = t, g = p, b = v;
|
||
|
break;
|
||
|
case 5:
|
||
|
r = v, g = p, b = q;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return {r: r, g: g, b: b};
|
||
|
}
|
||
|
|
||
|
static peakRGB(peak) {
|
||
|
return {
|
||
|
r: peak,
|
||
|
g: 1 - peak,
|
||
|
b: 0
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class VTVector {
|
||
|
constructor(x, y, z) {
|
||
|
this.x = x || 0;
|
||
|
this.y = y || 0;
|
||
|
this.z = z || 0;
|
||
|
}
|
||
|
|
||
|
//helper
|
||
|
static createRandom(x, y, z) {
|
||
|
x = x || 1;
|
||
|
y = y || 1;
|
||
|
z = z || 0;
|
||
|
return new VTVector(VTUtils.random(-x, x), VTUtils.random(-y, y), VTUtils.random(-z, z));
|
||
|
}
|
||
|
|
||
|
mult(times) {
|
||
|
this.x *= times;
|
||
|
this.y *= times;
|
||
|
this.z *= times;
|
||
|
}
|
||
|
|
||
|
set(vector) {
|
||
|
this.x = vector.x;
|
||
|
this.y = vector.y;
|
||
|
this.z = vector.z;
|
||
|
}
|
||
|
|
||
|
add(vector) {
|
||
|
this.x = this.x + vector.x;
|
||
|
this.y = this.y + vector.y;
|
||
|
this.z = this.z + vector.z;
|
||
|
}
|
||
|
|
||
|
addXYZ(x, y, z) {
|
||
|
this.x += x;
|
||
|
this.y += y;
|
||
|
this.z += z;
|
||
|
}
|
||
|
|
||
|
setXYZ(x, y, z) {
|
||
|
this.x = x || 0;
|
||
|
this.y = y || 0;
|
||
|
this.z = z || 0;
|
||
|
}
|
||
|
|
||
|
clone() {
|
||
|
return new VTVector(this.x, this.y, this.z);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class TDUtils {
|
||
|
static multiply(a, b) {
|
||
|
let b00 = b[0 * 4 + 0];
|
||
|
let b01 = b[0 * 4 + 1];
|
||
|
let b02 = b[0 * 4 + 2];
|
||
|
let b03 = b[0 * 4 + 3];
|
||
|
let b10 = b[1 * 4 + 0];
|
||
|
let b11 = b[1 * 4 + 1];
|
||
|
let b12 = b[1 * 4 + 2];
|
||
|
let b13 = b[1 * 4 + 3];
|
||
|
let b20 = b[2 * 4 + 0];
|
||
|
let b21 = b[2 * 4 + 1];
|
||
|
let b22 = b[2 * 4 + 2];
|
||
|
let b23 = b[2 * 4 + 3];
|
||
|
let b30 = b[3 * 4 + 0];
|
||
|
let b31 = b[3 * 4 + 1];
|
||
|
let b32 = b[3 * 4 + 2];
|
||
|
let b33 = b[3 * 4 + 3];
|
||
|
let a00 = a[0 * 4 + 0];
|
||
|
let a01 = a[0 * 4 + 1];
|
||
|
let a02 = a[0 * 4 + 2];
|
||
|
let a03 = a[0 * 4 + 3];
|
||
|
let a10 = a[1 * 4 + 0];
|
||
|
let a11 = a[1 * 4 + 1];
|
||
|
let a12 = a[1 * 4 + 2];
|
||
|
let a13 = a[1 * 4 + 3];
|
||
|
let a20 = a[2 * 4 + 0];
|
||
|
let a21 = a[2 * 4 + 1];
|
||
|
let a22 = a[2 * 4 + 2];
|
||
|
let a23 = a[2 * 4 + 3];
|
||
|
let a30 = a[3 * 4 + 0];
|
||
|
let a31 = a[3 * 4 + 1];
|
||
|
let a32 = a[3 * 4 + 2];
|
||
|
let a33 = a[3 * 4 + 3];
|
||
|
let dst = [];
|
||
|
dst[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
|
||
|
dst[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
|
||
|
dst[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
|
||
|
dst[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
|
||
|
dst[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
|
||
|
dst[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
|
||
|
dst[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
|
||
|
dst[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
|
||
|
dst[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
|
||
|
dst[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
|
||
|
dst[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
|
||
|
dst[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
|
||
|
dst[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
|
||
|
dst[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
|
||
|
dst[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
|
||
|
dst[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
static xRotation(angleInRadians) {
|
||
|
let c = Math.cos(angleInRadians);
|
||
|
let s = Math.sin(angleInRadians);
|
||
|
|
||
|
return [
|
||
|
1, 0, 0, 0,
|
||
|
0, c, s, 0,
|
||
|
0, -s, c, 0,
|
||
|
0, 0, 0, 1,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
static yRotation(angleInRadians) {
|
||
|
let c = Math.cos(angleInRadians);
|
||
|
let s = Math.sin(angleInRadians);
|
||
|
|
||
|
return [
|
||
|
c, 0, -s, 0,
|
||
|
0, 1, 0, 0,
|
||
|
s, 0, c, 0,
|
||
|
0, 0, 0, 1,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
static zRotation(angleInRadians) {
|
||
|
let c = Math.cos(angleInRadians);
|
||
|
let s = Math.sin(angleInRadians);
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function $(sel, s) {
|
||
|
return $$(sel, s)[0];
|
||
|
}
|
||
|
|
||
|
function $$(sel, s) {
|
||
|
s = s || document;
|
||
|
return s.querySelectorAll(sel);
|
||
|
}
|
||
|
|
||
|
Node.prototype.addDelegatedEventListener = function (type, aim, cb) {
|
||
|
this.addEventListener(type, (event) => {
|
||
|
let target = event.target;
|
||
|
if (target.matches(aim)) {
|
||
|
cb(event, target);
|
||
|
} else {
|
||
|
let parent = target.closest(aim);
|
||
|
if (parent) {
|
||
|
cb(event, parent);
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
};
|
||
|
|
||
|
function create(name, content) {
|
||
|
let d = document.createElement(name);
|
||
|
if (content) {
|
||
|
d.innerHTML = content;
|
||
|
}
|
||
|
return d;
|
||
|
}
|
||
|
|
||
|
function append(to, array) {
|
||
|
for (let item in array) {
|
||
|
to.appendChild(array[item]);
|
||
|
}
|
||
|
}
|
||
|
class ShaderHandler {
|
||
|
constructor(gl) {
|
||
|
this.gl = gl;
|
||
|
this.shaderNames = [];
|
||
|
this.shaders = {};
|
||
|
this.programs = {};
|
||
|
}
|
||
|
|
||
|
setGL(gl) {
|
||
|
this.gl = gl;
|
||
|
}
|
||
|
|
||
|
async loadShader(name, path) {
|
||
|
this.shaderNames.push(name);
|
||
|
await this.load(name, path + name + ".vert", this.gl.VERTEX_SHADER);
|
||
|
await this.load(name, path + name + ".frag", this.gl.FRAGMENT_SHADER);
|
||
|
}
|
||
|
|
||
|
async load(name, url, type) {
|
||
|
let realName = name + "_" + type;
|
||
|
if (!this.shaders[realName]) {
|
||
|
let data = await fetch(url);
|
||
|
let shader = this.createShader(await data.text(), type);
|
||
|
if (shader) {
|
||
|
this.shaders[realName] = shader;
|
||
|
}
|
||
|
}
|
||
|
return !!this.shaders[realName];
|
||
|
}
|
||
|
|
||
|
getShader(name, type) {
|
||
|
let realName = name + "_" + type;
|
||
|
return this.shaders[realName];
|
||
|
}
|
||
|
|
||
|
getAllShaders() {
|
||
|
return this.shaderNames;
|
||
|
}
|
||
|
|
||
|
async createProgramForEach(arr) {
|
||
|
arr = arr || this.shaderNames;
|
||
|
for (let i = 0; i < arr.length; i++) {
|
||
|
let shader = arr[i];
|
||
|
let v = await shaderHandler.createProgram(shader, [shader])
|
||
|
if (!v) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
createShader(source, type) {
|
||
|
let gl = this.gl;
|
||
|
let shader = gl.createShader(type);
|
||
|
gl.shaderSource(shader, source);
|
||
|
gl.compileShader(shader);
|
||
|
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||
|
return shader;
|
||
|
}
|
||
|
console.error(gl.getShaderInfoLog(shader));
|
||
|
gl.deleteShader(shader);
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
createProgram(name, shaders) {
|
||
|
let gl = this.gl;
|
||
|
let pro = gl.createProgram();
|
||
|
for (let i = 0; i < shaders.length; i++) {
|
||
|
gl.attachShader(pro, this.getShader(shaders[i], gl.VERTEX_SHADER));
|
||
|
gl.attachShader(pro, this.getShader(shaders[i], gl.FRAGMENT_SHADER));
|
||
|
}
|
||
|
gl.linkProgram(pro);
|
||
|
var success = gl.getProgramParameter(pro, gl.LINK_STATUS);
|
||
|
if (success) {
|
||
|
this.programs[name] = pro;
|
||
|
return pro;
|
||
|
}
|
||
|
|
||
|
console.log(gl.getProgramInfoLog(pro));
|
||
|
gl.deleteProgram(pro);
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
getProgram(name) {
|
||
|
return this.programs[name];
|
||
|
}
|
||
|
|
||
|
async loadArray(list, path) {
|
||
|
let self = this;
|
||
|
for (const e of list) {
|
||
|
await self.loadShader(e, path)
|
||
|
}
|
||
|
await self.createProgramForEach(list)
|
||
|
}
|
||
|
}
|
||
|
class AudioHandler {
|
||
|
async init() {
|
||
|
this.audioFile = new Audio();
|
||
|
}
|
||
|
}
|
||
|
class Player {
|
||
|
async init() {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
class GUI {
|
||
|
init() {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
class Visual {
|
||
|
constructor() {
|
||
|
this.data = []; //for drawing
|
||
|
this.dataArray = [];
|
||
|
}
|
||
|
draw() {
|
||
|
}
|
||
|
|
||
|
setup() {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class VisualDrawer {
|
||
|
|
||
|
}
|
||
|
class Sphere extends Visual {
|
||
|
draw() {
|
||
|
}
|
||
|
|
||
|
setup() {
|
||
|
}
|
||
|
}
|
||
|
const shaderHandler = new ShaderHandler(null),
|
||
|
audioHandler = new AudioHandler(),
|
||
|
gui = new GUI(),
|
||
|
player = new Player();
|
||
|
|
||
|
async function startUP() {
|
||
|
let c = document.body.querySelector('#c'),
|
||
|
gl = c.getContext("webgl2");
|
||
|
if (!gl) {
|
||
|
alert("SORRY THE BROWSER DOESN'T SUPPORT WEBGL2");
|
||
|
return false;
|
||
|
}
|
||
|
shaderHandler.setGL(gl)
|
||
|
await shaderHandler.loadArray(["wave", "sphere"], 'shaders/');
|
||
|
await audioHandler.init();
|
||
|
await player.init();
|
||
|
gui.init();
|
||
|
}
|
||
|
|
||
|
startUP().then(r => {
|
||
|
setTimeout(e => {
|
||
|
$('.loading-screen').remove();
|
||
|
}, 100)
|
||
|
});
|