immersive2/src/diagram/diagramManager.ts

170 lines
5.9 KiB
TypeScript

import {
AbstractMesh,
Angle,
Color3,
Mesh,
MeshBuilder,
Observable, Scene,
StandardMaterial,
Vector3, WebXRExperienceHelper
} from "@babylonjs/core";
import {v4 as uuidv4} from 'uuid';
import {DiagramEntity, DiagramEvent, DiagramEventType} from "./diagramEntity";
import {PersistenceManager} from "./persistenceManager";
export class DiagramManager {
private persistenceManager: PersistenceManager = new PersistenceManager();
static onDiagramEventObservable = new Observable();
private scene: Scene;
private xr: WebXRExperienceHelper;
static currentMesh: AbstractMesh;
constructor(scene: Scene, xr: WebXRExperienceHelper) {
this.scene = scene;
this.xr = xr;
this.persistenceManager.updateObserver.add(this.#onRemoteEvent, -1, true, this);
this.persistenceManager.initialize();
if (!DiagramManager.onDiagramEventObservable) {
DiagramManager.onDiagramEventObservable = new Observable();
}
if (DiagramManager.onDiagramEventObservable.hasObservers()) {
} else {
DiagramManager.onDiagramEventObservable.add(this.#onDiagramEvent, -1, true, this);
}
}
#onRemoteEvent(event: DiagramEntity) {
const mesh = this.#createMesh(event);
const material = new StandardMaterial("material-" + event.id, this.scene);
material.diffuseColor = Color3.FromHexString(event.color);
mesh.material = material;
}
#onDiagramEvent(event: DiagramEvent) {
const entity = event.entity;
let mesh;
let material
if (entity) {
mesh = this.scene.getMeshByName(entity.id);
if (mesh) {
material = mesh.material;
}
}
switch (event.type) {
case DiagramEventType.CLEAR:
DiagramManager.currentMesh.dispose();
DiagramManager.currentMesh = null;
break;
case DiagramEventType.DROPPED:
break;
case DiagramEventType.DROP:
if (DiagramManager.currentMesh) {
this.persistenceManager.add(DiagramManager.currentMesh);
const newName = uuidv4();
const newMesh = DiagramManager.currentMesh.clone("id"+newName, DiagramManager.currentMesh.parent);
const newMaterial = DiagramManager.currentMesh.material.clone("material"+newName);
newMesh.material=newMaterial;
DiagramManager.currentMesh.setParent(null);
DiagramManager.currentMesh = newMesh;
DiagramManager.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.DROPPED,
entity: entity
});
}
break;
case DiagramEventType.ADD:
if (DiagramManager.currentMesh) {
DiagramManager.currentMesh.dispose();
}
if (mesh) {
return;
} else {
mesh = this.#createMesh(entity);
if (!material) {
material = new StandardMaterial("material-" + event.entity.id, this.scene);
material.diffuseColor = Color3.FromHexString(event.entity.color);
mesh.material = material;
}
if (!mesh) {
return;
}
}
DiagramManager.currentMesh = mesh;
break;
case DiagramEventType.MODIFY:
if (!mesh) {
} else {
if (!material) {
material = new StandardMaterial("material-" + event.entity.id, this.scene);
material.diffuseColor = Color3.FromHexString(event.entity.color);
if (mesh) {
mesh.material = material;
}
}
mesh.material = material;
mesh.position = entity.position;
mesh.rotation = entity.rotation;
if (entity.parent) {
mesh.parent = this.scene.getMeshByName(entity.parent);
} else {
}
}
DiagramManager.currentMesh = mesh;
break;
case DiagramEventType.REMOVE:
break;
}
}
#createMesh(entity: DiagramEntity) {
if (!entity.id) {
entity.id = "id" + uuidv4();
}
let mesh: Mesh;
switch (entity.template) {
case "#box-template":
mesh = MeshBuilder.CreateBox(entity.id,
{
width: 1,
height: 1,
depth: 1
}, this.scene);
break;
case "#sphere-template":
mesh = MeshBuilder.CreateSphere(entity.id, {diameter: 1}, this.scene);
break
case "#cylinder-template":
mesh = MeshBuilder.CreateCylinder(entity.id, {
diameter: 1,
height: 1
}, this.scene);
break;
default:
mesh = null;
}
if (mesh) {
mesh.metadata = {template: entity.template};
if (entity.position) {
mesh.position = entity.position;
}
if (entity.rotation) {
mesh.rotation = entity.rotation;
}
if (entity.parent) {
mesh.parent = this.scene.getMeshByName(entity.parent);
}
if (entity.scale) {
mesh.scaling = entity.scale;
}
}
return mesh;
}
}