From 4a95028fe8f777a1e3c4284dc2fc212aa58e00f6 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Fri, 7 Jun 2024 08:24:31 -0500 Subject: [PATCH] performance optimization, reduced face counts. --- src/diagram/diagramObject.ts | 88 +++++++++++++------ .../functions/buildMeshFromDiagramEntity.ts | 7 +- src/toolbox/functions/buildMesh.ts | 14 ++- 3 files changed, 76 insertions(+), 33 deletions(-) diff --git a/src/diagram/diagramObject.ts b/src/diagram/diagramObject.ts index 41ec1cb..3f57d91 100644 --- a/src/diagram/diagramObject.ts +++ b/src/diagram/diagramObject.ts @@ -35,6 +35,9 @@ export class DiagramObject { private _label: AbstractMesh; private _meshesPresent: boolean = false; private _positionHash: string; + private _fromMesh: AbstractMesh; + private _toMesh: AbstractMesh; + private _meshRemovedObserver: Observer; public grabbed: boolean = false; @@ -100,16 +103,21 @@ export class DiagramObject { if (this._label) { this._mesh.computeWorldMatrix(true); this._mesh.refreshBoundingInfo(); - const top = - this._mesh.getBoundingInfo().boundingBox.maximumWorld; - const temp = new TransformNode("temp", this._scene); - temp.position = top; - temp.setParent(this._baseTransform); - const y = temp.position.y; - temp.dispose(); - this._label.position.y = y + .06; - this._label.billboardMode = Mesh.BILLBOARDMODE_Y; - + if (this._from && this._to) { + this._label.position.x = .06; + this._label.position.z = .06; + this._label.billboardMode = Mesh.BILLBOARDMODE_Y; + } else { + const top = + this._mesh.getBoundingInfo().boundingBox.maximumWorld; + const temp = new TransformNode("temp", this._scene); + temp.position = top; + temp.setParent(this._baseTransform); + const y = temp.position.y; + temp.dispose(); + this._label.position.y = y + .06; + this._label.billboardMode = Mesh.BILLBOARDMODE_Y; + } } } @@ -148,28 +156,48 @@ export class DiagramObject { if (!this._baseTransform) { this._baseTransform = new TransformNode("base-" + this._mesh.id, this._scene); } - if (this._from && this._to) { + if (!this._meshRemovedObserver) { + this._meshRemovedObserver = this._scene.onMeshRemovedObservable.add((mesh) => { + if (mesh && mesh.id) { + switch (mesh.id) { + case this._from: + this._fromMesh = null; + this._meshesPresent = false; + this._eventObservable.notifyObservers({ + type: DiagramEventType.REMOVE, + entity: this._diagramEntity + }, DiagramEventObserverMask.ALL); + this.dispose(); + break; + case this._to: + this._toMesh = null; + this._meshesPresent = false; + this._eventObservable.notifyObservers({ + type: DiagramEventType.REMOVE, + entity: this._diagramEntity + }, DiagramEventObserverMask.ALL); + this.dispose(); + } + } + + + }, -1, false, this); + } if (!this._sceneObserver) { this._observingStart = Date.now(); let tick = 0; this._sceneObserver = this._scene.onAfterRenderObservable.add(() => { + tick++; if (tick % 5 === 0) { if (this._meshesPresent) { - - const fromMesh = this._scene.getMeshById(this._from); - const toMesh = this._scene.getMeshById(this._to); - - if (fromMesh && toMesh) { - this.updateConnection(fromMesh, toMesh); - } - + this.updateConnection(); } else { - const fromMesh = this._scene.getMeshById(this._from); - const toMesh = this._scene.getMeshById(this._to); - if (fromMesh && toMesh) { - this.updateConnection(fromMesh, toMesh); + this._fromMesh = this._fromMesh || this._scene.getMeshById(this._from); + this._toMesh = this._toMesh || this._scene.getMeshById(this._to); + if (this._fromMesh && this._toMesh) { + this.updateConnection(); this._meshesPresent = true; } else { if (Date.now() - this._observingStart > 5000) { @@ -178,7 +206,6 @@ export class DiagramObject { type: DiagramEventType.REMOVE, entity: this._diagramEntity }, DiagramEventObserverMask.ALL); - this._scene.onAfterRenderObservable.remove(this._sceneObserver); this.dispose(); } @@ -214,13 +241,16 @@ export class DiagramObject { this._baseTransform?.dispose(); this._diagramEntity = null; this._scene = null; + this._fromMesh = null; + this._toMesh = null; + this._scene?.onMeshRemovedObservable.remove(this._meshRemovedObserver); } - private updateConnection(fromMesh: AbstractMesh, toMesh: AbstractMesh) { - this._baseTransform.position = Vector3.Center(fromMesh.getAbsolutePosition().clone(), toMesh.getAbsolutePosition().clone()); - this._baseTransform.lookAt(toMesh.getAbsolutePosition()); - this._mesh.scaling.y = Vector3.Distance(fromMesh.getAbsolutePosition(), toMesh.getAbsolutePosition()); - this._mesh.material = fromMesh.material; + private updateConnection() { + this._baseTransform.position = Vector3.Center(this._fromMesh.getAbsolutePosition().clone(), this._toMesh.getAbsolutePosition().clone()); + this._baseTransform.lookAt(this._toMesh.getAbsolutePosition()); + this._mesh.scaling.y = Vector3.Distance(this._fromMesh.getAbsolutePosition(), this._toMesh.getAbsolutePosition()); + this._mesh.material = this._fromMesh.material; if (!this._mesh.parent) { this._mesh.parent = this._baseTransform; } diff --git a/src/diagram/functions/buildMeshFromDiagramEntity.ts b/src/diagram/functions/buildMeshFromDiagramEntity.ts index 432e8f9..d318c6b 100644 --- a/src/diagram/functions/buildMeshFromDiagramEntity.ts +++ b/src/diagram/functions/buildMeshFromDiagramEntity.ts @@ -50,7 +50,12 @@ function createNewInstanceIfNecessary(entity: DiagramEntity, scene: Scene): Abst newMesh = buildImage(entity, scene); break; case DiagramTemplates.CONNECTION: - newMesh = MeshBuilder.CreateCylinder(entity.id, {diameter: .025, height: 1}, scene); + newMesh = MeshBuilder.CreateCylinder(entity.id, { + diameterBottom: .04, + height: 1, + diameterTop: .004, + tessellation: 3 + }, scene); break; case DiagramTemplates.BOX: case DiagramTemplates.SPHERE: diff --git a/src/toolbox/functions/buildMesh.ts b/src/toolbox/functions/buildMesh.ts index ec6d95e..5a7f72e 100644 --- a/src/toolbox/functions/buildMesh.ts +++ b/src/toolbox/functions/buildMesh.ts @@ -1,13 +1,21 @@ import {ToolType} from "../types/toolType"; import {Mesh, MeshBuilder, Scene} from "@babylonjs/core"; +const detail = { + tesselation: 16, + subdivisions: 5 +} export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh { switch (type) { case ToolType.BOX: return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, scene); case ToolType.SPHERE: - return MeshBuilder.CreateIcoSphere(toolname, {subdivisions: 6, radius: .5, flat: false}, scene); + return MeshBuilder.CreateIcoSphere(toolname, { + subdivisions: detail.subdivisions, + radius: .5, + flat: false + }, scene); //return MeshBuilder.CreateSphere(toolname, {diameter: 1}, scene); case ToolType.CYLINDER: @@ -15,7 +23,7 @@ export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh height: 1, diameter: 1, subdivisions: 1, - tessellation: 24 + tessellation: detail.tesselation }, scene); case ToolType.CONE: @@ -24,7 +32,7 @@ export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh subdivisions: 1, height: 1, diameterBottom: 1, - tessellation: 24 + tessellation: detail.tesselation }, scene); case ToolType.PLANE: