From fbfdaca8f6a8c338ef6381b5d2e000304bce20ea Mon Sep 17 00:00:00 2001 From: alan Date: Wed, 6 Dec 2023 14:13:44 -0500 Subject: [PATCH] Shell rendering --- buildwin.cmd | 2 +- src/client/client.ts | 31 ++++++++++++++++------------ src/client/math/shell.ts | 18 +++++++++++++++- src/client/mesh/import.ts | 2 +- src/client/render/canvas.ts | 41 +++++++++++++++++++++++++++++++++++++ src/client/render/index.ts | 3 +++ 6 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 src/client/render/canvas.ts create mode 100644 src/client/render/index.ts diff --git a/buildwin.cmd b/buildwin.cmd index 630919a..337a059 100644 --- a/buildwin.cmd +++ b/buildwin.cmd @@ -1,4 +1,4 @@ @REM rmdir dist\ @REM mkdir dist\public @REM xcopy .\assets .\dist\public /e /h /y /f -tsc && webpack --config .\webpack\development.js +tsc && webpack --config .\webpack\development.js --watch diff --git a/src/client/client.ts b/src/client/client.ts index fc03f99..25d6daf 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1,4 +1,5 @@ import { Mesh, MeshImport } from "./mesh"; +import { Canvas } from "./render"; const request_mesh_handler = (e: ProgressEvent) => { @@ -14,17 +15,7 @@ const request_mesh_listeners = (xhr: XMLHttpRequest) => { xhr.addEventListener("abort", request_mesh_handler); } -const request_mesh = (filename: string) => { - let request = new XMLHttpRequest(); - request_mesh_listeners(request); - request.onreadystatechange = function() { - if (request.readyState == XMLHttpRequest.DONE) { - console.log(request.responseText); - const mesh = MeshImport.parse(request.responseText); - console.log(`Got mesh array at ${mesh.name}`); - console.log(mesh); - } - } +const request_mesh = (request: XMLHttpRequest, filename: string) => { request.open('GET', `http://localhost:${3000}/mesh/${filename}`, true); request.send(null); return request; @@ -33,5 +24,19 @@ const request_mesh = (filename: string) => { // Wait for page load before executing code window.addEventListener('load', function() { console.log('PAGE LOADED'); - const req = request_mesh('clover.obj'); -}) + + const canvas = new Canvas(this.document.getElementById('draw')); + const req = new XMLHttpRequest(); + + req.onreadystatechange = function() { + if (req.readyState == XMLHttpRequest.DONE) { + console.log(req.responseText); + const mesh = MeshImport.parse(req.responseText); + console.log(`Got mesh array at ${mesh.name}`); + console.log(mesh); + + canvas.draw_shells(mesh.shells); + } + } + request_mesh(req, 'clover.obj'); +}); diff --git a/src/client/math/shell.ts b/src/client/math/shell.ts index 1002588..f8cb561 100644 --- a/src/client/math/shell.ts +++ b/src/client/math/shell.ts @@ -5,6 +5,7 @@ class Shell { public centerpoint: Vector2 = new Vector2(); public rotation: number = 0; public scale: number = 1.0; + public path: Path2D = new Path2D(); constructor(private triangles: Triangle[]) { } @@ -47,7 +48,8 @@ class Shell { this.triangles.push(t); } - public calculate_centerpoint() { + public precompute() { + // First, calculate centerpoint let uvs = Triangle.find_unique_uvs(this.triangles); this.centerpoint = new Vector2(); @@ -56,9 +58,23 @@ class Shell { }); this.centerpoint = Vector2.Divide(this.centerpoint, uvs.length); + // Apply centerpoint to all children this.triangles.forEach((t: Triangle) => { t.set_centerpoint(this.centerpoint); }); + + // Now compute strokes + this.generate_path(); + } + private generate_path() { + this.path = new Path2D(); + + this.triangles.forEach((t: Triangle) => { + this.path.moveTo(t.uvs[0].x, t.uvs[0].y); + this.path.lineTo(t.uvs[1].x, t.uvs[1].y); + this.path.lineTo(t.uvs[2].x, t.uvs[2].y); + this.path.lineTo(t.uvs[0].x, t.uvs[0].y); + }); } } diff --git a/src/client/mesh/import.ts b/src/client/mesh/import.ts index 7b8f7a5..3368f72 100644 --- a/src/client/mesh/import.ts +++ b/src/client/mesh/import.ts @@ -110,7 +110,7 @@ class MeshImport { // Finally, calculate shells shells.forEach((s: Shell) => { - s.calculate_centerpoint(); + s.precompute(); }); // Generate corresponding mesh diff --git a/src/client/render/canvas.ts b/src/client/render/canvas.ts new file mode 100644 index 0000000..9e0a63c --- /dev/null +++ b/src/client/render/canvas.ts @@ -0,0 +1,41 @@ +import { Shell } from '../math'; +import shell from '../math/shell'; + +class Canvas { + protected context: CanvasRenderingContext2D; + constructor(private element: HTMLCanvasElement) { + this.context = element.getContext('2d'); + } + + public clear() { + this.context.clearRect(0, 0, this.element.width, this.element.height); + } + + private transform_base() { + this.context.translate(0, this.element.height); + this.context.scale(this.element.width, -this.element.height); + } + + public draw_shells(shells: Shell[]) { + + this.context.fillStyle = '#888888'; + this.context.lineCap = 'round'; + this.context.lineWidth = 0.0003; + this.context.strokeStyle = '#000000'; + + shells.forEach((s: Shell) => { + this.context.resetTransform(); + this.transform_base(); + this.context.rotate(s.rotation); + this.context.translate(s.centerpoint.x, s.centerpoint.y); + this.context.scale(s.scale, s.scale); + + this.context.fill(s.path); + this.context.stroke(s.path); + }); + + console.log("Canvas drawn"); + } +}; + +export { Canvas as default }; diff --git a/src/client/render/index.ts b/src/client/render/index.ts new file mode 100644 index 0000000..c6e51b4 --- /dev/null +++ b/src/client/render/index.ts @@ -0,0 +1,3 @@ +import Canvas from './canvas'; + +export { Canvas };