diff --git a/src/controllers/functions/buildRig.ts b/src/controllers/functions/buildRig.ts index 9a742b0..d5c0da7 100644 --- a/src/controllers/functions/buildRig.ts +++ b/src/controllers/functions/buildRig.ts @@ -14,24 +14,19 @@ import { import {buildStandardMaterial} from "../../materials/functions/buildStandardMaterial"; export function buildRig(scene: Scene, xr: WebXRDefaultExperience): Mesh { - const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: .2}, scene); + const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: .01}, scene); const cameratransform = new TransformNode("cameraTransform", scene); cameratransform.parent = rigMesh; - xr.baseExperience.onInitialXRPoseSetObservable.add((state) => { - + xr.baseExperience.onInitialXRPoseSetObservable.add(() => { xr.baseExperience.camera.parent = cameratransform; xr.baseExperience.camera.position = new Vector3(0, 0, 0); - - }); for (const cam of scene.cameras) { cam.parent = cameratransform; if (cam.getClassName() == "FreeCamera") { - //cameratransform.position = new Vector3(0, 1.6, 0); - //cam.position.set(0, 1.6, 0); + } else { - //cameratransform.position = new Vector3(0, 1.6, 0); - //cam.position.set(0, 0, 0); + } } @@ -39,18 +34,13 @@ export function buildRig(scene: Scene, xr: WebXRDefaultExperience): Mesh { for (const cam of scene.cameras) { cam.parent = cameratransform; if (cam.getClassName() == "FreeCamera") { - //cameratransform.position = new Vector3(0, 1.6, 0); - //cam.position.set(0, 1.6, 0); } else { - //cameratransform.position = new Vector3(0, 0, 0); - //cam.position.set(0, 0, 0); } } cameratransform.rotation.set(0, Math.PI, 0); - //s.activeCamera.parent = cameratransform; }); rigMesh.material = buildStandardMaterial("rigMaterial", scene, "#2222ff"); - rigMesh.setAbsolutePosition(new Vector3(0, .01, 3)); + rigMesh.setAbsolutePosition(new Vector3(0, .01, 4)); rigMesh.isPickable = false; new AxesViewer(scene, .25); rigMesh.lookAt(new Vector3(0, 0.01, 0)); diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index 74b2353..34c864f 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -36,12 +36,11 @@ export class Rigplatform { public rigMesh: Mesh; constructor(scene: Scene, xr: WebXRDefaultExperience, - diagramManager: DiagramManager, - controllers: Controllers, + diagramManager: DiagramManager ) { this.scene = scene; this.diagramManager = diagramManager; - this.controllers = controllers; + this.controllers = diagramManager.controllers; this.xr = xr; this.rigMesh = buildRig(scene, xr); diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index b64dd21..b493488 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -27,7 +27,7 @@ export class DiagramManager { public readonly onDiagramEventObservable: Observable = new Observable(); private readonly logger = log.getLogger('DiagramManager'); private readonly toolbox: Toolbox; - private readonly scene: Scene; + private readonly _scene: Scene; private readonly sounds: DiaSounds; constructor(scene: Scene) { @@ -49,10 +49,10 @@ export class DiagramManager { }); this.sounds = new DiaSounds(scene); - this.scene = scene; + this._scene = scene; this.toolbox = new Toolbox(scene); - this.presentationManager = new PresentationManager(this.scene); - this.diagramEntityActionManager = buildEntityActionManager(this.scene, this.sounds, this._controllers); + this.presentationManager = new PresentationManager(this._scene); + this.diagramEntityActionManager = buildEntityActionManager(this._scene, this.sounds, this._controllers); if (this.onDiagramEventObservable.hasObservers()) { this.logger.warn("onDiagramEventObservable already has Observers, you should be careful"); @@ -95,6 +95,11 @@ export class DiagramManager { public get config(): AppConfig { return this._config; } + + public get scene(): Scene { + return this._scene; + } + public createCopy(mesh: AbstractMesh, copy: boolean = false): AbstractMesh { let newMesh; if (!mesh.isAnInstance) { @@ -116,14 +121,14 @@ export class DiagramManager { newMesh.material = mesh.material; newMesh.metadata = deepCopy(mesh.metadata); if (this._config.current?.physicsEnabled) { - applyPhysics(this.sounds, newMesh, this.scene); + applyPhysics(this.sounds, newMesh, this._scene); } return newMesh; } private onDiagramEvent(event: DiagramEvent) { diagramEventHandler( - event, this.scene, this.toolbox, this._config.current.physicsEnabled, + event, this._scene, this.toolbox, this._config.current.physicsEnabled, this.diagramEntityActionManager, this.sounds); } } \ No newline at end of file diff --git a/src/diagram/types/diagramEntity.ts b/src/diagram/types/diagramEntity.ts index 11d22dc..5fc4e10 100644 --- a/src/diagram/types/diagramEntity.ts +++ b/src/diagram/types/diagramEntity.ts @@ -1,5 +1,4 @@ import {Color3} from "@babylonjs/core"; -import {EditMenuState} from "../../menus/editMenuState"; export enum DiagramEventType { ADD, @@ -25,7 +24,6 @@ export enum DiagramEventMask { export type DiagramEvent = { type: DiagramEventType; - menustate?: EditMenuState; entity?: DiagramEntity; oldColor?: Color3; newColor?: Color3; diff --git a/src/information/hud.ts b/src/information/hud.ts deleted file mode 100644 index a562dc0..0000000 --- a/src/information/hud.ts +++ /dev/null @@ -1,50 +0,0 @@ -import {AbstractMesh, Color3, MeshBuilder, Scene, Vector3} from "@babylonjs/core"; -import {AdvancedDynamicTexture, StackPanel, TextBlock} from "@babylonjs/gui"; - -export class Hud { - private scene: Scene; - private parent: AbstractMesh; - private readonly hudPlane: AbstractMesh; - constructor(parent: AbstractMesh, scene: Scene) { - this.scene = scene; - this.parent = parent; - this.hudPlane = MeshBuilder.CreatePlane("hudPlane", {width: 1, height: .5}, this.parent.getScene()); - this.hudPlane.parent=this.parent.getScene().activeCamera - this.parent.getScene().onActiveCameraChanged.add((scene) => { - this.hudPlane.parent = scene.activeCamera; - }); - this.hudPlane.position = new Vector3(.5, .75, 3); - - this.hudPlane.outlineColor = Color3.FromHexString("#ffffff"); - - - const textPosition = this.createTextBlock(); - const textRotation = this.createTextBlock(); - - const hudTexture = AdvancedDynamicTexture.CreateForMesh(this.hudPlane, 1024, 512); - - hudTexture.background = "black"; - const stackPanel = new StackPanel(); - hudTexture.addControl(stackPanel); - - - stackPanel.addControl(textPosition); - stackPanel.addControl(textRotation); - - - } - createTextBlock(): TextBlock { - const text = new TextBlock(); - text.isHitTestVisible = false; - text.text = ""; - text.height="20%"; - text.resizeToFit=true; - - text.color="white"; - text.fontSize = 64; - return text; - } - private formatVector3(v: Vector3): string { - return `(${v.x.toFixed(2)},${v.y.toFixed(2)},${v.z.toFixed(2)})`; - } -} diff --git a/src/integration/pouchdbPersistenceManager.ts b/src/integration/pouchdbPersistenceManager.ts index 02f0264..b27a22f 100644 --- a/src/integration/pouchdbPersistenceManager.ts +++ b/src/integration/pouchdbPersistenceManager.ts @@ -271,7 +271,7 @@ export class PouchdbPersistenceManager { return; } if (target.data && target.data.userCtx) { - if (!target.data.userCtx.name) { + if (!target.data.userCtx.name || target.data.userCtx.name != remoteUserName) { const buildTarget = await axios.post(userEndpoint, {username: remoteUserName, password: password}); if (buildTarget.status != 200) { diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts deleted file mode 100644 index fdb4fbf..0000000 --- a/src/menus/editMenu.ts +++ /dev/null @@ -1,330 +0,0 @@ -import { - AbstractMesh, - Color3, - GizmoManager, - InstancedMesh, - Mesh, - PointerEventTypes, - PointerInfo, - Scene, - StandardMaterial, - Vector3, - WebXRDefaultExperience, -} from "@babylonjs/core"; -import {GUI3DManager, PlanePanel} from "@babylonjs/gui"; -import {DiagramManager} from "../diagram/diagramManager"; -import {EditMenuState} from "./editMenuState"; -import {DiagramEvent, DiagramEventType} from "../diagram/types/diagramEntity"; -import log from "loglevel"; -import {InputTextView} from "../information/inputTextView"; -import {DiaSounds} from "../util/diaSounds"; -import {updateTextNode} from "../util/functions/updateTextNode"; -import {DiagramConnection} from "../diagram/diagramConnection"; - -import {toDiagramEntity} from "../diagram/functions/toDiagramEntity"; -import {AbstractMenu} from "./abstractMenu"; -import {Controllers} from "../controllers/controllers"; -import {setMenuPosition} from "../util/functions/setMenuPosition"; -import {SoccerMenu} from "../soccer/soccerMenu"; -import {CameraMenu} from "./cameraMenu"; -import {exportGltf} from "../util/functions/exportGltf"; -import {isDiagramEntity} from "../diagram/functions/isDiagramEntity"; -import {ScaleMenu} from "./scaleMenu"; - -export class EditMenu extends AbstractMenu { - private state: EditMenuState = EditMenuState.NONE; - private manager: GUI3DManager; - private paintColor: string = null; - private readonly logger: log.Logger = log.getLogger('EditMenu'); - private gizmoManager: GizmoManager; - private readonly diagramManager: DiagramManager; - private connection: DiagramConnection = null; - private panel: PlanePanel; - private cameraMenu: CameraMenu = null; - private sounds: DiaSounds; - - private get isVisible(): boolean { - return this.panel.isVisible; - } - - private soccerMenu: SoccerMenu; - - private set isVisible(visible: boolean) { - this.panel.isVisible = visible; - this.panel.children.forEach((child) => { - child.isVisible = visible; - }); - this.handle.mesh.isVisible = visible; - } - 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; - } else { - this.logger.error("mesh has no metadata"); - } - this.diagramManager.onDiagramEventObservable.notifyObservers({ - type: DiagramEventType.MODIFY, - entity: toDiagramEntity(mesh), - }, -1); - } - - toggle() { - if (this.isVisible) { - this.sounds.exit.play(); - this.isVisible = false; - - } else { - this.sounds.enter.play(); - setMenuPosition(this.handle.mesh, this.scene, new Vector3(-.6, .4, 0)); - this.isVisible = true; - } - } - - makeButton(name: string, id: string) { - const button = super.makeButton(name, id); - button.onPointerClickObservable.add(this.handleClick, -1, false, this); - return button; - } - - private async diagramEntityPicked(pointerInfo: PointerInfo) { - const mesh = pointerInfo.pickInfo.pickedMesh; - if (!mesh) { - this.logger.warn("no mesh"); - return; - } - switch (this.state) { - case EditMenuState.REMOVING: - this.removeMesh(mesh); - break; - case EditMenuState.MODIFYING: - this.modifyMesh(mesh); - break; - case EditMenuState.LABELING: - this.labelMesh(mesh); - break; - case EditMenuState.COPYING: - this.copyMesh(mesh); - break; - case EditMenuState.CONNECTING: - 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)); - if (!newBase) { - return; - } - 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: toDiagramEntity(newMesh) - }, -1); - - } else { - this.logger.error("no paint color selectced"); - } - } - } - - private createMeshConnection(mesh: AbstractMesh, pointerInfo) { - if (this.connection) { - this.connection.to = mesh.id; - this.diagramManager.onDiagramEventObservable.notifyObservers({ - type: DiagramEventType.ADD, - entity: toDiagramEntity(this.connection.mesh) - }, -1); - this.connection = null; - } else { - this.connection = new DiagramConnection(mesh.id, null, null, this.scene, pointerInfo.pickInfo.gripTransform); - } - } - - private removeMesh(mesh: AbstractMesh) { - this.logger.debug("removing " + mesh?.id); - const event: DiagramEvent = { - type: DiagramEventType.REMOVE, - entity: - toDiagramEntity(mesh) - } - - this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1); - } - - private scaleMenu: ScaleMenu; - constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) { - super(scene, xr, controllers); - //this.scaleMenu = new ScaleMenu(this.scene, this.xr, this.controllers); - this.sounds = new DiaSounds(scene); - this.diagramManager = diagramManager; - /*this.gizmoManager = new GizmoManager(scene); - this.gizmoManager.boundingBoxGizmoEnabled = true; - this.gizmoManager.gizmos.boundingBoxGizmo.scaleBoxSize = .020; - this.gizmoManager.gizmos.boundingBoxGizmo.rotationSphereSize = .020; - this.gizmoManager.gizmos.boundingBoxGizmo.scaleDragSpeed = 2; - this.gizmoManager.clearGizmoOnEmptyPointerEvent = true; - this.gizmoManager.usePointerToAttachGizmos = false;*/ - this.manager = new GUI3DManager(this.scene); - - const panel = new PlanePanel(); - panel.orientation = PlanePanel.FACEFORWARDREVERSED_ORIENTATION; - panel.columns = 4; - this.manager.addControl(panel); - //panel.addControl(this.makeButton("Cameras", "camera")); - //panel.addControl(this.makeButton("Modify", "modify")); - panel.addControl(this.makeButton("Remove", "remove")); - panel.addControl(this.makeButton("Label", "label")); - panel.addControl(this.makeButton("Copy", "copy")); - panel.addControl(this.makeButton("Connect", "connect")); - //panel.addControl(this.makeButton("Export GLTF", "exportgltf")); - //panel.addControl(this.makeButton("Recolor", "recolor")); - //panel.addControl(this.makeButton("New Relic", "newrelic")); - //panel.addControl(this.makeButton("Soccer", "soccer")); - //panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras")); - this.manager.controlScaling = .1; - this.scene.onPointerObservable.add((pointerInfo) => { - switch (pointerInfo.type) { - case PointerEventTypes.POINTERPICK: - const pickedMesh = pointerInfo.pickInfo?.pickedMesh; - if (isDiagramEntity(pickedMesh) && - pickedMesh?.parent?.parent?.id != "toolbox") { - this.diagramEntityPicked(pointerInfo).then(() => { - this.logger.debug("handled"); - }).catch((e) => { - this.logger.error(e); - }); - 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); - } - - } - } - }); - this.panel = panel; - this.createHandle(this.manager.rootContainer.children[0].node); - this.manager.rootContainer.children[0].node.position.y = .15; - this.isVisible = false; - - } - - private copyMesh(mesh: AbstractMesh) { - if (mesh) { - const newMesh = this.diagramManager.createCopy(mesh, true); - newMesh.setParent(mesh.parent); - } - this.logger.warn('copying not implemented', mesh); - //@todo implement - } - - private labelMesh(mesh: AbstractMesh) { - this.logger.debug("labeling " + mesh.id); - let text = ""; - if (mesh?.metadata?.text) { - text = mesh.metadata.text; - } - const textInput = new InputTextView(text, this.xr, this.scene, this.controllers); - - textInput.show(); - textInput.onTextObservable.addOnce((value) => { - this.persist(mesh, value.text); - updateTextNode(mesh, value.text); - }); - - - } - - private showNewRelic() { - const inputTextView = new InputTextView('test', this.xr, this.scene, this.controllers); - inputTextView.show(); - inputTextView.onTextObservable.addOnce((value) => { - const config = this.diagramManager._config.current; - config.newRelicKey = value.text; - this.diagramManager._config.current = config; - inputTextView.show(); - inputTextView.onTextObservable.addOnce((value) => { - const config = this.diagramManager._config.current; - config.newRelicAccount = value.text; - this.diagramManager._config.current = config; - }); - }); - - - } - - private modifyMesh(mesh: AbstractMesh) { - if (isDiagramEntity(mesh) && - mesh.parent?.parent?.id != "toolbox") { - this.scaleMenu.changeMesh(mesh); - } - } - - private handleClick(_info, state) { - switch (state.currentTarget.name) { - case "modify": - this.state = EditMenuState.MODIFYING; - break; - case "remove": - this.state = EditMenuState.REMOVING; - break; - case "label": - this.state = EditMenuState.LABELING; - break; - case "copy": - this.state = EditMenuState.COPYING; - break; - case "connect": - this.state = EditMenuState.CONNECTING; - break; - case "recolor": - this.state = EditMenuState.RECOLORING; - break; - case "newrelic": - this.showNewRelic(); - break; - case "exportgltf": - this.downloadgltf(); - break; - case "soccer": - this.createSoccerField(); - break; - case "camera": - if (!this.cameraMenu) { - this.cameraMenu = new CameraMenu(this.scene, null, null); - } - break; - default: - this.logger.error("Unknown button"); - return; - - } - - this.isVisible = false; - } - - private createSoccerField() { - if (!this.soccerMenu) { - this.soccerMenu = new SoccerMenu(this.scene, this.xr, this.controllers); - } - } - - private downloadgltf() { - exportGltf(this.scene); - } -} \ No newline at end of file diff --git a/src/menus/editMenuState.ts b/src/menus/editMenuState.ts deleted file mode 100644 index d10496e..0000000 --- a/src/menus/editMenuState.ts +++ /dev/null @@ -1,12 +0,0 @@ -export enum EditMenuState { - NONE, - LABELING, - MODIFYING, // Editing an entity - REMOVING, - COPYING, // Removing an entity - CONNECTING, - RECOLORING, - SOCCER, - - -} \ No newline at end of file diff --git a/src/util/functions/groundMeshObserver.ts b/src/util/functions/groundMeshObserver.ts index 4f572ea..9ea7059 100644 --- a/src/util/functions/groundMeshObserver.ts +++ b/src/util/functions/groundMeshObserver.ts @@ -1,13 +1,17 @@ -import {WebXRDefaultExperience, WebXRState} from "@babylonjs/core"; +import {AbstractMesh, WebXRDefaultExperience, WebXRState} from "@babylonjs/core"; import log from "loglevel"; import {WebController} from "../../controllers/webController"; -import {EditMenu} from "../../menus/editMenu"; -import {ControllerEventType} from "../../controllers/controllers"; import {ConfigMenu} from "../../menus/configMenu"; +import {Rigplatform} from "../../controllers/rigplatform"; +import {DiagramManager} from "../../diagram/diagramManager"; +import {Spinner} from "../spinner"; const logger = log.getLogger('groungMeshObserver'); -export async function groundMeshObserver(ground, scene, diagramManager, controllers, spinner) { - const xr = await WebXRDefaultExperience.CreateAsync(scene, { + +export async function groundMeshObserver(ground: AbstractMesh, + diagramManager: DiagramManager, + spinner: Spinner) { + const xr = await WebXRDefaultExperience.CreateAsync(ground.getScene(), { floorMeshes: [ground], disableHandTracking: true, disableTeleportation: true, @@ -21,17 +25,11 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll pointerSelectionOptions: { enablePointerSelectionOnAllControllers: true } - - - }); - xr.baseExperience.onInitialXRPoseSetObservable.add((camera) => { - //camera.position = new Vector3(0, -1.6, 0); }); const enterButton = (document.querySelector('#enterXR') as HTMLAnchorElement); if (enterButton) { const vrSupported = await xr.baseExperience.sessionManager.isSessionSupportedAsync('immersive-vr'); if (vrSupported) { - //enterButton.style.display = "block"; enterButton.classList.remove('inactive'); enterButton.addEventListener('click', (evt) => { evt.preventDefault(); @@ -49,43 +47,31 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll xr.baseExperience.sessionManager.onXRSessionInit.add((session) => { session.addEventListener('visibilitychange', (ev) => { logger.debug(ev); - //this.logger.debug(ev); }); }); xr.baseExperience.onStateChangedObservable.add((state) => { switch (state) { case WebXRState.IN_XR: - scene.audioEnabled = true; - - //xr.baseExperience.camera.position = new Vector3(0, 1.6, 0); - //xr.baseExperience.camera.setTarget(new Vector3(0, 1.6, 3)); + ground.getScene().audioEnabled = true; window.addEventListener(('pa-button-state-change'), (event: any) => { if (event.detail) { logger.debug(event.detail); } }); break; - } + }); + const rig = new Rigplatform(ground.getScene(), xr, diagramManager); + const currentConfig = diagramManager.config.current; + rig.flyMode = currentConfig.flyMode; + rig.turnSnap = currentConfig.turnSnap; + diagramManager.config.onConfigChangedObservable.add((config) => { + rig.flyMode = config.flyMode; + rig.turnSnap = config.turnSnap; }); - import('../../controllers/rigplatform').then((rigmodule) => { - const rig = new rigmodule.Rigplatform(scene, xr, diagramManager, controllers); - const currentConfig = diagramManager.config.current; - rig.flyMode = currentConfig.flyMode; - rig.turnSnap = currentConfig.turnSnap; - diagramManager.config.onConfigChangedObservable.add((config) => { - rig.flyMode = config.flyMode; - rig.turnSnap = config.turnSnap; - }); - const menu = new EditMenu(scene, xr, diagramManager, controllers); - controllers.controllerObserver.add((event) => { - if (event.type == ControllerEventType.MENU) { - menu.toggle(); - } - }); - const config = new ConfigMenu(scene, xr, controllers, diagramManager.config); - const webController = new WebController(scene, rig, diagramManager, controllers); - }); + const config = new ConfigMenu(ground.getScene(), xr, diagramManager.controllers, diagramManager.config); + const webController = new WebController(ground.getScene(), rig, diagramManager, diagramManager.controllers); + } \ No newline at end of file diff --git a/src/vrApp.ts b/src/vrApp.ts index f8e437c..9228528 100644 --- a/src/vrApp.ts +++ b/src/vrApp.ts @@ -40,7 +40,7 @@ export class VrApp { const spinner = new Spinner(scene); spinner.show(); - //const config = new AppConfig(); + const diagramManager = new DiagramManager(scene); const db = new PouchdbPersistenceManager(); @@ -64,7 +64,7 @@ export class VrApp { scene.setActiveCameraByName("Main Camera"); const environment = new CustomEnvironment(scene, "default", diagramManager.config); environment.groundMeshObservable.add((ground) => { - groundMeshObserver(ground, scene, diagramManager, diagramManager.controllers, spinner); + groundMeshObserver(ground, diagramManager, spinner); }, -1, false, this); const gamepadManager = new GamepadManager(scene);