diff --git a/src/app/pages/algorithms/cloth-icm/cloth-icm-renderer.ts b/src/app/pages/algorithms/cloth-icm/cloth-icm-renderer.ts index caf03e9..61ccb6a 100644 --- a/src/app/pages/algorithms/cloth-icm/cloth-icm-renderer.ts +++ b/src/app/pages/algorithms/cloth-icm/cloth-icm-renderer.ts @@ -1,5 +1,5 @@ import { - ArcRotateCamera, Color3, Color4, LinesMesh, Mesh, MeshBuilder, Scene, ShaderMaterial, StandardMaterial, Vector3, VertexBuffer, VertexData + ArcRotateCamera, Color3, Color4, CreateLineSystemVertexData, LinesMesh, Mesh, MeshBuilder, Scene, ShaderMaterial, StandardMaterial, Vector3, VertexBuffer, VertexData } from '@babylonjs/core'; import {CLOTH_FRAGMENT_SHADER_GLSL, CLOTH_VERTEX_SHADER_GLSL} from '../cloth/cloth-glsl.shader'; import {ClothIcmScene} from './cloth-icm-scenes'; @@ -10,8 +10,8 @@ import {DOP_SIZE} from './collision/dop18'; import {Contour} from './collision/intersection-contours'; import {IntersectionSet} from './collision/intersection-set'; -const CONTOUR_COLOR = new Color3(1, 0.1, 0.1); -const CULLED_COLOR = new Color4(0.2, 0.9, 0.3, 1); +const CONTOUR_COLOR = new Color3(0.1, 1, 0.2); +const CULLED_COLOR = new Color4(0.2, 0.8, 1, 1); const TESTED_COLOR = new Color4(0.6, 0.6, 0.6, 1); const OBSTACLE_COLOR = new Color3(0.35, 0.55, 0.9); const GROUND_SIZE = 8; @@ -35,7 +35,6 @@ export class ClothIcmRenderer { private bvhLines: LinesMesh | null = null; private vertexBuffer = new Float32Array(0); private culledRegion = new Uint8Array(0); - private contourShape: number[] = []; private bvhBoxes: BvhBox[] = []; private bvhPaths: Vector3[][] = []; private bvhPathColors: Color4[][] = []; @@ -67,7 +66,6 @@ export class ClothIcmRenderer { this.obstacles.forEach(mesh => mesh.dispose()); this.obstacleMaterial?.dispose(); this.contourLines = null; - this.contourShape = []; this.bvhLines = null; this.bvhBoxes = []; this.bvhPaths = []; @@ -153,31 +151,26 @@ export class ClothIcmRenderer { /** * The hit points come from the detection, which runs on the predicted positions before the solver moves the cloth, - * so the lines can be a little off the drawn cloth (up to about 0.05 m). Babylon can only update a line system in - * place while every line keeps its point count; otherwise the mesh is rebuilt. + * so the lines can be a little off the drawn cloth (up to about 0.05 m). + * The mesh is created once and gets new geometry every frame. Disposing and creating it again would drop its shader + * (reference counted) and recompile it; the line shader compiles asynchronously, so a mesh whose point layout changes + * every frame (the drop scene) was never ready to draw. */ private updateContourLines(scene: Scene, set: IntersectionSet, contours: Contour[]): void { if (contours.length === 0) { - this.contourLines?.dispose(); - this.contourLines = null; - this.contourShape = []; + this.contourLines?.setEnabled(false); return; } - const lines = contours.map(contour => this.contourPath(set, contour)); - const shape = lines.map(line => line.length); - const existing = this.contourLines; - const sameShape = shape.length === this.contourShape.length && shape.every((length, index) => length === this.contourShape[index]); - if (existing && sameShape) { - MeshBuilder.CreateLineSystem('clothIcmContours', {lines, instance: existing}); - return; + const vertexData = CreateLineSystemVertexData({lines: contours.map(contour => this.contourPath(set, contour))}); + if (!this.contourLines) { + const mesh = new LinesMesh('clothIcmContours', scene); + mesh.color = CONTOUR_COLOR; + mesh.renderingGroupId = OVERLAY_RENDERING_GROUP; + mesh.alwaysSelectAsActiveMesh = true; + this.contourLines = mesh; } - this.contourLines?.dispose(); - const mesh = MeshBuilder.CreateLineSystem('clothIcmContours', {lines, updatable: true}, scene); - mesh.color = CONTOUR_COLOR; - mesh.renderingGroupId = OVERLAY_RENDERING_GROUP; - mesh.alwaysSelectAsActiveMesh = true; - this.contourLines = mesh; - this.contourShape = shape; + vertexData.applyToMesh(this.contourLines, true); + this.contourLines.setEnabled(true); } private contourPath(set: IntersectionSet, contour: Contour): Vector3[] {