Fix some issues, add the mesh rendering. General code improvements

This commit is contained in:
Clément Pons 2022-12-12 17:37:35 +01:00
parent e4217d3f4d
commit 0410e3d709
4 changed files with 119 additions and 48 deletions

View File

@ -1,9 +1,11 @@
import { Thread, supportThreads } from "./utils/workerUtils.mjs";
import Renderer from "./modules/renderer/renderer.mjs";
import Noise from '../libs/alea.mjs'
import Delaunator from 'https://cdn.skypack.dev/delaunator@5.0.0';
(async function()
{
globalThis.DEBUG = localStorage.getItem("debug");
globalThis.DEBUG = !!localStorage.getItem("debug");
globalThis.VERBOSE = DEBUG && localStorage.getItem("verbose");
globalThis.TIMINGS = DEBUG && localStorage.getItem("timings");
globalThis.RELEASE = !DEBUG;
@ -11,15 +13,17 @@ import Renderer from "./modules/renderer/renderer.mjs";
const thread = new Thread("./workers/base.mjs", "model", true);
await thread.setup();
const settings = { x: 200, y: 200, seed: 0, jitter: 0.5, width: window.innerWidth, height: window.innerHeight };
await thread.model.generatePoints(settings);
await thread.model.generateTriangles(settings);
//await new Promise(r => setTimeout(r, 3000));
const delaunay = await thread.debug.getDelaunay();
console.log(delaunay);
const settings = { model: { x: 50, y: 25, seed: 0, jitter: 0.2, }, view: { width: window.innerWidth, height: window.innerHeight, }, };
await thread.global.updateSettings(settings);
const view = new Float32Array(await thread.view.lerpToViewport(settings));
await thread.model.generateTriangles();
const view = await thread.view.lerpToViewport();
const debug = await thread.debug.getAll();
Renderer.init();
Renderer.initGrid(view, settings);
Renderer.initGrid(view.position, view.vertices);
})();

View File

@ -23,8 +23,11 @@ class Renderer
this._width = window.innerWidth;
this._height = window.innerHeight;
this._clock = new Three.Clock();
this._scene = new Three.Scene();
this._camera = new Three.OrthographicCamera(this._width / - 2, this._width / 2, this._height / 2, this._height / - 2, 0.1, 1000);
this._camera = new Three.OrthographicCamera(0, this._width, 0, this._height, 0.1, 1000);
this._camera.zoom = 0.98;
this._camera.updateProjectionMatrix();
Renderer.render();
}
@ -36,22 +39,30 @@ class Renderer
this._rAF = requestAnimationFrame(Renderer.render.bind(Renderer));
/*this._camera.zoom = 1 + (0.5 + Math.sin(this._clock.getElapsedTime()) / 2) * 5;
this._camera.updateProjectionMatrix();*/
this._renderer.render(this._scene, this._camera);
}
static async initGrid(grid, settings) //Share the list of cell and the resolution in the model with the view
static async initGrid(position, vertices) //Share the list of cell and the resolution in the model with the view
{
if(this._threaded)
{
//We can share the cells with the rendering thread because it will only be used as read-only to create the point data
await this._renderer_thread.view.lerpToView(grid, settings);
await this._renderer_thread.view.lerpToView(position, settings);
}
else
{
const geometry = new Three.BufferGeometry();
geometry.setAttribute('position', new Three.Float32BufferAttribute(grid, 3));
geometry.setIndex( new Three.Uint32BufferAttribute( vertices, 1 ) );
geometry.setAttribute('position', new Three.Float32BufferAttribute( position, 3));
const points = new Three.Points(geometry);
this._scene.add(points);
const material = new Three.MeshBasicMaterial( { color: 0xff0000, wireframe: true, } );
const mesh = new Three.Mesh( geometry, material );
this._scene.add( mesh );
/*const points = new Three.Points( geometry, new Three.PointsMaterial( { size: 3.0 } ) );
this._scene.add( points );*/
}
}
}

View File

@ -9,12 +9,13 @@ const Constants = {
WAITING: 1,
OK: 2,
ERROR: 3,
LOG: 4,
},
REQUEST: {
WAKEUP: 1,
SETUP: 2,
CALL: 3,
TERMINATE: 4,
TERMINATE: 4
},
TRANSFERABLE: [
ArrayBuffer,
@ -101,6 +102,17 @@ function wrapper(thread, mod, fn)
function onmessage(thread)
{
return function(e) {
if(e.data[0] === Constants.STATE.LOG)
{
globalThis.VERBOSE && console.debug(ret);
return;
}
if(e.data[0] === Constants.STATE.ERROR)
{
console.error(e.data[1]);
return;
}
const ret = parseReturns(e.data);
globalThis.VERBOSE && console.debug(`Received message from ${thread._name} containing `, ret);
globalThis.TIMINGS && thread._calledFn !== "" && console.timeEnd("Measuring " + thread._calledMod + "." + thread._calledFn);
@ -178,6 +190,16 @@ function send(ret)
postMessage([Constants.STATE.OK, ret], getTransferables(ret));
}
function error(err)
{
postMessage([Constants.STATE.ERROR, err]);
}
function log(msg)
{
postMessage([Constants.STATE.LOG, msg]);
}
class Process
{
static _isSetup = false;
@ -187,10 +209,11 @@ class Process
Process._isSetup = true;
Process._customFn = {};
globalThis.onmessage = Process.onmessage;
globalThis.onerror = Process.onerror;
}
static onmessage(e)
{
globalThis.VERBOSE && console.debug(`Received `, e.data);
globalThis.VERBOSE && log(`Received `, e.data);
if(e && e.data)
{
switch(e.data[0])
@ -210,7 +233,14 @@ class Process
case Constants.REQUEST.CALL:
const args = e.data[3];
send(Process._customFn[e.data[1]][e.data[2]](...args));
try
{
send(Process._customFn[e.data[1]][e.data[2]](...args));
}
catch(e)
{
error(e);
}
break;
case Constants.REQUEST.TERMINATE:

View File

@ -4,33 +4,37 @@ import Delaunator from 'https://cdn.skypack.dev/delaunator@5.0.0';
let settings = {};
const model = {};
const view = {};
//Settings contains x, y, seed, jitter
function generatePoints(settings)
function lerp(a, b, x)
{
const noise = Noise(settings.seed);
const grid = new Float32Array(settings.x * settings.y * 2);
return a + (b - a) * x;
}
function inverse_lerp(a, b, x)
{
return (x - a) / (b - a);
}
//Settings model contains x, y, seed, jitter
function generateTriangles()
{
const rand = Noise(settings.model.seed);
const grid = new Float32Array(settings.model.x * settings.model.y * 2);
for(let i = grid.length * 2 - 2; i > 0; i -= 2)
{
const _x = i / 2 % settings.x;
const _y = (i / 2 - _x) / settings.x;
const _x = i / 2 % settings.model.x;
const _y = (i / 2 - _x) / settings.model.x;
grid[i] = _x + (noise() - 0.5) * settings.jitter;
grid[i + 1] = _y + (noise() - 0.5) * settings.jitter;
const angle = lerp(0, Math.PI * 2, rand());
const magnitude = lerp(0, settings.model.jitter, rand());
grid[i ] = _x + Math.sin(angle) * magnitude;
grid[i + 1] = _y + Math.cos(angle) * magnitude;
}
model.grid = grid;
model.delaunay = new Delaunator(grid);
}
function generateTriangles(settings)
{
if(!model.hasOwnProperty("grid"))
generatePoints(settings);
const delaunay = new Delaunator(model.grid);
model.delaunay = delaunay;
}
function generateVoronoi(settings)
function generateVoronoi()
{
function circumcenter(a, b, c)
{
@ -44,30 +48,52 @@ function generateVoronoi(settings)
];
}
const coords = model.delaunay.coords;
const tri = model.delaunay.triangles;
for(let i = model.delaunay.trianglesLen - 1; i >= 0; --i)
{
tri[]
}
}
function getDelaunay()
{
return model.delaunay;
}
function lerpToViewport(settings)
function getAll()
{
const size = settings.x * settings.y;
const grid = model.grid;
const view = new Float32Array(size * 3);
return { model: model, view: view };
}
//Settings view contains width & height
function lerpToViewport()
{
const size = settings.model.x * settings.model.y;
const grid = model.delaunay.coords;
view.grid = new Float32Array(size * 3);
for(let i = size - 1; i >= 0; --i)
{
view[i * 3] = settings.width * grid[i * 2] / settings.x - settings.width / 2;
view[i * 3 + 1] = settings.height * grid[i * 2 + 1] / settings.y - settings.height / 2;
view[i * 3 + 2] = -3;
view.grid[i * 3 ] = lerp(0, settings.view.width , inverse_lerp(0, settings.model.x - 1, grid[i * 2 ]));
view.grid[i * 3 + 1] = lerp(0, settings.view.height, inverse_lerp(0, settings.model.y - 1, grid[i * 2 + 1]));
view.grid[i * 3 + 2] = -3;
}
return view.buffer;
return { position: view.grid, vertices: model.delaunay.triangles };
}
//Process.register is the equivalent of export
Process.register("model", [generatePoints, generateTriangles]);
Process.register("model", [generateTriangles]);
Process.register("view", [lerpToViewport]);
Process.register("debug", [getDelaunay]);
function updateSettings(s)
{
const old_settings = settings;
settings = s;
//Check which property has change and regenerate the appropriate objects.
}
Process.register("global", [updateSettings]);
Process.register("debug", [getDelaunay, getAll]);