diff --git a/main.js b/main.js index f92171d..fcf8068 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,12 @@ -import { Universe, set_panic_hook, default as init } from "./maxwell.js"; +import { Universe, default as init, set_panic_hook as setPanicHook } from "./maxwell.js"; -async function run() { - let wasm = await init("./maxwell_bg.wasm"); - set_panic_hook(); +/** + * Initialises and runs the Maxwell solver, + * plotting the solution to a canvas using webgl + */ +(async function run() { + const wasm = await init("./maxwell_bg.wasm"); + setPanicHook(); const canvas = document.getElementById("glCanvas"); @@ -56,7 +60,7 @@ async function run() { gl.shaderSource(vsShader, vsSource); gl.compileShader(vsShader); if (!gl.getShaderParameter(vsShader, gl.COMPILE_STATUS)) { - console.error('Could not compile shader: ' + gl.getShaderInfoLog(vsShader)); + console.error(`Could not compile shader: ${gl.getShaderInfoLog(vsShader)}`); return; } @@ -64,7 +68,7 @@ async function run() { gl.shaderSource(fsShader, fsSource); gl.compileShader(fsShader); if (!gl.getShaderParameter(fsShader, gl.COMPILE_STATUS)) { - console.error('Could not compile shader: ' + gl.getShaderInfoLog(fsShader)); + console.error(`Could not compile shader: ${gl.getShaderInfoLog(fsShader)}`); return; } @@ -74,12 +78,13 @@ async function run() { gl.linkProgram(shaderProgram); gl.validateProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - console.error('Unable to link shader program: ' + gl.getProgramInfoLog(shaderProgram)) + console.error(`Unable to link shader program: ${gl.getProgramInfoLog(shaderProgram)}`); return; } gl.useProgram(shaderProgram); - gl.clearColor(1.0, 0.753, 0.796, 1.0); // A nice pink to show missing values + // A nice pink to show missing values + gl.clearColor(1.0, 0.753, 0.796, 1.0); gl.clearDepth(1.0); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); @@ -92,17 +97,17 @@ async function run() { const height = 50; - let x = new Float32Array(width*height); - let y = new Float32Array(width*height); - for (let j = 0; j < height; j++) { - for (let i = 0; i < width; i++) { + const x = new Float32Array(width * height); + const y = new Float32Array(width * height); + for (let j = 0; j < height; j += 1) { + for (let i = 0; i < width; i += 1) { const n = width*j + i; x[n] = i / (width - 1.0); y[n] = j / (height - 1.0); } } - const universe = new Universe(width, height); + const universe = new Universe(width, height, x, y); // Transfer x, y to cpu, prepare fBuffer @@ -116,28 +121,28 @@ async function run() { const stride = 0; const offset = 0; - let loc = gl.getAttribLocation(shaderProgram, 'aX'); + let loc = gl.getAttribLocation(shaderProgram, "aX"); gl.bindBuffer(gl.ARRAY_BUFFER, xBuffer); gl.vertexAttribPointer(loc, numcomp, type, normalise, stride, offset); gl.enableVertexAttribArray(loc); gl.bufferData(gl.ARRAY_BUFFER, x, gl.STATIC_DRAW); - loc = gl.getAttribLocation(shaderProgram, 'aY'); + loc = gl.getAttribLocation(shaderProgram, "aY"); gl.bindBuffer(gl.ARRAY_BUFFER, yBuffer); gl.vertexAttribPointer(loc, numcomp, type, normalise, stride, offset); gl.enableVertexAttribArray(loc); gl.bufferData(gl.ARRAY_BUFFER, y, gl.STATIC_DRAW); - loc = gl.getAttribLocation(shaderProgram, 'aField'); + loc = gl.getAttribLocation(shaderProgram, "aField"); gl.bindBuffer(gl.ARRAY_BUFFER, fBuffer); - gl.enableVertexAttribArray(loc); gl.vertexAttribPointer(loc, numcomp, type, normalise, stride, offset); + gl.enableVertexAttribArray(loc); } // Create triangles covering the domain - let positions = new Int16Array((width-1)*(height-1)*2*3); - for (let j = 0; j < height - 1; j++) { - for (let i = 0; i < width - 1; i++) { + const positions = new Int16Array((width-1)*(height-1)*2*3); + for (let j = 0; j < height - 1; j += 1) { + for (let i = 0; i < width - 1; i += 1) { const n = 2*3*((width-1)*j + i); positions[n+0] = width*j + i; positions[n+1] = width*j + i+1; @@ -152,8 +157,8 @@ async function run() { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, positions, gl.STATIC_DRAW); - let bbox = [+Infinity, -Infinity, +Infinity, -Infinity]; - for (let i = 0; i < width*height; i++) { + const bbox = [+Number(Infinity), -Number(Infinity), +Number(Infinity), -Number(Infinity)]; + for (let i = 0; i < width*height; i += 1) { bbox[0] = Math.min(bbox[0], x[i]); bbox[1] = Math.max(bbox[1], x[i]); bbox[2] = Math.min(bbox[2], y[i]); @@ -161,7 +166,7 @@ async function run() { } { - const loc = gl.getUniformLocation(shaderProgram, 'uBbox'); + const loc = gl.getUniformLocation(shaderProgram, "uBbox"); gl.uniform4f(loc, bbox[0], 1.0/(bbox[1] - bbox[0]), bbox[2], 1.0/(bbox[3] - bbox[2])); } @@ -169,38 +174,42 @@ async function run() { const MAX_DT = 2.0/Math.max(width, height); let t = 0; - let first_draw = true; - let warn_time = -1; + let firstDraw = true; + let warnTime = -1; const chosenField = { - uLocation: gl.getUniformLocation(shaderProgram, 'uChosenField'), - value: 0, - cycle: function() { - if (this.value == 0) { + "uLocation": gl.getUniformLocation(shaderProgram, "uChosenField"), + "value": 0, + "cycle": function cycle() { + if (this.value === 0) { this.value = 1; - } else if (this.value == 1) { + } else if (this.value === 1) { this.value = 2; } else { this.value = 0; } gl.uniform1i(this.uLocation, this.value); - }, + } }; chosenField.cycle(); universe.init(0.5, 0.5); - function drawMe(t_draw) { + /** + * Integrates and draws the next iteration + * @param {Time} timeOfDraw Time of drawing + */ + function drawMe(timeOfDraw) { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - let dt = (t_draw - t) / TIMEFACTOR; - t = t_draw; - if (first_draw || dt <= 0.0) { - first_draw = false; + let dt = (timeOfDraw - t) / TIMEFACTOR; + t = timeOfDraw; + if (firstDraw || dt <= 0.0) { + firstDraw = false; dt = MAX_DT; } else { if (dt >= MAX_DT) { - warn_time += 1; - if (warn_time != -2) { + warnTime += 1; + if (warnTime !== -2) { console.warn("Can not keep up with framerate"); } dt = MAX_DT; @@ -209,15 +218,15 @@ async function run() { universe.advance(dt/2); universe.advance(dt/2); - let field_ptr; - if (chosenField.value == 0) { - field_ptr = universe.get_ex_ptr(); - } else if (chosenField.value == 1) { - field_ptr = universe.get_hz_ptr(); + let fieldPtr; + if (chosenField.value === 0) { + fieldPtr = universe.get_ex_ptr(); + } else if (chosenField.value === 1) { + fieldPtr = universe.get_hz_ptr(); } else { - field_ptr = universe.get_ey_ptr(); + fieldPtr = universe.get_ey_ptr(); } - const field = new Float32Array(wasm.memory.buffer, field_ptr, width*height); + const field = new Float32Array(wasm.memory.buffer, fieldPtr, width*height); gl.bufferData(gl.ARRAY_BUFFER, field, gl.DYNAMIC_DRAW); { @@ -238,21 +247,19 @@ async function run() { gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); } - window.addEventListener('keyup', event => { - if (event.key == 'c') { + window.addEventListener("keyup", event => { + if (event.key === "c") { chosenField.cycle(); } - }, {passive: true}); - window.addEventListener('resize', resizeCanvas, false); - window.addEventListener('click', event => { + }, {"passive": true}); + window.addEventListener("resize", resizeCanvas, false); + window.addEventListener("click", event => { // Must adjust for bbox and transformations for x/y const mousex = event.clientX / window.innerWidth; const mousey = event.clientY / window.innerHeight; universe.init(mousex, 1.0 - mousey); - }, {passive: true}); + }, {"passive": true}); resizeCanvas(); window.requestAnimationFrame(drawMe); -} - -run(); +}());