From 9c97b8172726413e65a06581114602b5f720a3f4 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Tue, 8 Aug 2023 09:22:55 -0500 Subject: [PATCH] Added Ability to recolor instances. --- src/app.ts | 3 +- src/diagram/diagramManager.ts | 11 +++--- src/menus/MenuState.ts | 4 ++- src/menus/editMenu.ts | 66 ++++++++++++++++++++++++++++------- src/toolbox/toolbox.ts | 10 ++++-- 5 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/app.ts b/src/app.ts index 8d01090..09ffccc 100644 --- a/src/app.ts +++ b/src/app.ts @@ -24,7 +24,7 @@ export class App { constructor() { const config = AppConfig.config; const logger = log.getLogger('App'); - log.disableAll(); + log.setDefaultLevel('info'); log.getLogger('App').setLevel('info'); @@ -33,6 +33,7 @@ export class App { //log.getLogger('DiagramConnection').setLevel('debug'); log.getLogger('DrawioManager').setLevel('debug'); + log.getLogger('EditMenu').setLevel('debug'); const canvas = document.createElement("canvas"); canvas.style.width = "100%"; canvas.style.height = "100%"; diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index 90d53d8..681002d 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -136,7 +136,7 @@ export class DiagramManager { if (entity) { mesh = this.scene.getMeshById(entity.id); } - if (!mesh) { + if (!mesh && event?.entity?.template) { const toolMesh = this.scene.getMeshById("tool-" + event.entity.template + "-" + event.entity.color); if (!toolMesh) { log.debug('no mesh found for ' + event.entity.template + "-" + event.entity.color, 'adding it'); @@ -145,13 +145,16 @@ export class DiagramManager { entity: event.entity }); } - mesh = MeshConverter.fromDiagramEntity(event.entity, this.scene); - mesh.actionManager = this.actionManager; - DiagramShapePhysics.applyPhysics(mesh, this.scene, PhysicsMotionType.DYNAMIC); + if (mesh) { + mesh.actionManager = this.actionManager; + DiagramShapePhysics.applyPhysics(mesh, this.scene, PhysicsMotionType.DYNAMIC); + } + } switch (event.type) { case DiagramEventType.CLEAR: + break; case DiagramEventType.DROPPED: break; diff --git a/src/menus/MenuState.ts b/src/menus/MenuState.ts index 7cc922f..9d8089d 100644 --- a/src/menus/MenuState.ts +++ b/src/menus/MenuState.ts @@ -4,6 +4,8 @@ export enum EditMenuState { MODIFYING, // Editing an entity REMOVING, COPYING, // Removing an entity - CONNECTING + CONNECTING, + RECOLORING + } \ No newline at end of file diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index 7152614..252c4d5 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -1,9 +1,13 @@ import { AbstractMesh, + Color3, GizmoManager, + InstancedMesh, + Mesh, PointerEventTypes, PointerInfo, Scene, + StandardMaterial, Vector3, WebXRExperienceHelper } from "@babylonjs/core"; @@ -24,6 +28,7 @@ export class EditMenu { private state: EditMenuState = EditMenuState.NONE; private manager: GUI3DManager; private readonly scene: Scene; + private paintColor: string = null; private readonly logger: log.Logger = log.getLogger('EditMenu'); private gizmoManager: GizmoManager; private readonly xr: WebXRExperienceHelper; @@ -55,6 +60,13 @@ export class EditMenu { }); break; } else { + const tool = pickedMesh?.metadata?.tool; + if (tool) { + this.logger.debug("tool type", tool); + this.paintColor = (pickedMesh.material as StandardMaterial).diffuseColor.toHexString(); + this.logger.debug((pickedMesh.material as StandardMaterial).diffuseColor.toHexString()); + this.logger.debug(pickedMesh.id); + } } } @@ -77,6 +89,7 @@ export class EditMenu { panel.addControl(this.makeButton("Copy", "copy")); panel.addControl(this.makeButton("Connect", "connect")); panel.addControl(this.makeButton("Export", "export")); + panel.addControl(this.makeButton("Recolor", "recolor")); //panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras")); this.manager.controlScaling = .5; @@ -84,6 +97,11 @@ export class EditMenu { } } + private getTool(template: string, color: Color3): Mesh { + const baseMeshId = 'tool-' + template + '-' + color.toHexString(); + return (this.scene.getMeshById(baseMeshId) as Mesh); + } + private persist(mesh: AbstractMesh, text: string) { if (mesh.metadata) { mesh.metadata.text = text; @@ -116,24 +134,43 @@ export class EditMenu { } switch (this.state) { case EditMenuState.REMOVING: - this.remove(mesh); + this.removeMesh(mesh); break; case EditMenuState.MODIFYING: - this.setModify(mesh); + this.modifyMesh(mesh); break; case EditMenuState.LABELING: - this.setLabeling(mesh); + this.labelMesh(mesh); break; case EditMenuState.COPYING: - this.setCopying(mesh); + this.copyMesh(mesh); break; case EditMenuState.CONNECTING: - this.setConnecting(mesh, pointerInfo); + this.createMeshConnection(mesh, pointerInfo); break; + case EditMenuState.RECOLORING: + if (this.paintColor) { + const template = mesh.metadata.template; + const newBase = this.getTool(template, + Color3.FromHexString(this.paintColor)); + const newMesh = (mesh as InstancedMesh).clone(mesh.name, mesh.parent, false, newBase); + newMesh.id = mesh.id; + newMesh.physicsBody = mesh.physicsBody; + newMesh.metadata = mesh.metadata; + mesh.physicsBody = null; + mesh.dispose(); + this.diagramManager.onDiagramEventObservable.notifyObservers({ + type: DiagramEventType.MODIFY, + entity: MeshConverter.toDiagramEntity(newMesh) + }); + + } else { + this.logger.error("no paint color selectced"); + } } } - private setConnecting(mesh: AbstractMesh, pointerInfo) { + private createMeshConnection(mesh: AbstractMesh, pointerInfo) { if (this.connection) { this.connection.to = mesh.id; this.diagramManager.onDiagramEventObservable.notifyObservers({ @@ -146,7 +183,7 @@ export class EditMenu { } } - private remove(mesh: AbstractMesh) { + private removeMesh(mesh: AbstractMesh) { this.logger.debug("removing " + mesh?.id); const event: DiagramEvent = { type: DiagramEventType.REMOVE, @@ -156,7 +193,7 @@ export class EditMenu { this.diagramManager.onDiagramEventObservable.notifyObservers(event); } - private setModify(mesh: AbstractMesh) { + private modifyMesh(mesh: AbstractMesh) { if (mesh.metadata?.template && mesh.parent?.parent?.id != "toolbox") { if (this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh?.id == mesh.id) { @@ -165,8 +202,8 @@ export class EditMenu { this.gizmoManager.attachToMesh(mesh); this.gizmoManager.gizmos.boundingBoxGizmo.onScaleBoxDragObservable.add(() => { this.diagramManager.onDiagramEventObservable.notifyObservers({ - type: DiagramEventType.MODIFY, - entity: MeshConverter.toDiagramEntity(mesh), + type: DiagramEventType.MODIFY, + entity: MeshConverter.toDiagramEntity(mesh), } ) this.logger.debug(mesh.scaling); @@ -175,16 +212,16 @@ export class EditMenu { } } - private setCopying(mesh: AbstractMesh) { + private copyMesh(mesh: AbstractMesh) { if (mesh) { const newMesh = this.diagramManager.createCopy(mesh, true); - newMesh.setParent(null); + newMesh.setParent(mesh.parent); } this.logger.warn('copying not implemented', mesh); //@todo implement } - private setLabeling(mesh: AbstractMesh) { + private labelMesh(mesh: AbstractMesh) { this.logger.debug("labeling " + mesh.id); let text = ""; if (mesh?.metadata?.text) { @@ -216,6 +253,9 @@ export class EditMenu { case "connect": this.state = EditMenuState.CONNECTING; break; + case "recolor": + this.state = EditMenuState.RECOLORING; + break; case "export": GLTF2Export.GLTFAsync(this.scene, 'diagram.gltf', { shouldExportNode: function (node) { diff --git a/src/toolbox/toolbox.ts b/src/toolbox/toolbox.ts index 75e5e8b..cb4e9d2 100644 --- a/src/toolbox/toolbox.ts +++ b/src/toolbox/toolbox.ts @@ -84,7 +84,7 @@ export class Toolbox { public buildTool(tool: ToolType, parent: AbstractMesh) { let newItem: Mesh; - const id = tool + "-" + (parent.material as StandardMaterial).diffuseColor.toHexString(); + const id = this.toolId(tool, (parent.material as StandardMaterial).diffuseColor); const material = parent.material; const toolname = "tool-" + id; switch (tool) { @@ -108,7 +108,7 @@ export class Toolbox { } if (newItem) { newItem.material = material; - newItem.id = "tool-" + id; + newItem.id = toolname if (tool === ToolType.PLANE) { newItem.material.backFaceCulling = false; } @@ -120,6 +120,7 @@ export class Toolbox { if (!newItem.material) { newItem.material = parent.material; } + if (newItem.metadata) { newItem.metadata.template = tool; } else { @@ -141,6 +142,10 @@ export class Toolbox { return null; } } + + private toolId(tool: ToolType, color: Color3) { + return tool + "-" + color.toHexString(); + } private calculatePosition(i: number) { return (i/this.gridsize)-.5-(1/this.gridsize/2); } @@ -186,6 +191,7 @@ export class Toolbox { mesh.material = material; mesh.position.z = this.index++/4; mesh.parent = this.node; + mesh.metadata = {tool: 'color'}; let i = 0; for (const tool of enumKeys(ToolType)) { const newItem = this.buildTool(ToolType[tool], mesh);