Initial Connector Commit.

This commit is contained in:
Michael Mainguy 2023-08-04 06:38:41 -05:00
parent 6544cd866d
commit 4f4874d66f
3 changed files with 122 additions and 2 deletions

View File

@ -88,11 +88,29 @@ export class DiagramManager {
newMesh.scaling = AppConfig.config.createSnapVal; newMesh.scaling = AppConfig.config.createSnapVal;
} }
newMesh.material = mesh.material; newMesh.material = mesh.material;
newMesh.metadata = mesh.metadata; const metaCopy = this.deepCopy(mesh.metadata);
newMesh.metadata = metaCopy;
DiagramShapePhysics.applyPhysics(newMesh, this.scene); DiagramShapePhysics.applyPhysics(newMesh, this.scene);
return newMesh; return newMesh;
} }
private deepCopy<T, U = T extends Array<infer V> ? V : never>(source: T): T {
if (Array.isArray(source)) {
return source.map(item => (this.deepCopy(item))) as T & U[]
}
if (source instanceof Date) {
return new Date(source.getTime()) as T & Date
}
if (source && typeof source === 'object') {
return (Object.getOwnPropertyNames(source) as (keyof T)[]).reduce<T>((o, prop) => {
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop)!)
o[prop] = this.deepCopy(source[prop])
return o
}, Object.create(Object.getPrototypeOf(source)))
}
return source
}
private onRemoteEvent(event: DiagramEntity) { private onRemoteEvent(event: DiagramEntity) {
this.logger.debug(event); this.logger.debug(event);
const toolMesh = this.scene.getMeshById("tool-" + event.template + "-" + event.color); const toolMesh = this.scene.getMeshById("tool-" + event.template + "-" + event.color);

View File

@ -3,6 +3,7 @@ export enum EditMenuState {
LABELING, LABELING,
MODIFYING, // Editing an entity MODIFYING, // Editing an entity
REMOVING, REMOVING,
COPYING // Removing an entity COPYING, // Removing an entity
CONNECTING
} }

View File

@ -1,9 +1,13 @@
import { import {
AbstractMesh, AbstractMesh,
CreateGreasedLine,
GizmoManager, GizmoManager,
GreasedLineMesh,
GreasedLineTools,
PointerEventTypes, PointerEventTypes,
PointerInfo, PointerInfo,
Scene, Scene,
TransformNode,
Vector3, Vector3,
WebXRExperienceHelper WebXRExperienceHelper
} from "@babylonjs/core"; } from "@babylonjs/core";
@ -18,6 +22,82 @@ import {DiaSounds} from "../util/diaSounds";
import {CameraHelper} from "../util/cameraHelper"; import {CameraHelper} from "../util/cameraHelper";
import {TextLabel} from "../diagram/textLabel"; import {TextLabel} from "../diagram/textLabel";
class DiagramConnection {
private mesh: GreasedLineMesh;
private readonly scene: Scene;
private readonly fromPoint: Vector3 = new Vector3();
private readonly toPoint: Vector3 = new Vector3();
private toAnchor: 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;
if (from) {
const fromPoint = this.scene.getMeshById(from).getAbsolutePosition().clone();
this.fromPoint.copyFrom(fromPoint);
this.toAnchor = new TransformNode("toAnchor", this.scene);
this.toAnchor.position = fromPoint;
this.toAnchor.setParent(pointerInfo.pickInfo.gripTransform);
this.buildConnection();
}
}
public _from: string;
public get from(): string {
return this._from;
}
public set from(value: string) {
this._from = value;
}
public _to: string;
public get to(): string {
return this._to;
}
public set to(value: string) {
this._to = value;
}
public _id: string;
public get id(): string {
return this._id;
}
private recalculate() {
this.points = [this.fromPoint, this.toAnchor.absolutePosition];
}
private setPoints() {
this.mesh.setPoints([GreasedLineTools.ToNumberArray(this.points)]);
}
private buildConnection() {
this.scene.onBeforeRenderObservable.add(() => {
this.recalculate();
this.setPoints();
});
this.recalculate();
this.mesh = CreateGreasedLine("connection",
{points: (GreasedLineTools.ToNumberArray(this.points) as number[]), updatable: true}, null, this.scene);
this.setPoints();
//this.mesh.outlineColor = new Color3(0.5, 0.5, 1);
}
}
export class EditMenu { export class EditMenu {
private state: EditMenuState = EditMenuState.NONE; private state: EditMenuState = EditMenuState.NONE;
private manager: GUI3DManager; private manager: GUI3DManager;
@ -26,6 +106,7 @@ export class EditMenu {
private gizmoManager: GizmoManager; private gizmoManager: GizmoManager;
private readonly xr: WebXRExperienceHelper; private readonly xr: WebXRExperienceHelper;
private readonly diagramManager: DiagramManager; private readonly diagramManager: DiagramManager;
private connection: DiagramConnection = null;
constructor(scene: Scene, xr: WebXRExperienceHelper, diagramManager: DiagramManager) { constructor(scene: Scene, xr: WebXRExperienceHelper, diagramManager: DiagramManager) {
this.scene = scene; this.scene = scene;
@ -69,6 +150,7 @@ export class EditMenu {
panel.addControl(this.makeButton("Remove", "remove")); panel.addControl(this.makeButton("Remove", "remove"));
panel.addControl(this.makeButton("Add Label", "label")); panel.addControl(this.makeButton("Add Label", "label"));
panel.addControl(this.makeButton("Copy", "copy")); panel.addControl(this.makeButton("Copy", "copy"));
panel.addControl(this.makeButton("Connect", "connect"));
//panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras")); //panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras"));
this.manager.controlScaling = .5; this.manager.controlScaling = .5;
@ -119,6 +201,22 @@ export class EditMenu {
case EditMenuState.COPYING: case EditMenuState.COPYING:
this.setCopying(mesh); this.setCopying(mesh);
break; break;
case EditMenuState.CONNECTING:
this.setConnecting(mesh, pointerInfo);
break;
}
}
private setConnecting(mesh: AbstractMesh, pointerInfo) {
if (this.connection) {
this.connection.to = mesh.id;
this.diagramManager.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.ADD,
entity: this.connection,
});
this.connection = null;
} else {
this.connection = new DiagramConnection(mesh.id, null, null, this.scene, pointerInfo);
} }
} }
@ -189,6 +287,9 @@ export class EditMenu {
case "copy": case "copy":
this.state = EditMenuState.COPYING; this.state = EditMenuState.COPYING;
break; break;
case "connect":
this.state = EditMenuState.CONNECTING;
break;
default: default:
this.logger.error("Unknown button"); this.logger.error("Unknown button");
return; return;