DefaultScene static method to be upper case...added webGPU support (disabled as there appears to be a bug).

This commit is contained in:
Michael Mainguy 2024-04-17 08:18:35 -05:00
parent 8bb77873cc
commit 469d4a5116
21 changed files with 86 additions and 51 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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']

View File

@ -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']);

View File

@ -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;

View File

@ -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');
}
}

View File

@ -154,7 +154,7 @@ export class DiagramConnection {
}
private beforeRender = () => {
this.tick++;
if (this.tick % 5 == 0) {
this.recalculate();
this.setPoints();

View File

@ -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);

View File

@ -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(

View File

@ -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);

View File

@ -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;
}

View File

@ -18,7 +18,7 @@ export class Spinner {
private particleSystem: ParticleSystem;
constructor() {
this._scene = DefaultScene.scene;
this._scene = DefaultScene.Scene;
this.build();
}

View File

@ -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);

View File

@ -26,7 +26,7 @@ export class CustomEnvironment {
private readonly _groundMeshObservable: Observable<GroundMesh> = new Observable<GroundMesh>();
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;

View File

@ -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) {

View File

@ -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');

View File

@ -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();

View File

@ -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);

View File

@ -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();