From 469d4a5116809c636568986c36cbdcd4d6cd0cd3 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Wed, 17 Apr 2024 08:18:35 -0500 Subject: [PATCH] DefaultScene static method to be upper case...added webGPU support (disabled as there appears to be a bug). --- src/controllers/base.ts | 2 +- .../functions/beforeRenderObserver.ts | 2 +- src/controllers/functions/buildRig.ts | 2 +- src/controllers/functions/grabAndClone.ts | 4 +- src/controllers/left.ts | 2 +- src/controllers/right.ts | 2 +- src/controllers/rigplatform.ts | 2 +- src/defaultScene.ts | 31 +++++++---- src/diagram/diagramConnection.ts | 2 +- src/diagram/diagramManager.ts | 2 +- .../functions/buildEntityActionManager.ts | 2 +- src/information/inputTextView.ts | 2 +- src/menus/abstractMenu.ts | 2 +- src/objects/spinner.ts | 2 +- src/toolbox/toolbox.ts | 2 +- src/util/customEnvironment.ts | 6 +- src/util/functions/exportGltf.ts | 2 +- src/util/functions/groundMeshObserver.ts | 2 + src/util/functions/sceneInspctor.ts | 2 +- src/util/functions/updateTextNode.ts | 9 ++- src/vrApp.ts | 55 ++++++++++++------- 21 files changed, 86 insertions(+), 51 deletions(-) diff --git a/src/controllers/base.ts b/src/controllers/base.ts index 9600456..da52550 100644 --- a/src/controllers/base.ts +++ b/src/controllers/base.ts @@ -55,7 +55,7 @@ export class Base { this.logger.setLevel(this.logger.levels.DEBUG); this.controller = controller; this.controllers = diagramManager.controllers; - this.scene = DefaultScene.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 b0faf48..03b79f0 100644 --- a/src/controllers/functions/beforeRenderObserver.ts +++ b/src/controllers/functions/beforeRenderObserver.ts @@ -3,7 +3,7 @@ import {DefaultScene} from "../../defaultScene"; export function beforeRenderObserver() { if (this?.grabbedMesh?.physicsBody) { - const scene = DefaultScene.scene; + const scene = DefaultScene.Scene; const hk = (scene.getPhysicsEngine().getPhysicsPlugin() as HavokPlugin); this.lastPosition = this?.grabbedMesh?.physicsBody?.transformNode.absolutePosition.clone(); if (this.grabbedMeshParentId) { diff --git a/src/controllers/functions/buildRig.ts b/src/controllers/functions/buildRig.ts index a6ca6b1..ca287aa 100644 --- a/src/controllers/functions/buildRig.ts +++ b/src/controllers/functions/buildRig.ts @@ -14,7 +14,7 @@ import {buildStandardMaterial} from "../../materials/functions/buildStandardMate import {DefaultScene} from "../../defaultScene"; export function buildRig(xr: WebXRDefaultExperience): Mesh { - const scene = DefaultScene.scene; + const scene = DefaultScene.Scene; const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: .01}, scene); const cameratransform = new TransformNode("cameraTransform", scene); cameratransform.parent = rigMesh; diff --git a/src/controllers/functions/grabAndClone.ts b/src/controllers/functions/grabAndClone.ts index dac7c73..21a397b 100644 --- a/src/controllers/functions/grabAndClone.ts +++ b/src/controllers/functions/grabAndClone.ts @@ -1,10 +1,12 @@ import {AbstractMesh, TransformNode} from "@babylonjs/core"; import {DiagramManager} from "../../diagram/diagramManager"; +import {DefaultScene} from "../../defaultScene"; export function grabAndClone(diagramManager: DiagramManager, mesh: AbstractMesh, parent: AbstractMesh): { transformNode: TransformNode, newMesh: AbstractMesh } { + const scene = DefaultScene.Scene; const newMesh = diagramManager.createCopy(mesh); - const transformNode = new TransformNode("grabAnchor, this.scene"); + const transformNode = new TransformNode("grabAnchor", scene); transformNode.id = "grabAnchor"; transformNode.position = newMesh.position.clone(); if (newMesh.rotationQuaternion) { diff --git a/src/controllers/left.ts b/src/controllers/left.ts index c3b5be3..3a834b2 100644 --- a/src/controllers/left.ts +++ b/src/controllers/left.ts @@ -18,7 +18,7 @@ export class Left extends Base { constructor(controller: WebXRInputSource, xr: WebXRDefaultExperience, diagramManager: DiagramManager) { super(controller, xr, diagramManager); - const scene = DefaultScene.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 aa23898..4d78707 100644 --- a/src/controllers/right.ts +++ b/src/controllers/right.ts @@ -42,7 +42,7 @@ export class Right extends Base { ) { super(controller, xr, diagramManager); - const scene = DefaultScene.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 60810cc..e3c6910 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -40,7 +40,7 @@ export class Rigplatform { xr: WebXRDefaultExperience, diagramManager: DiagramManager ) { - this.scene = DefaultScene.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 index 6c55d41..056d61a 100644 --- a/src/defaultScene.ts +++ b/src/defaultScene.ts @@ -1,27 +1,38 @@ -import {Scene} from "@babylonjs/core"; +import {Engine, Scene} from "@babylonjs/core"; import log from "loglevel"; const logger = log.getLogger('DefaultScene'); export class DefaultScene { - private static _scene: Scene; + private static _Scene: Scene; - public static get scene(): Scene { - return DefaultScene._scene; + public static get Scene(): Scene { + if (!DefaultScene._Scene) { + logger.error('default scene not yet created'); + if (Engine.LastCreatedScene) { + logger.warn('using last created scene, this may not be what you want, proceed with caution'); + DefaultScene._Scene = Engine.LastCreatedScene; + return DefaultScene._Scene; + } else { + return null; + } + } else { + return DefaultScene._Scene; + } } - static create(scene: Scene) { - if (DefaultScene._scene) { + public static set Scene(scene: Scene) { + if (DefaultScene._Scene) { logger.error('default scene already created, disposing and recreating'); - if (DefaultScene._scene.isDisposed) { + if (DefaultScene._Scene.isDisposed) { logger.warn('default scene is already disposed'); } else { - DefaultScene._scene.dispose(); + DefaultScene._Scene.dispose(); logger.info('default scene disposed'); } - DefaultScene._scene = null; + DefaultScene._Scene = null; } - DefaultScene._scene = scene; + DefaultScene._Scene = scene; logger.info('default scene created'); } } \ No newline at end of file diff --git a/src/diagram/diagramConnection.ts b/src/diagram/diagramConnection.ts index 9bd8d15..9c1dbb5 100644 --- a/src/diagram/diagramConnection.ts +++ b/src/diagram/diagramConnection.ts @@ -154,7 +154,7 @@ export class DiagramConnection { } private beforeRender = () => { - this.tick++; + if (this.tick % 5 == 0) { this.recalculate(); this.setPoints(); diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index cad6ce9..cc2dada 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -29,7 +29,7 @@ export class DiagramManager { constructor() { - this._scene = DefaultScene.scene; + this._scene = DefaultScene.Scene; this._config = new AppConfig(); this._controllers = new Controllers(); this.inputTextView = new InputTextView(this._controllers); diff --git a/src/diagram/functions/buildEntityActionManager.ts b/src/diagram/functions/buildEntityActionManager.ts index 4f52226..05ba218 100644 --- a/src/diagram/functions/buildEntityActionManager.ts +++ b/src/diagram/functions/buildEntityActionManager.ts @@ -5,7 +5,7 @@ import {DefaultScene} from "../../defaultScene"; export function buildEntityActionManager(controllers: Controllers) { const logger = log.getLogger('buildEntityActionManager'); - const actionManager = new ActionManager(DefaultScene.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 e21b2d6..410e988 100644 --- a/src/information/inputTextView.ts +++ b/src/information/inputTextView.ts @@ -24,7 +24,7 @@ export class InputTextView { constructor(controllers: Controllers) { this.controllers = controllers; - this.scene = DefaultScene.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/menus/abstractMenu.ts b/src/menus/abstractMenu.ts index 5109d8b..becbd9a 100644 --- a/src/menus/abstractMenu.ts +++ b/src/menus/abstractMenu.ts @@ -10,7 +10,7 @@ export abstract class AbstractMenu { protected controllers: Controllers; protected constructor(xr: WebXRDefaultExperience, controllers: Controllers) { - this.scene = DefaultScene.scene; + this.scene = DefaultScene.Scene; this.xr = xr; this.controllers = controllers; } diff --git a/src/objects/spinner.ts b/src/objects/spinner.ts index 7185853..53f4456 100644 --- a/src/objects/spinner.ts +++ b/src/objects/spinner.ts @@ -18,7 +18,7 @@ export class Spinner { private particleSystem: ParticleSystem; constructor() { - this._scene = DefaultScene.scene; + this._scene = DefaultScene.Scene; this.build(); } diff --git a/src/toolbox/toolbox.ts b/src/toolbox/toolbox.ts index ae97eb6..efcc9e1 100644 --- a/src/toolbox/toolbox.ts +++ b/src/toolbox/toolbox.ts @@ -28,7 +28,7 @@ export class Toolbox { private axes: AxesViewer; constructor() { - this.scene = DefaultScene.scene; + this.scene = DefaultScene.Scene; this.addPanel = new StackPanel3D(); this.manager = new GUI3DManager(this.scene); this.manager.addControl(this.addPanel); diff --git a/src/util/customEnvironment.ts b/src/util/customEnvironment.ts index 1eb9234..5641870 100644 --- a/src/util/customEnvironment.ts +++ b/src/util/customEnvironment.ts @@ -26,7 +26,7 @@ export class CustomEnvironment { private readonly _groundMeshObservable: Observable = new Observable(); constructor(name: string = "default", config: AppConfig) { - this.scene = DefaultScene.scene; + this.scene = DefaultScene.Scene; this.name = name; const loading = document.querySelector('#loadingGrid'); if (loading) { @@ -121,7 +121,7 @@ export class CustomEnvironment { } async function createPoints(divisions: number = 10, scale: number = 80) { - const scene = DefaultScene.scene; + const scene = DefaultScene.Scene; const half = .5; const increment = 1 / divisions; let x = -half; @@ -156,7 +156,7 @@ async function createPoints(divisions: number = 10, scale: number = 80) { } function createGridMaterial(lineColor: Color3, mainColor: Color3): Material { - const scene = DefaultScene.scene; + const scene = DefaultScene.Scene; const material = new GridMaterial("gridMaterial", scene); material.minorUnitVisibility = .1; material.gridRatio = .1; diff --git a/src/util/functions/exportGltf.ts b/src/util/functions/exportGltf.ts index e47786f..1ce8b97 100644 --- a/src/util/functions/exportGltf.ts +++ b/src/util/functions/exportGltf.ts @@ -1,7 +1,7 @@ import {DefaultScene} from "../../defaultScene"; export function exportGltf() { - const scene = DefaultScene.scene; + 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 77e7c58..a998072 100644 --- a/src/util/functions/groundMeshObserver.ts +++ b/src/util/functions/groundMeshObserver.ts @@ -25,10 +25,12 @@ export async function groundMeshObserver(ground: AbstractMesh, } }, optionalFeatures: true, + pointerSelectionOptions: { enablePointerSelectionOnAllControllers: true } }); + //xr.baseExperience.featuresManager.enableFeature(WebXRFeatureName.LAYERS, "latest", { preferMultiviewOnInit: true }, true, false); const enterButton = (document.querySelector('#enterXR') as HTMLAnchorElement); if (enterButton) { const vrSupported = await xr.baseExperience.sessionManager.isSessionSupportedAsync('immersive-vr'); diff --git a/src/util/functions/sceneInspctor.ts b/src/util/functions/sceneInspctor.ts index f4c8e27..c513231 100644 --- a/src/util/functions/sceneInspctor.ts +++ b/src/util/functions/sceneInspctor.ts @@ -1,7 +1,7 @@ import {DefaultScene} from "../../defaultScene"; export function addSceneInspector() { - const scene = DefaultScene.scene; + const scene = DefaultScene.Scene; window.addEventListener("keydown", (ev) => { if (ev.key == "z") { //voiceManager.startRecording(); diff --git a/src/util/functions/updateTextNode.ts b/src/util/functions/updateTextNode.ts index 19a323a..5e96b2d 100644 --- a/src/util/functions/updateTextNode.ts +++ b/src/util/functions/updateTextNode.ts @@ -1,4 +1,4 @@ -import {AbstractMesh, DynamicTexture, Material, MeshBuilder, StandardMaterial} from "@babylonjs/core"; +import {AbstractMesh, Color3, DynamicTexture, Material, MeshBuilder, StandardMaterial} from "@babylonjs/core"; import log from "loglevel"; @@ -46,9 +46,12 @@ export function updateTextNode(mesh: AbstractMesh, text: string) { height: DTHeight }, mesh.getScene(), false); const mat = new StandardMaterial("mat", mesh.getScene()); - mat.diffuseTexture = dynamicTexture; + mat.diffuseColor = Color3.Black(); + mat.disableLighting = true; + mat.backFaceCulling = true; + mat.emissiveTexture = dynamicTexture; //mat.emissiveColor = Color3.White(); - dynamicTexture.drawText(text, null, null, font, "#000000", "#ffffff", true); + dynamicTexture.drawText(text, null, null, font, "#ffffff", "#000000", true); //Create plane and set dynamic texture as material //const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene()); const plane1 = createPlane(mat, mesh, text, planeWidth, height); diff --git a/src/vrApp.ts b/src/vrApp.ts index d7501c2..f6602f3 100644 --- a/src/vrApp.ts +++ b/src/vrApp.ts @@ -1,4 +1,4 @@ -import {Color3, Engine, FreeCamera, Scene, Vector3} from "@babylonjs/core"; +import {Color3, Engine, FreeCamera, Scene, Vector3, WebGPUEngine} from "@babylonjs/core"; import '@babylonjs/loaders'; import {DiagramManager} from "./diagram/diagramManager"; import log, {Logger} from "loglevel"; @@ -12,30 +12,22 @@ import {buildQuestLink} from "./util/functions/buildQuestLink"; import {exportGltf} from "./util/functions/exportGltf"; import {DefaultScene} from "./defaultScene"; +const webGpu = false; export class VrApp { - private engine: Engine; + private engine: WebGPUEngine | Engine; //preTasks = [havokModule]; private logger: Logger = log.getLogger('App'); constructor() { - 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); - scene.ambientColor = new Color3(.1, .1, .1); - DefaultScene.create(scene); + this.initializeEngine().then(() => { + this.logger.info('Engine initialized'); + }); - log.resetLevel(); - log.setDefaultLevel('error'); - this.logger.debug('App', 'gameCanvas created'); } public async initialize() { - const scene = DefaultScene.scene; + const scene = DefaultScene.Scene; const spinner = new Spinner(); spinner.show(); @@ -90,16 +82,41 @@ export class VrApp { } + private async initializeEngine() { + const canvas = (document.querySelector('#gameCanvas') as HTMLCanvasElement); + if (webGpu) { + this.engine = new WebGPUEngine(canvas); + await (this.engine as WebGPUEngine).initAsync(); + } else { + this.engine = new Engine(canvas, true); + } + + //this.engine.setHardwareScalingLevel(1 / window.devicePixelRatio); + + //window.onresize = () => { + // this.engine.resize(); + // } + /*window.setInterval(() => { + console.log(this.engine.performanceMonitor.instantaneousFPS.toFixed(2) + " fps"); + }, 1000);*/ + const scene = new Scene(this.engine); + scene.ambientColor = new Color3(.1, .1, .1); + DefaultScene.Scene = scene; + + log.resetLevel(); + log.setDefaultLevel('error'); + this.logger.debug('App', 'gameCanvas created'); + await this.initialize(); + } + public async start() { } } const vrApp = new VrApp(); - -vrApp.initialize().then(() => { - buildQuestLink(); -}); +buildQuestLink(); +