performance optimization, reduced face counts.

This commit is contained in:
Michael Mainguy 2024-06-07 08:24:31 -05:00
parent ffe8f60f38
commit 4a95028fe8
3 changed files with 76 additions and 33 deletions

View File

@ -35,6 +35,9 @@ export class DiagramObject {
private _label: AbstractMesh; private _label: AbstractMesh;
private _meshesPresent: boolean = false; private _meshesPresent: boolean = false;
private _positionHash: string; private _positionHash: string;
private _fromMesh: AbstractMesh;
private _toMesh: AbstractMesh;
private _meshRemovedObserver: Observer<AbstractMesh>;
public grabbed: boolean = false; public grabbed: boolean = false;
@ -100,6 +103,11 @@ export class DiagramObject {
if (this._label) { if (this._label) {
this._mesh.computeWorldMatrix(true); this._mesh.computeWorldMatrix(true);
this._mesh.refreshBoundingInfo(); this._mesh.refreshBoundingInfo();
if (this._from && this._to) {
this._label.position.x = .06;
this._label.position.z = .06;
this._label.billboardMode = Mesh.BILLBOARDMODE_Y;
} else {
const top = const top =
this._mesh.getBoundingInfo().boundingBox.maximumWorld; this._mesh.getBoundingInfo().boundingBox.maximumWorld;
const temp = new TransformNode("temp", this._scene); const temp = new TransformNode("temp", this._scene);
@ -109,7 +117,7 @@ export class DiagramObject {
temp.dispose(); temp.dispose();
this._label.position.y = y + .06; this._label.position.y = y + .06;
this._label.billboardMode = Mesh.BILLBOARDMODE_Y; this._label.billboardMode = Mesh.BILLBOARDMODE_Y;
}
} }
} }
@ -148,28 +156,48 @@ export class DiagramObject {
if (!this._baseTransform) { if (!this._baseTransform) {
this._baseTransform = new TransformNode("base-" + this._mesh.id, this._scene); this._baseTransform = new TransformNode("base-" + this._mesh.id, this._scene);
} }
if (this._from && this._to) { 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) { if (!this._sceneObserver) {
this._observingStart = Date.now(); this._observingStart = Date.now();
let tick = 0; let tick = 0;
this._sceneObserver = this._scene.onAfterRenderObservable.add(() => { this._sceneObserver = this._scene.onAfterRenderObservable.add(() => {
tick++; tick++;
if (tick % 5 === 0) { if (tick % 5 === 0) {
if (this._meshesPresent) { if (this._meshesPresent) {
this.updateConnection();
const fromMesh = this._scene.getMeshById(this._from);
const toMesh = this._scene.getMeshById(this._to);
if (fromMesh && toMesh) {
this.updateConnection(fromMesh, toMesh);
}
} else { } else {
const fromMesh = this._scene.getMeshById(this._from); this._fromMesh = this._fromMesh || this._scene.getMeshById(this._from);
const toMesh = this._scene.getMeshById(this._to); this._toMesh = this._toMesh || this._scene.getMeshById(this._to);
if (fromMesh && toMesh) { if (this._fromMesh && this._toMesh) {
this.updateConnection(fromMesh, toMesh); this.updateConnection();
this._meshesPresent = true; this._meshesPresent = true;
} else { } else {
if (Date.now() - this._observingStart > 5000) { if (Date.now() - this._observingStart > 5000) {
@ -178,7 +206,6 @@ export class DiagramObject {
type: DiagramEventType.REMOVE, type: DiagramEventType.REMOVE,
entity: this._diagramEntity entity: this._diagramEntity
}, DiagramEventObserverMask.ALL); }, DiagramEventObserverMask.ALL);
this._scene.onAfterRenderObservable.remove(this._sceneObserver);
this.dispose(); this.dispose();
} }
@ -214,13 +241,16 @@ export class DiagramObject {
this._baseTransform?.dispose(); this._baseTransform?.dispose();
this._diagramEntity = null; this._diagramEntity = null;
this._scene = null; this._scene = null;
this._fromMesh = null;
this._toMesh = null;
this._scene?.onMeshRemovedObservable.remove(this._meshRemovedObserver);
} }
private updateConnection(fromMesh: AbstractMesh, toMesh: AbstractMesh) { private updateConnection() {
this._baseTransform.position = Vector3.Center(fromMesh.getAbsolutePosition().clone(), toMesh.getAbsolutePosition().clone()); this._baseTransform.position = Vector3.Center(this._fromMesh.getAbsolutePosition().clone(), this._toMesh.getAbsolutePosition().clone());
this._baseTransform.lookAt(toMesh.getAbsolutePosition()); this._baseTransform.lookAt(this._toMesh.getAbsolutePosition());
this._mesh.scaling.y = Vector3.Distance(fromMesh.getAbsolutePosition(), toMesh.getAbsolutePosition()); this._mesh.scaling.y = Vector3.Distance(this._fromMesh.getAbsolutePosition(), this._toMesh.getAbsolutePosition());
this._mesh.material = fromMesh.material; this._mesh.material = this._fromMesh.material;
if (!this._mesh.parent) { if (!this._mesh.parent) {
this._mesh.parent = this._baseTransform; this._mesh.parent = this._baseTransform;
} }

View File

@ -50,7 +50,12 @@ function createNewInstanceIfNecessary(entity: DiagramEntity, scene: Scene): Abst
newMesh = buildImage(entity, scene); newMesh = buildImage(entity, scene);
break; break;
case DiagramTemplates.CONNECTION: 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; break;
case DiagramTemplates.BOX: case DiagramTemplates.BOX:
case DiagramTemplates.SPHERE: case DiagramTemplates.SPHERE:

View File

@ -1,13 +1,21 @@
import {ToolType} from "../types/toolType"; import {ToolType} from "../types/toolType";
import {Mesh, MeshBuilder, Scene} from "@babylonjs/core"; import {Mesh, MeshBuilder, Scene} from "@babylonjs/core";
const detail = {
tesselation: 16,
subdivisions: 5
}
export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh { export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh {
switch (type) { switch (type) {
case ToolType.BOX: case ToolType.BOX:
return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, scene); return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, scene);
case ToolType.SPHERE: 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); //return MeshBuilder.CreateSphere(toolname, {diameter: 1}, scene);
case ToolType.CYLINDER: case ToolType.CYLINDER:
@ -15,7 +23,7 @@ export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh
height: 1, height: 1,
diameter: 1, diameter: 1,
subdivisions: 1, subdivisions: 1,
tessellation: 24 tessellation: detail.tesselation
}, scene); }, scene);
case ToolType.CONE: case ToolType.CONE:
@ -24,7 +32,7 @@ export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh
subdivisions: 1, subdivisions: 1,
height: 1, height: 1,
diameterBottom: 1, diameterBottom: 1,
tessellation: 24 tessellation: detail.tesselation
}, scene); }, scene);
case ToolType.PLANE: case ToolType.PLANE: