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) });