From a1248a2e3417e4bb16bff281d74d7aebf09e3553 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Tue, 16 Apr 2024 11:14:32 -0500 Subject: [PATCH] Refactored scene to use DefaultScene. --- src/controllers/base.ts | 3 +- .../functions/beforeRenderObserver.ts | 6 ++- src/controllers/left.ts | 3 +- src/controllers/right.ts | 3 +- src/controllers/rigplatform.ts | 3 +- src/defaultScene.ts | 13 ++++++ src/diagram/diagramManager.ts | 22 ++++----- .../functions/buildEntityActionManager.ts | 7 +-- src/information/inputTextView.ts | 5 +- src/{util => objects}/spinner.ts | 21 +++++---- src/toolbox/toolbox.ts | 7 +-- src/util/appConfig.ts | 4 +- src/util/functions/exportGltf.ts | 5 +- src/util/functions/groundMeshObserver.ts | 2 +- src/util/functions/sceneInspctor.ts | 5 +- src/vrApp.ts | 46 +++++++++---------- 16 files changed, 89 insertions(+), 66 deletions(-) create mode 100644 src/defaultScene.ts rename src/{util => objects}/spinner.ts (85%) diff --git a/src/controllers/base.ts b/src/controllers/base.ts index afd2fda..9600456 100644 --- a/src/controllers/base.ts +++ b/src/controllers/base.ts @@ -26,6 +26,7 @@ import {motionControllerObserver} from "./functions/motionControllerObserver"; import {handleWasGrabbed} from "./functions/handleWasGrabbed"; import {buildDrop} from "./functions/buildDrop"; import {pointable} from "./functions/pointable"; +import {DefaultScene} from "../defaultScene"; const CLICK_TIME = 300; export class Base { @@ -54,7 +55,7 @@ export class Base { this.logger.setLevel(this.logger.levels.DEBUG); this.controller = controller; this.controllers = diagramManager.controllers; - this.scene = diagramManager.scene; + this.scene = DefaultScene.scene; this.xr = xr; this.diagramManager = diagramManager; this.scene.onBeforeRenderObservable.add(beforeRenderObserver, -1, false, this); diff --git a/src/controllers/functions/beforeRenderObserver.ts b/src/controllers/functions/beforeRenderObserver.ts index 2a5f615..b0faf48 100644 --- a/src/controllers/functions/beforeRenderObserver.ts +++ b/src/controllers/functions/beforeRenderObserver.ts @@ -1,11 +1,13 @@ import {HavokPlugin} from "@babylonjs/core"; +import {DefaultScene} from "../../defaultScene"; export function beforeRenderObserver() { if (this?.grabbedMesh?.physicsBody) { - const hk = (this.scene.getPhysicsEngine().getPhysicsPlugin() as HavokPlugin); + const scene = DefaultScene.scene; + const hk = (scene.getPhysicsEngine().getPhysicsPlugin() as HavokPlugin); this.lastPosition = this?.grabbedMesh?.physicsBody?.transformNode.absolutePosition.clone(); if (this.grabbedMeshParentId) { - const parent = this.scene.getTransformNodeById(this.grabbedMeshParentId); + const parent = scene.getTransformNodeById(this.grabbedMeshParentId); if (parent) { hk.setPhysicsBodyTransformation(this.grabbedMesh.physicsBody, parent); hk.sync(this.grabbedMesh.physicsBody); diff --git a/src/controllers/left.ts b/src/controllers/left.ts index b6994f3..c3b5be3 100644 --- a/src/controllers/left.ts +++ b/src/controllers/left.ts @@ -11,13 +11,14 @@ import {ControllerEventType} from "./controllers"; import log from "loglevel"; import {DiagramManager} from "../diagram/diagramManager"; import {RoundButton} from "../objects/roundButton"; +import {DefaultScene} from "../defaultScene"; const logger = log.getLogger('Left'); export class Left extends Base { constructor(controller: WebXRInputSource, xr: WebXRDefaultExperience, diagramManager: DiagramManager) { super(controller, xr, diagramManager); - const scene = diagramManager.scene; + const scene = DefaultScene.scene; this.controller.onMotionControllerInitObservable.add((init) => { if (init.components['xr-standard-thumbstick']) { init.components['xr-standard-thumbstick'] diff --git a/src/controllers/right.ts b/src/controllers/right.ts index 0122185..aa23898 100644 --- a/src/controllers/right.ts +++ b/src/controllers/right.ts @@ -12,6 +12,7 @@ import {ControllerEventType} from "./controllers"; import {DiagramManager} from "../diagram/diagramManager"; import {RoundButton} from "../objects/roundButton"; import log from "loglevel"; +import {DefaultScene} from "../defaultScene"; const logger = log.getLogger("Right"); export class Right extends Base { @@ -41,7 +42,7 @@ export class Right extends Base { ) { super(controller, xr, diagramManager); - const scene = diagramManager.scene; + const scene = DefaultScene.scene; this.controller.onMotionControllerInitObservable.add((init) => { this.initTrigger(init.components['xr-standard-trigger']); diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index dd0d31f..253ba66 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -5,6 +5,7 @@ import {ControllerEvent, ControllerEventType, Controllers} from "./controllers"; import log from "loglevel"; import {DiagramManager} from "../diagram/diagramManager"; import {buildRig} from "./functions/buildRig"; +import {DefaultScene} from "../defaultScene"; const RIGHT = "right"; const LEFT = "left"; @@ -39,7 +40,7 @@ export class Rigplatform { xr: WebXRDefaultExperience, diagramManager: DiagramManager ) { - this.scene = diagramManager.scene; + this.scene = DefaultScene.scene; this.diagramManager = diagramManager; this.controllers = diagramManager.controllers; this.xr = xr; diff --git a/src/defaultScene.ts b/src/defaultScene.ts new file mode 100644 index 0000000..af4d860 --- /dev/null +++ b/src/defaultScene.ts @@ -0,0 +1,13 @@ +import {Scene} from "@babylonjs/core"; + +export class DefaultScene { + private static _scene: Scene; + + public static get scene(): Scene { + return DefaultScene._scene; + } + + static create(scene: Scene) { + DefaultScene._scene = scene; + } +} \ No newline at end of file diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index de77e3e..cad6ce9 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -4,7 +4,6 @@ import log from "loglevel"; import {Controllers} from "../controllers/controllers"; import {AppConfig} from "../util/appConfig"; import {Toolbox} from "../toolbox/toolbox"; -import {PresentationManager} from "./presentationManager"; import {diagramEventHandler} from "./functions/diagramEventHandler"; import {deepCopy} from "../util/functions/deepCopy"; import {applyPhysics} from "./functions/diagramShapePhysics"; @@ -14,13 +13,13 @@ import {v4 as uuidv4} from 'uuid'; import {buildEntityActionManager} from "./functions/buildEntityActionManager"; import {isDiagramEntity} from "./functions/isDiagramEntity"; import {InputTextView} from "../information/inputTextView"; +import {DefaultScene} from "../defaultScene"; export class DiagramManager { public readonly _config: AppConfig; private readonly _controllers: Controllers; private readonly diagramEntityActionManager: ActionManager; - private presentationManager: PresentationManager; private readonly inputTextView: InputTextView; public readonly onDiagramEventObservable: Observable = new Observable(); @@ -29,12 +28,13 @@ export class DiagramManager { private readonly _scene: Scene; - constructor(scene: Scene) { + constructor() { + this._scene = DefaultScene.scene; this._config = new AppConfig(); this._controllers = new Controllers(); - this.inputTextView = new InputTextView(scene, this._controllers); + this.inputTextView = new InputTextView(this._controllers); this.inputTextView.onTextObservable.add((evt) => { - const mesh = scene.getMeshById(evt.id); + const mesh = this._scene.getMeshById(evt.id); if (mesh) { const entity = toDiagramEntity(mesh); entity.text = evt.text; @@ -47,11 +47,9 @@ export class DiagramManager { } }); - - this._scene = scene; - this.toolbox = new Toolbox(scene); - this.presentationManager = new PresentationManager(this._scene); - this.diagramEntityActionManager = buildEntityActionManager(this._scene, this._controllers); + this.toolbox = new Toolbox(); + //this.presentationManager = new PresentationManager(this._scene); + this.diagramEntityActionManager = buildEntityActionManager(this._controllers); if (this.onDiagramEventObservable.hasObservers()) { this.logger.warn("onDiagramEventObservable already has Observers, you should be careful"); @@ -66,10 +64,10 @@ export class DiagramManager { this.onDiagramEventObservable.add(this.onDiagramEvent, 1, true, this); this.logger.debug("DiagramManager constructed"); - scene.onMeshRemovedObservable.add((mesh) => { + this._scene.onMeshRemovedObservable.add((mesh) => { if (isDiagramEntity(mesh)) { if (mesh.metadata.template != '#connection-template') { - scene.meshes.forEach((m) => { + this._scene.meshes.forEach((m) => { if (m?.metadata?.to == mesh.id || m?.metadata?.from == mesh.id) { this.logger.debug("removing connection", m.id); this.onDiagramEventObservable.notifyObservers({ diff --git a/src/diagram/functions/buildEntityActionManager.ts b/src/diagram/functions/buildEntityActionManager.ts index 75e74dd..4f52226 100644 --- a/src/diagram/functions/buildEntityActionManager.ts +++ b/src/diagram/functions/buildEntityActionManager.ts @@ -1,10 +1,11 @@ -import {ActionManager, ExecuteCodeAction, Scene} from "@babylonjs/core"; +import {ActionManager, ExecuteCodeAction} from "@babylonjs/core"; import {ControllerEventType, Controllers} from "../../controllers/controllers"; import log from "loglevel"; +import {DefaultScene} from "../../defaultScene"; -export function buildEntityActionManager(scene: Scene, controllers: Controllers) { +export function buildEntityActionManager(controllers: Controllers) { const logger = log.getLogger('buildEntityActionManager'); - const actionManager = new ActionManager(scene); + const actionManager = new ActionManager(DefaultScene.scene); /*actionManager.registerAction( new PlaySoundAction(ActionManager.OnPointerOverTrigger, sounds.tick));*/ actionManager.registerAction( diff --git a/src/information/inputTextView.ts b/src/information/inputTextView.ts index 5afc6cb..e21b2d6 100644 --- a/src/information/inputTextView.ts +++ b/src/information/inputTextView.ts @@ -3,6 +3,7 @@ import log, {Logger} from "loglevel"; import {AdvancedDynamicTexture, Control, InputText, VirtualKeyboard} from "@babylonjs/gui"; import {ControllerEventType, Controllers} from "../controllers/controllers"; import {Handle} from "../objects/handle"; +import {DefaultScene} from "../defaultScene"; export type TextEvent = { id: string; @@ -21,9 +22,9 @@ export class InputTextView { private diagramMesh: AbstractMesh; private keyboard: VirtualKeyboard; - constructor(scene: Scene, controllers: Controllers) { + constructor(controllers: Controllers) { this.controllers = controllers; - this.scene = scene; + this.scene = DefaultScene.scene; this.inputMesh = MeshBuilder.CreatePlane("input", {width: 1, height: .5}, this.scene); this.handle = new Handle(this.inputMesh); diff --git a/src/util/spinner.ts b/src/objects/spinner.ts similarity index 85% rename from src/util/spinner.ts rename to src/objects/spinner.ts index 2bf6a12..7185853 100644 --- a/src/util/spinner.ts +++ b/src/objects/spinner.ts @@ -10,14 +10,15 @@ import { StandardMaterial, Texture } from "@babylonjs/core"; +import {DefaultScene} from "../defaultScene"; export class Spinner { - private readonly scene: Scene; + private readonly _scene: Scene; private spinner: AbstractMesh; private particleSystem: ParticleSystem; - constructor(scene: Scene) { - this.scene = scene; + constructor() { + this._scene = DefaultScene.scene; this.build(); } @@ -32,9 +33,9 @@ export class Spinner { } private build() { - const spinner: AbstractMesh = MeshBuilder.CreateSphere("spinner", {diameter: 2}, this.scene); - const material = new StandardMaterial("spinner", this.scene); - const text = new DynamicTexture("spinner", {width: 1024, height: 1024}, this.scene, false); + const spinner: AbstractMesh = MeshBuilder.CreateSphere("spinner", {diameter: 2}, this._scene); + const material = new StandardMaterial("spinner", this._scene); + const text = new DynamicTexture("spinner", {width: 1024, height: 1024}, this._scene, false); text.drawText("Please Wait", 250, 500, "bold 150px Segoe UI", "white", "transparent", true, true); spinner.rotation.z = Math.PI; material.diffuseTexture = text; @@ -52,23 +53,23 @@ export class Spinner { }); rotate.setKeys(keys); spinner.animations.push(rotate); - this.scene.beginAnimation(spinner, 0, 30, true); + this._scene.beginAnimation(spinner, 0, 30, true); material.alpha = .9; spinner.material = material; let particleSystem; if (GPUParticleSystem.IsSupported) { - particleSystem = new GPUParticleSystem("particles", {capacity: 100000}, this.scene); + particleSystem = new GPUParticleSystem("particles", {capacity: 100000}, this._scene); particleSystem.activeParticleCount = 2048; } else { - particleSystem = new ParticleSystem("particles", 2048, this.scene); + particleSystem = new ParticleSystem("particles", 2048, this._scene); } particleSystem.emitRate = 10; const emitter = new SphereParticleEmitter(.9); emitter.radiusRange = .2; particleSystem.particleEmitterType = emitter; - particleSystem.particleTexture = new Texture("/assets/textures/flare.png", this.scene); + particleSystem.particleTexture = new Texture("/assets/textures/flare.png", this._scene); particleSystem.minEmitPower = .1; diff --git a/src/toolbox/toolbox.ts b/src/toolbox/toolbox.ts index c386299..ae97eb6 100644 --- a/src/toolbox/toolbox.ts +++ b/src/toolbox/toolbox.ts @@ -3,6 +3,7 @@ import {GUI3DManager, StackPanel3D,} from "@babylonjs/gui"; import {buildColor} from "./functions/buildColor"; import log from "loglevel"; import {Handle} from "../objects/handle"; +import {DefaultScene} from "../defaultScene"; const colors: string[] = [ "#222222", "#8b4513", "#006400", "#778899", @@ -26,10 +27,10 @@ export class Toolbox { new Observable<{ oldColor: string; newColor: string }>() private axes: AxesViewer; - constructor(scene: Scene) { - this.scene = scene; + constructor() { + this.scene = DefaultScene.scene; this.addPanel = new StackPanel3D(); - this.manager = new GUI3DManager(scene); + this.manager = new GUI3DManager(this.scene); this.manager.addControl(this.addPanel); this.toolboxBaseNode = new TransformNode("toolbox", this.scene); this.handle = new Handle(this.toolboxBaseNode); diff --git a/src/util/appConfig.ts b/src/util/appConfig.ts index ae2c0a8..d301084 100644 --- a/src/util/appConfig.ts +++ b/src/util/appConfig.ts @@ -9,14 +9,14 @@ export class AppConfig { this._currentConfig = { id: 1, gridSnap: .1, - rotateSnap: 45, + rotateSnap: 90, createSnap: .1, turnSnap: 22.5, newRelicKey: null, newRelicAccount: null, physicsEnabled: false, demoCompleted: false, - flyMode: false + flyMode: true }; this.onConfigChangedObservable.add((config) => { this._currentConfig = config; diff --git a/src/util/functions/exportGltf.ts b/src/util/functions/exportGltf.ts index 56d5eb9..e47786f 100644 --- a/src/util/functions/exportGltf.ts +++ b/src/util/functions/exportGltf.ts @@ -1,6 +1,7 @@ -import {Scene} from "@babylonjs/core"; +import {DefaultScene} from "../../defaultScene"; -export function exportGltf(scene: Scene) { +export function exportGltf() { + const scene = DefaultScene.scene; import("@babylonjs/serializers").then((serializers) => { serializers.GLTF2Export.GLBAsync(scene, 'diagram.glb', { shouldExportNode: function (node) { diff --git a/src/util/functions/groundMeshObserver.ts b/src/util/functions/groundMeshObserver.ts index 7c9d569..8621e90 100644 --- a/src/util/functions/groundMeshObserver.ts +++ b/src/util/functions/groundMeshObserver.ts @@ -4,7 +4,7 @@ import {WebController} from "../../controllers/webController"; import {ConfigMenu} from "../../menus/configMenu"; import {Rigplatform} from "../../controllers/rigplatform"; import {DiagramManager} from "../../diagram/diagramManager"; -import {Spinner} from "../spinner"; +import {Spinner} from "../../objects/spinner"; const logger = log.getLogger('groungMeshObserver'); diff --git a/src/util/functions/sceneInspctor.ts b/src/util/functions/sceneInspctor.ts index 8c521b4..f4c8e27 100644 --- a/src/util/functions/sceneInspctor.ts +++ b/src/util/functions/sceneInspctor.ts @@ -1,4 +1,7 @@ -export function addSceneInspector(scene) { +import {DefaultScene} from "../../defaultScene"; + +export function addSceneInspector() { + const scene = DefaultScene.scene; window.addEventListener("keydown", (ev) => { if (ev.key == "z") { //voiceManager.startRecording(); diff --git a/src/vrApp.ts b/src/vrApp.ts index 9228528..68d4547 100644 --- a/src/vrApp.ts +++ b/src/vrApp.ts @@ -4,45 +4,43 @@ import {DiagramManager} from "./diagram/diagramManager"; import log, {Logger} from "loglevel"; import {GamepadManager} from "./controllers/gamepadManager"; import {CustomEnvironment} from "./util/customEnvironment"; -import {Spinner} from "./util/spinner"; +import {Spinner} from "./objects/spinner"; import {PouchdbPersistenceManager} from "./integration/pouchdbPersistenceManager"; import {addSceneInspector} from "./util/functions/sceneInspctor"; import {groundMeshObserver} from "./util/functions/groundMeshObserver"; -import {MainMenu} from "./menus/mainMenu"; import {buildQuestLink} from "./util/functions/buildQuestLink"; import {exportGltf} from "./util/functions/exportGltf"; +import {DefaultScene} from "./defaultScene"; export class VrApp { - private scene: Scene; + private engine: Engine; //preTasks = [havokModule]; private logger: Logger = log.getLogger('App'); constructor() { - //log.getLogger('App').setLevel('debug'); - //log.getLogger('DiagramManager').setLevel('debug'); - log.resetLevel(); - log.setDefaultLevel('error'); - - const canvas = document.querySelector('#gameCanvas'); - this.logger.debug('App', 'gameCanvas created'); - } - - public async initialize(canvas: HTMLCanvasElement) { + const canvas = (document.querySelector('#gameCanvas') as HTMLCanvasElement); this.engine = new Engine(canvas, true); this.engine.setHardwareScalingLevel(1 / window.devicePixelRatio); window.onresize = () => { this.engine.resize(); } const scene = new Scene(this.engine); - this.scene = scene; - this.scene.ambientColor = new Color3(.1, .1, .1); + scene.ambientColor = new Color3(.1, .1, .1); + DefaultScene.create(scene); - const spinner = new Spinner(scene); + log.resetLevel(); + log.setDefaultLevel('error'); + this.logger.debug('App', 'gameCanvas created'); + } + + public async initialize() { + const scene = DefaultScene.scene; + + const spinner = new Spinner(); spinner.show(); - - const diagramManager = new DiagramManager(scene); + const diagramManager = new DiagramManager(); const db = new PouchdbPersistenceManager(); db.setDiagramManager(diagramManager); db.configObserver.add((newConfig) => { @@ -72,18 +70,18 @@ export class VrApp { */ - addSceneInspector(scene); - const mainMenu = new MainMenu(scene); + addSceneInspector(); + //const mainMenu = new MainMenu(scene); const el = document.querySelector('#download'); if (el) { el.addEventListener('click', () => { - exportGltf(scene); + exportGltf(); }) } this.logger.info('keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer'); let i = 0; this.engine.runRenderLoop(() => { - this.scene.render(); + scene.render(); if (i++ % 60 == 0) { } @@ -98,8 +96,8 @@ export class VrApp { } const vrApp = new VrApp(); -const canvas = (document.querySelector('#gameCanvas') as HTMLCanvasElement); -vrApp.initialize(canvas).then(() => { + +vrApp.initialize().then(() => { buildQuestLink(); });