immersive2/src/diagram/diagramManager.ts
2023-07-29 07:54:49 -05:00

145 lines
5.5 KiB
TypeScript

import {
AbstractMesh,
ActionManager,
Color3,
ExecuteCodeAction,
InstancedMesh,
Mesh,
Observable,
PlaySoundAction,
Scene,
Sound,
WebXRExperienceHelper
} from "@babylonjs/core";
import {DiagramEntity, DiagramEvent, DiagramEventType} from "./diagramEntity";
import {IPersistenceManager} from "./persistenceManager";
import {MeshConverter} from "./meshConverter";
import log from "loglevel";
import {Controllers} from "../controllers/controllers";
export class DiagramManager {
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
private readonly logger = log.getLogger('DiagramManager');
private persistenceManager: IPersistenceManager = null;
private readonly scene: Scene;
private xr: WebXRExperienceHelper;
private readonly tick: Sound;
public setPersistenceManager(persistenceManager: IPersistenceManager) {
this.persistenceManager = persistenceManager;
this.persistenceManager.updateObserver.add(this.onRemoteEvent, -1, true, this);
}
private getPersistenceManager(): IPersistenceManager {
if (!this.persistenceManager) {
this.logger.warn("persistenceManager not set");
return null;
}
return this.persistenceManager;
}
private readonly actionManager: ActionManager;
constructor(scene: Scene, xr: WebXRExperienceHelper) {
this.scene = scene;
this.xr = xr;
this.tick = new Sound("tick", './tick.mp3', this.scene);
this.tick.setVolume(.3);
this.actionManager = new ActionManager(this.scene);
this.actionManager.registerAction(
new PlaySoundAction(ActionManager.OnPointerOverTrigger, this.tick));
this.actionManager.registerAction(
new ExecuteCodeAction(ActionManager.OnPointerOverTrigger, (evt) => {
Controllers.controllerObserver.notifyObservers({
type: 'pulse',
gripId: evt?.additionalData?.pickResult?.gripTransform?.id
})
this.logger.debug(evt);
})
);
if (this.onDiagramEventObservable.hasObservers()) {
this.logger.warn("onDiagramEventObservable already has Observers, you should be careful");
}
this.onDiagramEventObservable.add(this.onDiagramEvent, -1, true, this);
this.logger.debug("DiagramManager constructed");
}
public createCopy(mesh: AbstractMesh): AbstractMesh {
let newMesh;
if (!mesh.isAnInstance) {
newMesh = new InstancedMesh("new", (mesh as Mesh));
} else {
newMesh = new InstancedMesh("new", (mesh as InstancedMesh).sourceMesh);
}
newMesh.actionManager = this.actionManager;
return newMesh;
}
private onRemoteEvent(event: DiagramEntity) {
this.logger.debug(event);
const toolMesh = this.scene.getMeshById("tool-" + event.template + "-" + event.color);
if (!toolMesh) {
log.debug('no mesh found for ' + event.template + "-" + event.color, 'adding it');
this.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.CHANGECOLOR,
entity: event
});
}
const mesh = MeshConverter.fromDiagramEntity(event, this.scene);
mesh.actionManager = this.actionManager;
if (event.parent) {
mesh.parent = this.scene.getMeshById(event.parent);
}
}
private onDiagramEvent(event: DiagramEvent) {
this.logger.debug(event.type);
const entity = event.entity;
let mesh;
if (entity) {
mesh = this.scene.getMeshById(entity.id);
}
switch (event.type) {
case DiagramEventType.CLEAR:
break;
case DiagramEventType.DROPPED:
break;
case DiagramEventType.DROP:
this.getPersistenceManager()?.modify(mesh);
MeshConverter.updateTextNode(mesh, entity.text);
break;
case DiagramEventType.ADD:
this.getPersistenceManager()?.add(mesh);
break;
case DiagramEventType.MODIFY:
this.getPersistenceManager()?.modify(mesh);
break;
case DiagramEventType.CHANGECOLOR:
if (!event.oldColor) {
if (!event.newColor) {
this.getPersistenceManager()?.changeColor(null, Color3.FromHexString(event.entity.color));
this.logger.info("Recieved color change event, sending entity color as new color");
} else {
this.logger.info("Recieved color change event, no old color, sending new color");
this.getPersistenceManager()?.changeColor(null, event.newColor);
}
} else {
if (event.newColor) {
this.logger.info("changing color from " + event.oldColor + " to " + event.newColor);
this.getPersistenceManager()?.changeColor(event.oldColor, event.newColor);
} else {
this.logger.error("changing color from " + event.oldColor + ", but no new color found");
}
}
break;
case DiagramEventType.REMOVE:
if (mesh) {
this.getPersistenceManager()?.remove(mesh)
mesh.dispose();
}
break;
}
}
}