From 4b93e3856e6843b62a3caee6ffa7d1dbd6c33b42 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Fri, 4 Aug 2023 19:22:07 -0500 Subject: [PATCH] Initial commit to persist connections. --- src/app.ts | 7 +- src/diagram/diagramConnection.ts | 135 ++++++++++++++++++++----------- src/diagram/diagramEntity.ts | 3 + src/diagram/diagramManager.ts | 3 + src/diagram/meshConverter.ts | 16 +++- src/menus/editMenu.ts | 4 +- 6 files changed, 114 insertions(+), 54 deletions(-) diff --git a/src/app.ts b/src/app.ts index 2115607..a8d20cb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -38,8 +38,11 @@ export class App { constructor() { const config = AppConfig.config; log.setLevel('info'); - log.getLogger('App').setLevel('debug'); - log.getLogger('PeerjsNetworkConnection').setLevel('debug'); + log.getLogger('App').setLevel('info'); + log.getLogger('IndexdbPersistenceManager').setLevel('info'); + log.getLogger('DiagramManager').setLevel('info'); + + log.getLogger('DiagramConnection').setLevel('debug'); const canvas = document.createElement("canvas"); canvas.style.width = "100%"; canvas.style.height = "100%"; diff --git a/src/diagram/diagramConnection.ts b/src/diagram/diagramConnection.ts index 975855e..60c9161 100644 --- a/src/diagram/diagramConnection.ts +++ b/src/diagram/diagramConnection.ts @@ -7,96 +7,133 @@ import { TransformNode, Vector3 } from "@babylonjs/core"; +import log, {Logger} from "loglevel"; + export class DiagramConnection { - private mesh: GreasedLineMesh; + private logger: Logger = log.getLogger('DiagramConnection'); + + constructor(from: string, to: string, scene?: Scene, pointerInfo?: PointerInfo) { + this.logger.debug('buildConnection constructor'); + this.scene = scene; + this._to = to; + this._from = from; + const fromMesh = this.scene.getMeshById(from); + if (fromMesh) { + this.fromAnchor = fromMesh; + } + const toMesh = this.scene.getMeshById(to); + if (toMesh) { + this.toAnchor = toMesh; + } else { + if (fromMesh) { + this.toAnchor = new TransformNode(this.id + "_to", this.scene); + this.toAnchor.id = this.id + "_to"; + this.toAnchor.position = fromMesh.absolutePosition.clone(); + if (pointerInfo) { + this.toAnchor.setParent(pointerInfo.pickInfo.gripTransform); + } + } + } + this.buildConnection(); + } private readonly scene: Scene; private toAnchor: TransformNode; private fromAnchor: TransformNode; - private pointerInfo: PointerInfo; private points: Vector3[] = []; - constructor(from: string, to: string, id: string, scene: Scene, pointerInfo: PointerInfo) { - this._from = from; - this._to = to; - this._id = id; - this.scene = scene; - this.pointerInfo = pointerInfo; + private _mesh: GreasedLineMesh; - if (from) { - const fromMesh = this.scene.getMeshById(from); - if (fromMesh) { - this.fromAnchor = fromMesh; - this.toAnchor = new TransformNode("toAnchor", this.scene); - this.toAnchor.position = fromMesh.absolutePosition.clone(); - this.toAnchor.setParent(pointerInfo.pickInfo.gripTransform); - - this.buildConnection(); - } - - } + public get mesh(): GreasedLineMesh { + return this._mesh; } - public _from: string; - - public get from(): string { - return this._from; - } - - public set from(value: string) { - this._from = value; - } - - public _to: string; + private _to: string; public get to(): string { - return this._to; + return this?.toAnchor?.id; } public set to(value: string) { if (!value) { return; } - const toMesh = this.scene.getMeshById(value); - if (toMesh) { - const toAnchor = this.toAnchor; - this.toAnchor = toMesh; - toAnchor.dispose(); + const toAnchor = this.scene.getMeshById(value); + if (this.fromAnchor && toAnchor) { + this.toAnchor.dispose(); + this.toAnchor = toAnchor; + this._mesh.metadata.to = this.to; + this._mesh.id = this.id; this.recalculate(); this.setPoints(); - this._to = value; } } - public _id: string; + private _from: string; + + public get from(): string { + return this?.fromAnchor?.id; + } public get id(): string { - return this._id; + return "connection_" + this?.fromAnchor?.id + "_" + this?.toAnchor?.id; } private recalculate() { - //this.fromAnchor.computeWorldMatrix(true); - //this.toAnchor.computeWorldMatrix(true); - this.points = [this.fromAnchor.absolutePosition, this.toAnchor.absolutePosition]; + if (this.fromAnchor && this.toAnchor) { + this.points = [this.fromAnchor.absolutePosition, this.toAnchor.absolutePosition]; + } else { + this.points = [Vector3.Zero(), Vector3.Zero()]; + } + } private setPoints() { - this.mesh.setPoints([GreasedLineTools.ToNumberArray(this.points)]); + if (this.points.length > 1) { + this._mesh.setPoints([GreasedLineTools.ToNumberArray(this.points)]); + } + } private buildConnection() { + this.logger.debug('buildConnection'); + this.logger.debug(this._to); + this.logger.debug(this._from); this.recalculate(); - - this.mesh = CreateGreasedLine("connection", + this._mesh = CreateGreasedLine(this.id, {points: (GreasedLineTools.ToNumberArray(this.points) as number[]), updatable: true}, null, this.scene); - + this._mesh.id = this.id; + if (!this._mesh.metadata) { + this._mesh.metadata = {template: "#connection-template", from: this._from}; + } + if (this._to) { + this.mesh.metadata.to = this.to; + } this.setPoints(); this.scene.onBeforeRenderObservable.add(() => { this.recalculate(); this.setPoints(); }); + this.scene.onNewMeshAddedObservable.add((mesh) => { + if (mesh && mesh.id) { + if (!this.toAnchor || !this.fromAnchor) { + this.logger.debug('render'); + if (mesh?.id == this?._to) { + this.logger.debug("Found to anchor"); + this.toAnchor = mesh; + this._mesh.metadata.to = this.to; + } + if (mesh?.id == this?._from) { + this.logger.debug("Found from anchor"); + this.fromAnchor = mesh; + this._mesh.metadata.from = this.from; + } + } + } + + }, -1, true, this); + return; - //this.mesh.outlineColor = new Color3(0.5, 0.5, 1); } -} \ No newline at end of file +} diff --git a/src/diagram/diagramEntity.ts b/src/diagram/diagramEntity.ts index 53dde5e..9dfb293 100644 --- a/src/diagram/diagramEntity.ts +++ b/src/diagram/diagramEntity.ts @@ -17,6 +17,7 @@ export type DiagramEvent = { type: DiagramEventType; menustate?: EditMenuState; entity?: DiagramEntity; + oldColor?: Color3; newColor?: Color3; @@ -24,6 +25,8 @@ export type DiagramEvent = { export type DiagramEntity = { color?: string; id?: string; + from?: string; + to?: string; last_seen?: Date; position?: Vector3; rotation?: Vector3; diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index e2b432d..79f20bc 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -196,6 +196,9 @@ class DiagramShapePhysics { this.logger.error("applyPhysics: mesh.metadata.template is null", mesh); return; } + if (mesh.metadata.template == '#connector-template') { + return; + } if (!scene) { this.logger.error("applyPhysics: mesh or scene is null"); return; diff --git a/src/diagram/meshConverter.ts b/src/diagram/meshConverter.ts index c4f2782..5233f4a 100644 --- a/src/diagram/meshConverter.ts +++ b/src/diagram/meshConverter.ts @@ -3,6 +3,7 @@ import {AbstractMesh, Color3, InstancedMesh, Mesh, Quaternion, Scene, StandardMa import {v4 as uuidv4} from 'uuid'; import log from "loglevel"; import {TextLabel} from "./textLabel"; +import {DiagramConnection} from "./diagramConnection"; export class MeshConverter { private static logger = log.getLogger('MeshConverter'); @@ -18,10 +19,13 @@ export class MeshConverter { } entity.id = mesh.id; entity.position = mesh.position; + entity.rotation = mesh.rotation; entity.last_seen = new Date(); entity.template = mesh?.metadata?.template; entity.text = mesh?.metadata?.text; + entity.from = mesh?.metadata?.from; + entity.to = mesh?.metadata?.to; entity.scale = mesh.scaling; if (mesh.material) { entity.color = (mesh.material as any).diffuseColor.toHexString(); @@ -38,10 +42,14 @@ export class MeshConverter { if (!entity.id) { entity.id = "id" + uuidv4(); } - let mesh = scene.getMeshById(entity.id); + let mesh: AbstractMesh = scene.getMeshById(entity.id); if (mesh) { log.debug('mesh already exists'); } else { + if (entity.template == "#connection-template") { + const connection: DiagramConnection = new DiagramConnection(entity.from, entity.to, scene); + + } mesh = scene.getMeshById("tool-" + entity.template + "-" + entity.color); if (mesh) { if (mesh.isAnInstance) { @@ -80,6 +88,12 @@ export class MeshConverter { mesh.metadata.text = entity.text; TextLabel.updateTextNode(mesh, entity.text); } + if (entity.from) { + mesh.metadata.from = entity.from; + } + if (entity.to) { + mesh.metadata.to = entity.to; + } } else { this.logger.error("fromDiagramEntity: mesh is null after it should have been created"); } diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index 83a1b5a..4794cdb 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -133,11 +133,11 @@ export class EditMenu { this.connection.to = mesh.id; this.diagramManager.onDiagramEventObservable.notifyObservers({ type: DiagramEventType.ADD, - entity: this.connection, + entity: MeshConverter.toDiagramEntity(this.connection.mesh) }); this.connection = null; } else { - this.connection = new DiagramConnection(mesh.id, null, null, this.scene, pointerInfo); + this.connection = new DiagramConnection(mesh.id, null, this.scene, pointerInfo); } }