소스 검색

linting and docs

Trevor Baron 6 년 전
부모
커밋
d106c69a6e

+ 1 - 0
dist/preview release/what's new.md

@@ -25,6 +25,7 @@
 - Effect renderer to render one or multiple shader effects to a texture ([TrevorDev](https://github.com/TrevorDev))
 - Added url parameters to web request modifiers ([PierreLeBlond](https://github.com/PierreLeBlond))
 - WebXR updated to spec as of June 27th ([TrevorDev](https://github.com/TrevorDev))
+- WebXR webVR parity helpers ([TrevorDev](https://github.com/TrevorDev))
 
 ### Engine
 - Morph targets now can morph UV channel as well ([Deltakosh](https://github.com/deltakosh/))

+ 10 - 8
src/Cameras/XR/webXRController.ts

@@ -17,6 +17,9 @@ export class WebXRController {
      */
     public pointer: AbstractMesh;
 
+    /**
+     * Event that fires when the controller is removed/disposed
+     */
     public onDisposeObservable = new Observable<{}>();
 
     private _tmpMatrix = new Matrix();
@@ -89,16 +92,15 @@ export class WebXRController {
      * Gets a world space ray coming from the controller
      * @param result the resulting ray
      */
-    public getWorldPointerRayToRef(result:Ray){
+    public getWorldPointerRayToRef(result: Ray) {
         // Force update to ensure picked point is synced with ray
-        let worldMatrix = this.pointer.computeWorldMatrix(true)
-        worldMatrix.decompose(undefined, this._tmpQuaternion, undefined)
-        this._tmpVector.set(0,0,1)
-        this._tmpVector.rotateByQuaternionToRef(this._tmpQuaternion, this._tmpVector)
-        result.origin = this.pointer.absolutePosition
-        result.direction.copyFrom(this._tmpVector)
+        let worldMatrix = this.pointer.computeWorldMatrix(true);
+        worldMatrix.decompose(undefined, this._tmpQuaternion, undefined);
+        this._tmpVector.set(0, 0, 1);
+        this._tmpVector.rotateByQuaternionToRef(this._tmpQuaternion, this._tmpVector);
+        result.origin = this.pointer.absolutePosition;
+        result.direction.copyFrom(this._tmpVector);
         result.length = 1000;
-        return result;
     }
 
     /**

+ 26 - 26
src/Cameras/XR/webXRControllerModelLoader.ts

@@ -1,4 +1,4 @@
-import { Quaternion} from '../../Maths/math';
+import { Quaternion } from '../../Maths/math';
 import { WindowsMotionController } from '../../Gamepads/Controllers/windowsMotionController';
 import { OculusTouchController } from '../../Gamepads/Controllers/oculusTouchController';
 import { WebXRInput } from './webXRInput';
@@ -11,34 +11,34 @@ export class WebXRControllerModelLoader {
      * Creates the WebXRControllerModelLoader
      * @param input xr input that creates the controllers
      */
-    constructor(input: WebXRInput){
-        input.onControllerAddedObservable.add((c)=>{
-            if(c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-touch"){
+    constructor(input: WebXRInput) {
+        input.onControllerAddedObservable.add((c) => {
+            if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-touch") {
                 let controllerModel = new OculusTouchController(c.inputSource.gamepad);
-                controllerModel.hand = c.inputSource.handedness
-                controllerModel.isXR = true
-                controllerModel.initControllerMesh(c.grip!.getScene(), (m)=>{
-                    controllerModel.mesh!.parent = c.grip!
-                    controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(0,Math.PI,0);
-                })
-            }else if(c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-quest"){
+                controllerModel.hand = c.inputSource.handedness;
+                controllerModel.isXR = true;
+                controllerModel.initControllerMesh(c.grip!.getScene(), (m) => {
+                    controllerModel.mesh!.parent = c.grip!;
+                    controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);
+                });
+            }else if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-quest") {
                 OculusTouchController._IsQuest = true;
                 let controllerModel = new OculusTouchController(c.inputSource.gamepad);
-                controllerModel.hand = c.inputSource.handedness
-                controllerModel.isXR = true
-                controllerModel.initControllerMesh(c.grip!.getScene(), (m)=>{
-                    controllerModel.mesh!.parent = c.grip!
-                    controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(Math.PI/-4,Math.PI,0);
-                })
-            }else{
+                controllerModel.hand = c.inputSource.handedness;
+                controllerModel.isXR = true;
+                controllerModel.initControllerMesh(c.grip!.getScene(), (m) => {
+                    controllerModel.mesh!.parent = c.grip!;
+                    controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(Math.PI / -4, Math.PI, 0);
+                });
+            }else {
                 let controllerModel = new WindowsMotionController(c.inputSource.gamepad);
-                controllerModel.hand = c.inputSource.handedness
-                controllerModel.isXR = true
-                controllerModel.initControllerMesh(c.grip!.getScene(), (m)=>{
-                    controllerModel.mesh!.parent = c.grip!
-                    controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(0,Math.PI,0);
-                })
-            } 
-        })
+                controllerModel.hand = c.inputSource.handedness;
+                controllerModel.isXR = true;
+                controllerModel.initControllerMesh(c.grip!.getScene(), (m) => {
+                    controllerModel.mesh!.parent = c.grip!;
+                    controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);
+                });
+            }
+        });
     }
 }

+ 33 - 31
src/Cameras/XR/webXRControllerPointerSelection.ts

@@ -9,34 +9,36 @@ import { WebXRInput } from './webXRInput';
  * Handles pointer input automatically for the pointer of XR controllers
  */
 export class WebXRControllerPointerSelection {
-    
-    public static _idCounter = 0;
-    
+    private static _idCounter = 0;
     private _tmpRay = new Ray(new Vector3(), new Vector3());
-    constructor(input: WebXRInput){
-        
-        input.onControllerAddedObservable.add((c)=>{
-            let scene = c.pointer.getScene();
+
+    /**
+     * Creates a WebXRControllerPointerSelection
+     * @param input input manager to setup pointer selection
+     */
+    constructor(input: WebXRInput) {
+        input.onControllerAddedObservable.add((controller) => {
+            let scene = controller.pointer.getScene();
 
             let laserPointer: Mesh;
             let cursorMesh: Mesh;
             let triggerDown = false;
-            let id:number;
+            let id: number;
             id = WebXRControllerPointerSelection._idCounter++;
 
             // Create a laser pointer for the XR controller
             laserPointer = Mesh.CreateCylinder("laserPointer", 1, 0.0002, 0.004, 20, 1, scene, false);
-            laserPointer.parent = c.pointer
+            laserPointer.parent = controller.pointer;
             let laserPointerMaterial = new StandardMaterial("laserPointerMat", scene);
             laserPointerMaterial.emissiveColor = new Color3(0.7, 0.7, 0.7);
             laserPointerMaterial.alpha = 0.6;
             laserPointer.material = laserPointerMaterial;
             laserPointer.rotation.x = Math.PI / 2;
-            this._updatePointerDistance(laserPointer,1)
+            this._updatePointerDistance(laserPointer, 1);
             laserPointer.isPickable = false;
 
             // Create a gaze tracker for the  XR controlelr
-            cursorMesh = Mesh.CreateTorus("gazeTracker", 0.0035*3, 0.0025*3, 20, scene, false);
+            cursorMesh = Mesh.CreateTorus("gazeTracker", 0.0035 * 3, 0.0025 * 3, 20, scene, false);
             cursorMesh.bakeCurrentTransformIntoVertices();
             cursorMesh.isPickable = false;
             cursorMesh.isVisible = false;
@@ -46,31 +48,31 @@ export class WebXRControllerPointerSelection {
             targetMat.backFaceCulling = false;
             cursorMesh.material = targetMat;
 
-            let renderObserver = scene.onBeforeRenderObservable.add(()=>{     
-                // Every frame check collisions/input        
-                c.getWorldPointerRayToRef(this._tmpRay)
-                let pick = scene.pickWithRay(this._tmpRay)
-                if(pick){
-                    if(c.inputSource.gamepad && c.inputSource.gamepad.buttons[0] && c.inputSource.gamepad.buttons[0].value > 0.7){
-                        if(!triggerDown){
+            let renderObserver = scene.onBeforeRenderObservable.add(() => {
+                // Every frame check collisions/input
+                controller.getWorldPointerRayToRef(this._tmpRay);
+                let pick = scene.pickWithRay(this._tmpRay);
+                if (pick) {
+                    if (controller.inputSource.gamepad && controller.inputSource.gamepad.buttons[0] && controller.inputSource.gamepad.buttons[0].value > 0.7) {
+                        if (!triggerDown) {
                             scene.simulatePointerDown(pick, { pointerId: id });
                         }
                         triggerDown = true;
-                    }else{
-                        if(triggerDown){
+                    }else {
+                        if (triggerDown) {
                             scene.simulatePointerUp(pick, { pointerId: id });
                         }
                         triggerDown = false;
                     }
                     scene.simulatePointerMove(pick, { pointerId: id });
                 }
-                
-                if(pick && pick.pickedPoint && pick.hit){
+
+                if (pick && pick.pickedPoint && pick.hit) {
                     // Update laser state
-                    this._updatePointerDistance(laserPointer, pick.distance)
+                    this._updatePointerDistance(laserPointer, pick.distance);
 
                     // Update cursor state
-                    cursorMesh.position.copyFrom(pick.pickedPoint)
+                    cursorMesh.position.copyFrom(pick.pickedPoint);
                     cursorMesh.scaling.x = Math.sqrt(pick.distance);
                     cursorMesh.scaling.y = Math.sqrt(pick.distance);
                     cursorMesh.scaling.z = Math.sqrt(pick.distance);
@@ -86,18 +88,18 @@ export class WebXRControllerPointerSelection {
                         cursorMesh.position.addInPlace(pickNormal.scale(deltaFighting));
                     }
                     cursorMesh.isVisible = true;
-                }else{
+                }else {
                     cursorMesh.isVisible = false;
                 }
-            })
+            });
 
-            c.onDisposeObservable.addOnce(()=>{
+            controller.onDisposeObservable.addOnce(() => {
                 laserPointer.dispose();
                 cursorMesh.dispose();
 
-                scene.onBeforeRenderObservable.remove(renderObserver)
-            })
-        })
+                scene.onBeforeRenderObservable.remove(renderObserver);
+            });
+        });
     }
 
     private _convertNormalToDirectionOfRay(normal: Nullable<Vector3>, ray: Ray) {
@@ -110,7 +112,7 @@ export class WebXRControllerPointerSelection {
         return normal;
     }
 
-    private _updatePointerDistance(_laserPointer:Mesh, distance: number = 100) {
+    private _updatePointerDistance(_laserPointer: Mesh, distance: number = 100) {
         _laserPointer.scaling.y = distance;
         _laserPointer.position.z = distance / 2;
     }

+ 63 - 64
src/Cameras/XR/webXRControllerTeleportation.ts

@@ -19,12 +19,12 @@ export class WebXRControllerTeleportation {
     private _tmpVector = new Vector3();
 
     /**
-     * 
-     * @param input 
-     * @param floorMeshes 
+     * Creates a WebXRControllerTeleportation
+     * @param input input manager to add teleportation to
+     * @param floorMeshes floormeshes which can be teleported to
      */
-    constructor(input: WebXRInput, public floorMeshes:Array<AbstractMesh> = []){
-        input.onControllerAddedObservable.add((c)=>{
+    constructor(input: WebXRInput, floorMeshes: Array<AbstractMesh> = []) {
+        input.onControllerAddedObservable.add((c) => {
             let scene = c.pointer.getScene();
 
             let forwardReadyToTeleport = false;
@@ -80,103 +80,102 @@ export class WebXRControllerTeleportation {
             scene.beginAnimation(torus, 0, 60, true);
 
             // Handle user input on every frame
-            let renderObserver = scene.onBeforeRenderObservable.add(()=>{
+            let renderObserver = scene.onBeforeRenderObservable.add(() => {
                 // Move the teleportationTarget to where the user is targetting to teleport to
-                if(forwardReadyToTeleport){
-                    c.getWorldPointerRayToRef(this._tmpRay)
-                    let pick = scene.pickWithRay(this._tmpRay, (o)=>{
+                if (forwardReadyToTeleport) {
+                    c.getWorldPointerRayToRef(this._tmpRay);
+                    let pick = scene.pickWithRay(this._tmpRay, (o) => {
                         return floorMeshes.indexOf(o) !== -1;
-                    })
-                    if(pick && pick.pickedPoint){
+                    });
+                    if (pick && pick.pickedPoint) {
                         // To avoid z-fighting
                         teleportationTarget.position.copyFrom(pick.pickedPoint);
                         teleportationTarget.position.y += 0.002;
                     }
                     teleportationTarget.isVisible = true;
                     (<Mesh>teleportationTarget.getChildren()[0]).isVisible = true;
-                }else{
+                }else {
                     teleportationTarget.isVisible = false;
                     (<Mesh>teleportationTarget.getChildren()[0]).isVisible = false;
                 }
 
-                if(c.inputSource.gamepad){
-                    if(c.inputSource.gamepad.axes[1]){
+                if (c.inputSource.gamepad) {
+                    if (c.inputSource.gamepad.axes[1]) {
                         // Forward teleportation
-                        if(c.inputSource.gamepad.axes[1] < -0.7){
-                            forwardReadyToTeleport = true
-                        }else{
-                            if(forwardReadyToTeleport){
+                        if (c.inputSource.gamepad.axes[1] < -0.7) {
+                            forwardReadyToTeleport = true;
+                        }else {
+                            if (forwardReadyToTeleport) {
                                 // Teleport the users feet to where they targetted
-                                this._tmpVector.copyFrom(teleportationTarget.position)
-                                this._tmpVector.y += input.xrExperienceHelper.camera.position.y;
-                                input.xrExperienceHelper.setPositionOfCameraUsingContainer(this._tmpVector)
+                                this._tmpVector.copyFrom(teleportationTarget.position);
+                                this._tmpVector.y += input.baseExperience.camera.position.y;
+                                input.baseExperience.setPositionOfCameraUsingContainer(this._tmpVector);
                             }
-                            forwardReadyToTeleport = false
+                            forwardReadyToTeleport = false;
                         }
 
                         // Backward teleportation
-                        if(c.inputSource.gamepad.axes[1] > 0.7){
-                            backwardReadyToTeleport = true
-                        }else{
-                            if(backwardReadyToTeleport){
+                        if (c.inputSource.gamepad.axes[1] > 0.7) {
+                            backwardReadyToTeleport = true;
+                        }else {
+                            if (backwardReadyToTeleport) {
                                 // Cast a ray down from behind the user
-                                let camMat = input.xrExperienceHelper.camera.computeWorldMatrix();
-                                let q = new Quaternion()
-                                camMat.decompose(undefined, q, this._tmpRay.origin)
-                                this._tmpVector.set(0,0,-1);
-                                this._tmpVector.rotateByQuaternionToRef(q, this._tmpVector)
+                                let camMat = input.baseExperience.camera.computeWorldMatrix();
+                                let q = new Quaternion();
+                                camMat.decompose(undefined, q, this._tmpRay.origin);
+                                this._tmpVector.set(0, 0, -1);
+                                this._tmpVector.rotateByQuaternionToRef(q, this._tmpVector);
                                 this._tmpVector.y = 0;
-                                this._tmpVector.normalize()
+                                this._tmpVector.normalize();
                                 this._tmpVector.y = -1.5;
-                                this._tmpVector.normalize()
-                                this._tmpRay.direction.copyFrom(this._tmpVector)
-                                let pick = scene.pickWithRay(this._tmpRay, (o)=>{
+                                this._tmpVector.normalize();
+                                this._tmpRay.direction.copyFrom(this._tmpVector);
+                                let pick = scene.pickWithRay(this._tmpRay, (o) => {
                                     return floorMeshes.indexOf(o) !== -1;
-                                })
+                                });
 
-                                if(pick && pick.pickedPoint){
+                                if (pick && pick.pickedPoint) {
                                     // Teleport the users feet to where they targetted
-                                    this._tmpVector.copyFrom(pick.pickedPoint)
-                                    this._tmpVector.y += input.xrExperienceHelper.camera.position.y;
-                                    input.xrExperienceHelper.setPositionOfCameraUsingContainer(this._tmpVector)
+                                    this._tmpVector.copyFrom(pick.pickedPoint);
+                                    this._tmpVector.y += input.baseExperience.camera.position.y;
+                                    input.baseExperience.setPositionOfCameraUsingContainer(this._tmpVector);
                                 }
                             }
-                            backwardReadyToTeleport = false
+                            backwardReadyToTeleport = false;
                         }
                     }
 
-                    if(c.inputSource.gamepad.axes[0]){
-                        if(c.inputSource.gamepad.axes[0] < -0.7){
-                            leftReadyToTeleport = true
-                        }else{
-                            if(leftReadyToTeleport){
-                                input.xrExperienceHelper.rotateCameraByQuaternionUsingContainer(Quaternion.FromEulerAngles(0, -Math.PI/4, 0))
+                    if (c.inputSource.gamepad.axes[0]) {
+                        if (c.inputSource.gamepad.axes[0] < -0.7) {
+                            leftReadyToTeleport = true;
+                        }else {
+                            if (leftReadyToTeleport) {
+                                input.baseExperience.rotateCameraByQuaternionUsingContainer(Quaternion.FromEulerAngles(0, -Math.PI / 4, 0));
                             }
-                            leftReadyToTeleport = false
+                            leftReadyToTeleport = false;
                         }
-                        if(c.inputSource.gamepad.axes[0] > 0.7){
-                            rightReadyToTeleport = true
-                        }else{
-                            if(rightReadyToTeleport){
-                                input.xrExperienceHelper.rotateCameraByQuaternionUsingContainer(Quaternion.FromEulerAngles(0, Math.PI/4, 0))
+                        if (c.inputSource.gamepad.axes[0] > 0.7) {
+                            rightReadyToTeleport = true;
+                        }else {
+                            if (rightReadyToTeleport) {
+                                input.baseExperience.rotateCameraByQuaternionUsingContainer(Quaternion.FromEulerAngles(0, Math.PI / 4, 0));
                             }
-                            rightReadyToTeleport = false
+                            rightReadyToTeleport = false;
                         }
                     }
-                    
+
                 }
-            })
+            });
 
-            c.onDisposeObservable.addOnce(()=>{
-                teleportationTarget.dispose()
-                dynamicTexture.dispose()
-                teleportationCircleMaterial.dispose()
-                torus.dispose()
+            c.onDisposeObservable.addOnce(() => {
+                teleportationTarget.dispose();
+                dynamicTexture.dispose();
+                teleportationCircleMaterial.dispose();
+                torus.dispose();
 
                 scene.onBeforeRenderObservable.remove(renderObserver);
-            })
-        })
+            });
+        });
     }
 
-    
 }

+ 72 - 20
src/Cameras/XR/webXRDefaultExperience.ts

@@ -1,5 +1,5 @@
-import {WebXRExperienceHelper} from "./webXRExperienceHelper"
-import { Scene } from 'scene';
+import { WebXRExperienceHelper } from "./webXRExperienceHelper";
+import { Scene } from '../../scene';
 import { WebXRInput } from './webXRInput';
 import { WebXRControllerModelLoader } from './webXRControllerModelLoader';
 import { WebXRControllerPointerSelection } from './webXRControllerPointerSelection';
@@ -7,24 +7,60 @@ import { WebXRControllerTeleportation } from './webXRControllerTeleportation';
 import { WebXRManagedOutputCanvas } from './webXRManagedOutputCanvas';
 import { WebXREnterExitUI } from './webXREnterExitUI';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
+/**
+ * Options for the default xr helper
+ */
 export class WebXRDefaultExperienceOptions {
-    floorMeshes: Array<AbstractMesh>
+    /**
+     * Floor meshes that should be used for teleporting
+     */
+    public floorMeshes: Array<AbstractMesh>;
 }
 
+/**
+ * Default experience which provides a similar setup to the previous webVRExperience
+ */
 export class WebXRDefaultExperience {
-    public baseExperience:WebXRExperienceHelper;
-    public input:WebXRInput;
-    public controllerModelLoader:WebXRControllerModelLoader;
-    public pointerSelection:WebXRControllerPointerSelection;
-    public teleportation:WebXRControllerTeleportation;
-    public enterExitUI:WebXREnterExitUI
-    public outputCanvas:WebXRManagedOutputCanvas
-
-    public static CreateAsync(scene:Scene, options:WebXRDefaultExperienceOptions){
+    /**
+     * Base experience
+     */
+    public baseExperience: WebXRExperienceHelper;
+    /**
+     * Input experience extension
+     */
+    public input: WebXRInput;
+    /**
+     * Loads the controller models
+     */
+    public controllerModelLoader: WebXRControllerModelLoader;
+    /**
+     * Enables laser pointer and selection
+     */
+    public pointerSelection: WebXRControllerPointerSelection;
+    /**
+     * Enables teleportation
+     */
+    public teleportation: WebXRControllerTeleportation;
+    /**
+     * Enables ui for enetering/exiting xr
+     */
+    public enterExitUI: WebXREnterExitUI;
+    /**
+     * Default output canvas xr should render to
+     */
+    public outputCanvas: WebXRManagedOutputCanvas;
+
+    /**
+     * Creates the default xr experience
+     * @param scene scene
+     * @param options options for basic configuration
+     * @returns resulting WebXRDefaultExperience
+     */
+    public static CreateAsync(scene: Scene, options: WebXRDefaultExperienceOptions) {
         var result = new WebXRDefaultExperience();
 
         // Create base experience
-        return WebXRExperienceHelper.CreateAsync(scene).then((xrHelper)=>{
+        return WebXRExperienceHelper.CreateAsync(scene).then((xrHelper) => {
             result.baseExperience = xrHelper;
 
             // Add controller support
@@ -37,16 +73,32 @@ export class WebXRDefaultExperience {
             result.outputCanvas = new WebXRManagedOutputCanvas(xrHelper, scene.getEngine().getRenderingCanvas() as HTMLCanvasElement);
 
             // Create ui for entering/exiting xr
-            return WebXREnterExitUI.CreateAsync(scene, result.baseExperience, {webXRManagedOutputCanvas: result.outputCanvas})
-        }).then((ui)=>{
+            return WebXREnterExitUI.CreateAsync(scene, result.baseExperience, {webXRManagedOutputCanvas: result.outputCanvas});
+        }).then((ui) => {
             result.enterExitUI = ui;
-            return result
-        })
+            return result;
+        });
     }
-    constructor(){
 
-    }
-    public dispose(){
+    private constructor() {
 
     }
+    
+    /**
+     * DIsposes of the experience helper
+     */
+    public dispose() {
+        if(this.baseExperience){
+            this.baseExperience.dispose()
+        }
+        if(this.input){
+            this.input.dispose()
+        }
+        if(this.enterExitUI){
+            this.enterExitUI.dispose()
+        }
+        if(this.outputCanvas){
+            this.outputCanvas.dispose()
+        }
+    }
 }

+ 2 - 2
src/Cameras/XR/webXRExperienceHelper.ts

@@ -153,9 +153,9 @@ export class WebXRExperienceHelper implements IDisposable {
             });
 
             // Wait until the first frame arrives before setting state to in xr
-            this.sessionManager.onXRFrameObservable.addOnce(()=>{
+            this.sessionManager.onXRFrameObservable.addOnce(() => {
                 this._setState(WebXRState.IN_XR);
-            })
+            });
         }).catch((e: any) => {
             console.log(e);
             console.log(e.message);

+ 22 - 17
src/Cameras/XR/webXRInput.ts

@@ -25,30 +25,35 @@ export class WebXRInput implements IDisposable {
 
     /**
      * Initializes the WebXRInput
-     * @param xrExperienceHelper experience helper which the input should be created for
+     * @param baseExperience experience helper which the input should be created for
      */
-    public constructor(public xrExperienceHelper: WebXRExperienceHelper) {
+    public constructor(
+        /**
+         * Base experience the input listens to
+         */
+        public baseExperience: WebXRExperienceHelper
+    ) {
         // Remove controllers when exiting XR
-        this._stateObserver = xrExperienceHelper.onStateChangedObservable.add((s)=>{
-            if(s === WebXRState.NOT_IN_XR){
-                this._addAndRemoveControllers([], this.controllers.map((c)=>{return c.inputSource}));
+        this._stateObserver = baseExperience.onStateChangedObservable.add((s) => {
+            if (s === WebXRState.NOT_IN_XR) {
+                this._addAndRemoveControllers([], this.controllers.map((c) => {return c.inputSource; }));
             }
-        })
-        
-        this._frameObserver = xrExperienceHelper.sessionManager.onXRFrameObservable.add(() => {
-            if (!xrExperienceHelper.sessionManager.currentFrame) {
+        });
+
+        this._frameObserver = baseExperience.sessionManager.onXRFrameObservable.add(() => {
+            if (!baseExperience.sessionManager.currentFrame) {
                 return;
             }
 
             // Start listing to input add/remove event
-            if (this.controllers.length == 0 && xrExperienceHelper.sessionManager.session.inputSources) {
-                this._addAndRemoveControllers(xrExperienceHelper.sessionManager.session.inputSources, []);
-                xrExperienceHelper.sessionManager.session.addEventListener("inputsourceschange", this._onInputSourcesChange);
+            if (this.controllers.length == 0 && baseExperience.sessionManager.session.inputSources) {
+                this._addAndRemoveControllers(baseExperience.sessionManager.session.inputSources, []);
+                baseExperience.sessionManager.session.addEventListener("inputsourceschange", this._onInputSourcesChange);
             }
 
             // Update controller pose info
             this.controllers.forEach((controller) => {
-                controller.updateFromXRFrame(xrExperienceHelper.sessionManager.currentFrame!, xrExperienceHelper.sessionManager.referenceSpace);
+                controller.updateFromXRFrame(baseExperience.sessionManager.currentFrame!, baseExperience.sessionManager.referenceSpace);
             });
 
         });
@@ -61,9 +66,9 @@ export class WebXRInput implements IDisposable {
     private _addAndRemoveControllers(addInputs: Array<XRInputSource>, removeInputs: Array<XRInputSource>) {
         // Add controllers if they don't already exist
         let sources = this.controllers.map((c) => {return c.inputSource; });
-        for(let input of addInputs){
+        for (let input of addInputs) {
             if (sources.indexOf(input) === -1) {
-                let controller = new WebXRController(this.xrExperienceHelper.camera._scene, input, this.xrExperienceHelper.container);
+                let controller = new WebXRController(this.baseExperience.camera._scene, input, this.baseExperience.container);
                 this.controllers.push(controller);
                 this.onControllerAddedObservable.notifyObservers(controller);
             }
@@ -94,7 +99,7 @@ export class WebXRInput implements IDisposable {
         this.controllers.forEach((c) => {
             c.dispose();
         });
-        this.xrExperienceHelper.sessionManager.onXRFrameObservable.remove(this._frameObserver);
-        this.xrExperienceHelper.onStateChangedObservable.remove(this._stateObserver);
+        this.baseExperience.sessionManager.onXRFrameObservable.remove(this._frameObserver);
+        this.baseExperience.onStateChangedObservable.remove(this._stateObserver);
     }
 }

+ 2 - 2
src/Cameras/XR/webXRSessionManager.ts

@@ -138,10 +138,10 @@ export class WebXRSessionManager implements IDisposable {
      * @returns Promise which resolves after it exits XR
      */
     public exitXRAsync() {
-        if(this.session){
+        if (this.session) {
             this.session.end();
         }
-        return new Promise(()=>{});
+        return new Promise(() => {});
     }
 
     /**

+ 7 - 7
src/Gamepads/Controllers/poseEnabledController.ts

@@ -232,8 +232,8 @@ export class PoseEnabledController extends Gamepad implements PoseControlled {
      * Updates the state of the pose enbaled controller and mesh based on the current position and rotation of the controller
      */
     public update() {
-        if(this.isXR){
-            return
+        if (this.isXR) {
+            return;
         }
         super.update();
         this._updatePoseAndMesh();
@@ -243,8 +243,8 @@ export class PoseEnabledController extends Gamepad implements PoseControlled {
      * Updates only the pose device and mesh without doing any button event checking
      */
     protected _updatePoseAndMesh() {
-        if(this.isXR){
-            return
+        if (this.isXR) {
+            return;
         }
         var pose: GamepadPose = this.browserGamepad.pose;
         this.updateFromDevice(pose);
@@ -293,8 +293,8 @@ export class PoseEnabledController extends Gamepad implements PoseControlled {
      * @param poseData raw pose fromthe device
      */
     updateFromDevice(poseData: DevicePose) {
-        if(this.isXR){
-            return
+        if (this.isXR) {
+            return;
         }
         if (poseData) {
             this.rawPose = poseData;
@@ -348,7 +348,7 @@ export class PoseEnabledController extends Gamepad implements PoseControlled {
         }
 
         // Sync controller mesh and pointing pose node's state with controller, this is done to avoid a frame where position is 0,0,0 when attaching mesh
-        if(!this.isXR){
+        if (!this.isXR) {
             this._updatePoseAndMesh();
             if (this._pointingPoseNode) {
                 var parents = [];

+ 4 - 3
src/Helpers/sceneHelpers.ts

@@ -81,9 +81,10 @@ declare module "../scene" {
         /**
          * Creates a new WebXRDefaultExperience
          * @see http://doc.babylonjs.com/how_to/webxr
+         * @param options experience options
          * @returns a promise for a new WebXRDefaultExperience
          */
-        createDefaultXRExperienceAsync(options:WebXRDefaultExperienceOptions): Promise<WebXRDefaultExperience>;
+        createDefaultXRExperienceAsync(options: WebXRDefaultExperienceOptions): Promise<WebXRDefaultExperience>;
     }
 }
 
@@ -207,8 +208,8 @@ Scene.prototype.createDefaultVRExperience = function(webVROptions: VRExperienceH
     return new VRExperienceHelper(this, webVROptions);
 };
 
-Scene.prototype.createDefaultXRExperienceAsync = function(options:WebXRDefaultExperienceOptions): Promise<WebXRDefaultExperience> {
+Scene.prototype.createDefaultXRExperienceAsync = function(options: WebXRDefaultExperienceOptions): Promise<WebXRDefaultExperience> {
     return WebXRDefaultExperience.CreateAsync(this, options).then((helper) => {
-        return helper
+        return helper;
     });
 };