From 9d5234b62972ec185572a21ea2e3547e81cbdb9f Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Fri, 14 Feb 2025 11:01:27 -0600 Subject: [PATCH] Added webxr exit button --- index.html | 4 +-- src/controllers/functions/grabAndClone.ts | 4 ++- src/controllers/rigplatform.ts | 22 +++++++++++++++ src/diagram/diagramManager.ts | 7 +++-- src/diagram/diagramMenuManager.ts | 27 +++++++++++-------- src/diagram/diagramObject.ts | 5 ++-- src/diagram/types/diagramEntity.ts | 7 ++--- src/integration/database/database.ts | 4 +-- src/integration/database/pouchData.ts | 10 +++++++ .../database/pouchdbPersistenceManager.ts | 6 ++--- src/integration/functions/syncDoc.ts | 10 ++++--- src/menus/configMenu.ts | 1 + src/menus/connectionPreview.ts | 4 +-- src/menus/inputFile.ts | 4 +-- src/react/vrTemplate.tsx | 6 ++--- src/util/constants.ts | 2 +- src/util/customEnvironment.ts | 6 +++-- src/util/functions/groundMeshObserver.ts | 2 +- src/vrApp.ts | 6 ++--- 19 files changed, 90 insertions(+), 47 deletions(-) diff --git a/index.html b/index.html index 4826956..fc23190 100644 --- a/index.html +++ b/index.html @@ -3,14 +3,14 @@ - - Deep Diagram + DASFAD diff --git a/src/controllers/functions/grabAndClone.ts b/src/controllers/functions/grabAndClone.ts index 20b1f74..d59f167 100644 --- a/src/controllers/functions/grabAndClone.ts +++ b/src/controllers/functions/grabAndClone.ts @@ -3,6 +3,7 @@ import {DiagramManager} from "../../diagram/diagramManager"; import {DiagramObject} from "../../diagram/diagramObject"; import log from "loglevel"; import {vectoxys} from "../../diagram/functions/vectorConversion"; +import {DiagramEntityType} from "../../diagram/types/diagramEntity"; export function grabAndClone(diagramManager: DiagramManager, mesh: AbstractMesh, parent: AbstractMesh): DiagramObject { @@ -23,7 +24,8 @@ export function grabAndClone(diagramManager: DiagramManager, mesh: AbstractMesh, color: mesh.metadata.color, position: vectoxys(mesh.absolutePosition), rotation: vectoxys(mesh.absoluteRotationQuaternion.toEulerAngles()), - scale: vectoxys(mesh.scaling) + scale: vectoxys(mesh.scaling), + type: DiagramEntityType.ENTITY } const obj = new DiagramObject(parent.getScene(), diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index a317d75..55085ec 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -8,6 +8,7 @@ import {DefaultScene} from "../defaultScene"; import {ControllerEvent} from "./types/controllerEvent"; import {ControllerEventType} from "./types/controllerEventType"; import {controllerObservable} from "./controllers"; +import {Button} from "../objects/Button"; const RIGHT = "right"; const LEFT = "left"; @@ -44,6 +45,27 @@ export class Rigplatform { this._xr = xr; this.rigMesh = buildRig(xr); + this._xr.baseExperience.onStateChangedObservable.add((state) => { + if (state == 2) { + const button = Button.CreateButton("exitXr", "exitXr", this._scene, {}); + button.transform.position.z = 1; + button.transform.rotation.y = Math.PI; + button.transform.position.y = 1.2; + button.transform.scaling = new Vector3(.1, .1, .1); + button.transform.parent = this.rigMesh; + button.onPointerObservable.add((evt) => { + console.log(evt); + console.log(evt.sourceEvent.type); + if (evt.sourceEvent.type == 'pointerdown') { + xr.baseExperience.exitXRAsync(); + } + //xr.baseExperience.exitXRAsync(); + }); + + } + + }); + this._fixRotation(); this._initializeControllers(); this._registerVelocityObserver(); diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index 6ec1a80..291665d 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -1,5 +1,5 @@ import {AbstractActionManager, AbstractMesh, ActionManager, Observable, Scene} from "@babylonjs/core"; -import {DiagramEntity, DiagramEvent, DiagramEventType} from "./types/diagramEntity"; +import {DiagramEntity, DiagramEntityType, DiagramEvent, DiagramEventType} from "./types/diagramEntity"; import log from "loglevel"; import {AppConfig} from "../util/appConfig"; @@ -33,7 +33,7 @@ export class DiagramManager { this._me = getMe(); this._scene = DefaultScene.Scene; this._config = new AppConfig(); - this._diagramMenuManager = new DiagramMenuManager(this.onDiagramEventObservable, controllerObservable, this._config, readyObservable); + this._diagramMenuManager = new DiagramMenuManager(this.onDiagramEventObservable, controllerObservable, readyObservable); this._diagramEntityActionManager = buildEntityActionManager(controllerObservable); this.onDiagramEventObservable.add(this.onDiagramEvent, DiagramEventObserverMask.FROM_DB, true, this); this.onUserEventObservable.add((user) => { @@ -79,7 +79,7 @@ export class DiagramManager { template: '#image-template', image: event.detail.data, text: event.detail.name, - type: 'entity', + type: DiagramEntityType.ENTITY, position: {x: 0, y: 1.6, z: 0}, rotation: {x: 0, y: Math.PI, z: 0}, scale: {x: 1, y: 1, z: 1}, @@ -97,7 +97,6 @@ export class DiagramManager { }); this._logger.debug("DiagramManager constructed"); - } public get actionManager(): AbstractActionManager { diff --git a/src/diagram/diagramMenuManager.ts b/src/diagram/diagramMenuManager.ts index 8039510..2dc491f 100644 --- a/src/diagram/diagramMenuManager.ts +++ b/src/diagram/diagramMenuManager.ts @@ -1,12 +1,10 @@ -import {DiagramEvent, DiagramEventType} from "./types/diagramEntity"; +import {DiagramEntityType, DiagramEvent, DiagramEventType} from "./types/diagramEntity"; import {AbstractMesh, ActionEvent, Observable, Scene, Vector3, WebXRInputSource} from "@babylonjs/core"; import {InputTextView} from "../information/inputTextView"; import {DefaultScene} from "../defaultScene"; import log from "loglevel"; import {Toolbox} from "../toolbox/toolbox"; import {ClickMenu} from "../menus/clickMenu"; -import {ConfigMenu} from "../menus/configMenu"; -import {AppConfig} from "../util/appConfig"; import {DiagramEventObserverMask} from "./types/diagramEventObserverMask"; import {ConnectionPreview} from "../menus/connectionPreview"; import {ScaleMenu2} from "../menus/ScaleMenu2"; @@ -19,7 +17,6 @@ import {ControllerEventType} from "../controllers/types/controllerEventType"; export class DiagramMenuManager { public readonly toolbox: Toolbox; public readonly scaleMenu: ScaleMenu2; - public readonly configMenu: ConfigMenu; private readonly _notifier: Observable; private readonly _inputTextView: InputTextView; private _groupMenu: GroupMenu; @@ -27,22 +24,27 @@ export class DiagramMenuManager { private _logger = log.getLogger('DiagramMenuManager'); private _connectionPreview: ConnectionPreview; - constructor(notifier: Observable, controllerObservable: Observable, config: AppConfig, readyObservable: Observable) { + constructor(notifier: Observable, controllerObservable: Observable, readyObservable: Observable) { this._scene = DefaultScene.Scene; this._notifier = notifier; this._inputTextView = new InputTextView(controllerObservable); - this.configMenu = new ConfigMenu(config); + //this.configMenu = new ConfigMenu(config); this._inputTextView.onTextObservable.add((evt) => { - const event = {type: DiagramEventType.MODIFY, entity: {id: evt.id, text: evt.text}} + const event = { + type: DiagramEventType.MODIFY, + entity: {id: evt.id, text: evt.text, type: DiagramEntityType.ENTITY} + } this._notifier.notifyObservers(event, DiagramEventObserverMask.FROM_DB); }); this.toolbox = new Toolbox(readyObservable); + + this.scaleMenu = new ScaleMenu2(this._notifier); if (viewOnly()) { this.toolbox.handleMesh.setEnabled(false); //this.scaleMenu.handleMesh.setEnabled(false) - this.configMenu.handleTransformNode.setEnabled(false); + // this.configMenu.handleTransformNode.setEnabled(false); } controllerObservable.add((event: ControllerEvent) => { if (event.type == ControllerEventType.B_BUTTON) { @@ -64,9 +66,9 @@ export class DiagramMenuManager { this._inputTextView.handleMesh.position.y = localCamera.y - .2; } const configY = this._inputTextView.handleMesh.absolutePosition.y; - if (configY > (cameraPos.y - .2)) { + /*if (configY > (cameraPos.y - .2)) { this.configMenu.handleTransformNode.position.y = localCamera.y - .2; - } + }*/ } } }); @@ -94,7 +96,10 @@ export class DiagramMenuManager { switch (evt.source.id) { case "remove": - this.notifyAll({type: DiagramEventType.REMOVE, entity: {id: clickMenu.mesh.id}}); + this.notifyAll({ + type: DiagramEventType.REMOVE, + entity: {id: clickMenu.mesh.id, type: DiagramEntityType.ENTITY} + }); break; case "label": this.editText(clickMenu.mesh); diff --git a/src/diagram/diagramObject.ts b/src/diagram/diagramObject.ts index af32faa..a3fe403 100644 --- a/src/diagram/diagramObject.ts +++ b/src/diagram/diagramObject.ts @@ -12,7 +12,7 @@ import { TransformNode, Vector3 } from "@babylonjs/core"; -import {DiagramEntity, DiagramEvent, DiagramEventType} from "./types/diagramEntity"; +import {DiagramEntity, DiagramEntityType, DiagramEvent, DiagramEventType} from "./types/diagramEntity"; import {buildMeshFromDiagramEntity} from "./functions/buildMeshFromDiagramEntity"; import {toDiagramEntity} from "./functions/toDiagramEntity"; import {v4 as uuidv4} from 'uuid'; @@ -29,6 +29,7 @@ type DiagramObjectOptionsType = { export class DiagramObject { private readonly _logger: Logger = log.getLogger('DiagramObject'); + private _group: TransformNode; private _scene: Scene; public grabbed: boolean = false; private _from: string; @@ -177,7 +178,7 @@ export class DiagramObject { position: oldEntity.position, rotation: oldEntity.rotation, scale: oldEntity.scale, - type: 'entity', + type: DiagramEntityType.ENTITY, image: oldEntity.image, template: oldEntity.template, color: oldEntity.color, diff --git a/src/diagram/types/diagramEntity.ts b/src/diagram/types/diagramEntity.ts index 6bece00..e92ab53 100644 --- a/src/diagram/types/diagramEntity.ts +++ b/src/diagram/types/diagramEntity.ts @@ -13,7 +13,8 @@ export enum DiagramEventType { } export enum DiagramEntityType { - USER = "user" + USER = "user", + ENTITY = "entity", } export enum DiagramEventMask { @@ -38,8 +39,8 @@ export type DiagramEvent = { entity?: DiagramEntity; oldColor?: Color3; newColor?: Color3; - } + export type DiagramEntity = { color?: string; id?: string; @@ -50,7 +51,7 @@ export type DiagramEntity = { position?: { x: number, y: number, z: number }; rotation?: { x: number, y: number, z: number }; template?: string; - type: 'entity' + type: DiagramEntityType; text?: string; scale?: { x: number, y: number, z: number }; parent?: string; diff --git a/src/integration/database/database.ts b/src/integration/database/database.ts index e9f368b..f51b7fa 100644 --- a/src/integration/database/database.ts +++ b/src/integration/database/database.ts @@ -1,3 +1,3 @@ -import {DEFAULT_DB_NAME} from "../../util/constants"; +import {DIRECTORY_DB} from "../../util/constants"; -export const db = new PouchDB(DEFAULT_DB_NAME); \ No newline at end of file +export const db = new PouchDB(DIRECTORY_DB); \ No newline at end of file diff --git a/src/integration/database/pouchData.ts b/src/integration/database/pouchData.ts index f3d1825..d7986ba 100644 --- a/src/integration/database/pouchData.ts +++ b/src/integration/database/pouchData.ts @@ -57,6 +57,16 @@ export class PouchData { diagramManager.onDiagramEventObservable.notifyObservers( {type: DiagramEventType.REMOVE, entity: entity}, DiagramEventObserverMask.FROM_DB); }); + this._db.allDocs({include_docs: true}).then((docs) => { + docs.rows.forEach((row) => { + if (row.doc.id != 'metadata') { + diagramManager.onDiagramEventObservable.notifyObservers({ + type: DiagramEventType.ADD, + entity: row.doc + }, DiagramEventObserverMask.FROM_DB); + } + }); + }); } public async remove(id: string) { diff --git a/src/integration/database/pouchdbPersistenceManager.ts b/src/integration/database/pouchdbPersistenceManager.ts index 560b852..5b55564 100644 --- a/src/integration/database/pouchdbPersistenceManager.ts +++ b/src/integration/database/pouchdbPersistenceManager.ts @@ -1,5 +1,5 @@ import PouchDB from 'pouchdb'; -import {DiagramEntity, DiagramEventType} from "../../diagram/types/diagramEntity"; +import {DiagramEntity, DiagramEntityType, DiagramEventType} from "../../diagram/types/diagramEntity"; import {Observable} from "@babylonjs/core"; import axios from "axios"; import {DiagramManager} from "../../diagram/diagramManager"; @@ -93,7 +93,7 @@ export class PouchdbPersistenceManager { this.onDBEntityUpdateObservable.add((evt) => { this._logger.debug(evt); - if (evt.id != 'metadata' && evt.type = 'user') { + if (evt.id != 'metadata' && evt?.type == DiagramEntityType.USER) { diagramManager.onDiagramEventObservable.notifyObservers({ type: DiagramEventType.ADD, entity: evt @@ -263,7 +263,7 @@ export class PouchdbPersistenceManager { let sync = false; let current = getPath(); if (current && current != 'localdb') { - //sync = true; + sync = true; } else { current = 'localdb'; } diff --git a/src/integration/functions/syncDoc.ts b/src/integration/functions/syncDoc.ts index 748aff8..b345c65 100644 --- a/src/integration/functions/syncDoc.ts +++ b/src/integration/functions/syncDoc.ts @@ -1,5 +1,5 @@ import log from "loglevel"; -import {DiagramEntity} from "../../diagram/types/diagramEntity"; +import {DiagramEntity, DiagramEntityType} from "../../diagram/types/diagramEntity"; import {Observable} from "@babylonjs/core"; import {Encryption} from "../encryption"; import {DiagramEventObserverMask} from "../../diagram/types/diagramEventObserverMask"; @@ -19,7 +19,7 @@ export async function syncDoc(info: any, onDBRemoveObservable: Observable { - this.file = event.target.files[0]; + this.fileInput.onchange = (event: InputEvent) => { + this.file = (event.target as HTMLInputElement).files[0]; }; //document.body.appendChild(this.fileInput); this.fileInput.click(); diff --git a/src/react/vrTemplate.tsx b/src/react/vrTemplate.tsx index b2c32db..44d57c2 100644 --- a/src/react/vrTemplate.tsx +++ b/src/react/vrTemplate.tsx @@ -4,18 +4,16 @@ import React from "react"; import {theme} from "./theme"; import {Provider} from "use-pouchdb"; import PouchDB from 'pouchdb'; -import {DEFAULT_DB_NAME} from "../util/constants"; +import {DIRECTORY_DB} from "../util/constants"; -const db = new PouchDB(DEFAULT_DB_NAME); +const db = new PouchDB(DIRECTORY_DB); export default function VrTemplate(props: { children: React.ReactNode }) { return ( - {props.children} - diff --git a/src/util/constants.ts b/src/util/constants.ts index 366d605..67f6908 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -1 +1 @@ -export const DEFAULT_DB_NAME = "mydb"; \ No newline at end of file +export const DIRECTORY_DB = "local-directory"; \ No newline at end of file diff --git a/src/util/customEnvironment.ts b/src/util/customEnvironment.ts index c0ae66f..bd9b27c 100644 --- a/src/util/customEnvironment.ts +++ b/src/util/customEnvironment.ts @@ -19,14 +19,16 @@ import {CustomPhysics} from "./customPhysics"; import {AppConfig} from "./appConfig"; import {GridMaterial} from "@babylonjs/materials"; import {DefaultScene} from "../defaultScene"; +import log from "loglevel"; export class CustomEnvironment { private readonly scene: Scene; private readonly name: string; private readonly _groundMeshObservable: Observable = new Observable(); - + private readonly _logger = log.getLogger('CustomEnvironment'); constructor(name: string = "default", config: AppConfig) { + this._logger.debug('CustomEnvironment constructor', config); this.scene = DefaultScene.Scene; this.name = name; @@ -35,7 +37,7 @@ export class CustomEnvironment { light.groundColor = new Color3(0, 0, 0); light.diffuse = new Color3(1, 1, 1); light.intensity = .8; - const physics = new CustomPhysics(this.scene, config); + const physics = new CustomPhysics(this.scene); physics .initializeAsync() .then(() => { diff --git a/src/util/functions/groundMeshObserver.ts b/src/util/functions/groundMeshObserver.ts index a288c4f..0aab068 100644 --- a/src/util/functions/groundMeshObserver.ts +++ b/src/util/functions/groundMeshObserver.ts @@ -31,7 +31,7 @@ export async function groundMeshObserver(ground: AbstractMesh, enablePointerSelectionOnAllControllers: true } }); - window.addEventListener('enterXr', async (e: CustomEvent) => { + window.addEventListener('enterXr', async () => { await xr.baseExperience.enterXRAsync('immersive-vr', 'local-floor'); logger.debug("Entering XR Experience"); }) diff --git a/src/vrApp.ts b/src/vrApp.ts index bfb408e..05ffe15 100644 --- a/src/vrApp.ts +++ b/src/vrApp.ts @@ -15,7 +15,6 @@ import {CustomEnvironment} from "./util/customEnvironment"; import {Spinner} from "./objects/spinner"; import {addSceneInspector} from "./util/functions/sceneInspector"; import {groundMeshObserver} from "./util/functions/groundMeshObserver"; -import {exportGltf} from "./util/functions/exportGltf"; import {DefaultScene} from "./defaultScene"; import {Introduction} from "./tutorial/introduction"; import {PouchData} from "./integration/database/pouchData"; @@ -23,6 +22,7 @@ import {PouchData} from "./integration/database/pouchData"; const webGpu = false; log.setLevel('error', false); +log.getLogger('PouchdbPersistenceManager').setLevel('debug', false); export default class VrApp { //preTasks = [havokModule]; private logger: Logger = log.getLogger('App'); @@ -58,14 +58,14 @@ export default class VrApp { }); initEnvironment(diagramManager, spinner); addSceneInspector(); - const el = document.querySelector('#download'); + /*const el = document.querySelector('#download'); if (el) { el.addEventListener('click', () => { exportGltf(); }) } else { this.logger.error('Download button not found'); - } + }*/ if (!localStorage.getItem('tutorialCompleted')) { this.logger.info('Starting tutorial'); const intro = new Introduction();