浏览代码

Merge pull request #7550 from BabylonJS/master

Nightly
David Catuhe 5 年之前
父节点
当前提交
f0188f5f51
共有 32 个文件被更改,包括 885 次插入780 次删除
  1. 27 30
      dist/preview release/babylon.d.ts
  2. 1 1
      dist/preview release/babylon.js
  3. 346 351
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 69 75
      dist/preview release/babylon.module.d.ts
  6. 27 30
      dist/preview release/documentation.d.ts
  7. 69 75
      dist/preview release/viewer/babylon.module.d.ts
  8. 23 23
      dist/preview release/viewer/babylon.viewer.js
  9. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  10. 3 2
      dist/preview release/what's new.md
  11. 106 0
      gui/src/2D/controls/scrollViewers/scrollViewer.ts
  12. 33 4
      nodeEditor/src/diagram/graphFrame.ts
  13. 3 0
      nodeEditor/src/diagram/properties/framePropertyComponent.tsx
  14. 1 1
      nodeEditor/src/globalState.ts
  15. 1 1
      nodeEditor/src/graphEditor.tsx
  16. 4 3
      nodeEditor/src/nodeLocationInfo.ts
  17. 4 4
      src/XR/features/WebXRControllerPhysics.ts
  18. 10 10
      src/XR/features/WebXRControllerPointerSelection.ts
  19. 8 8
      src/XR/features/WebXRControllerTeleportation.ts
  20. 1 1
      src/XR/index.ts
  21. 1 1
      src/XR/motionController/index.ts
  22. 0 0
      src/XR/motionController/webXRAbstractMotionController.ts
  23. 7 7
      src/XR/motionController/webXRControllerComponent.ts
  24. 1 1
      src/XR/motionController/webXRGenericMotionController.ts
  25. 2 2
      src/XR/motionController/webXRHTCViveMotionController.ts
  26. 3 3
      src/XR/motionController/webXRMicrosoftMixedRealityController.ts
  27. 1 1
      src/XR/motionController/webXRMotionControllerManager.ts
  28. 2 2
      src/XR/motionController/webXROculusTouchMotionController.ts
  29. 1 1
      src/XR/motionController/webXRProfiledMotionController.ts
  30. 113 127
      src/XR/webXRCamera.ts
  31. 7 7
      src/XR/webXRInput.ts
  32. 9 7
      src/XR/webXRController.ts

+ 27 - 30
dist/preview release/babylon.d.ts

@@ -42654,48 +42654,44 @@ declare module BABYLON {
 declare module BABYLON {
 declare module BABYLON {
     /**
     /**
      * WebXR Camera which holds the views for the xrSession
      * WebXR Camera which holds the views for the xrSession
-     * @see https://doc.babylonjs.com/how_to/webxr
+     * @see https://doc.babylonjs.com/how_to/webxr_camera
      */
      */
     export class WebXRCamera extends FreeCamera {
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
         private _xrSessionManager;
-        /**
-         * Should position compensation execute on first frame.
-         * This is used when copying the position from a native (non XR) camera
-         */
-        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _firstFrame;
-        private _referencedPosition;
         private _referenceQuaternion;
         private _referenceQuaternion;
+        private _referencedPosition;
         private _xrInvPositionCache;
         private _xrInvPositionCache;
         private _xrInvQuaternionCache;
         private _xrInvQuaternionCache;
-        private _realWorldHeight;
-        /**
-         * Prevent the camera from calculating the real-world height
-         * If you are not using the user's height disable this for better performance
-         */
-        disableRealWorldHeightCalculation: boolean;
         /**
         /**
-         * Return the user's height, unrelated to the current ground.
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
          */
          */
-        get realWorldHeight(): number;
+        compensateOnFirstFrame: boolean;
         /**
         /**
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * @param name the name of the camera
          * @param name the name of the camera
          * @param scene the scene to add the camera to
          * @param scene the scene to add the camera to
+         * @param _xrSessionManager a constructed xr session manager
          */
          */
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
-        private _updateNumberOfRigCameras;
+        /**
+         * Return the user's height, unrelated to the current ground.
+         * This will be the y position of this camera, when ground level is 0.
+         */
+        get realWorldHeight(): number;
+        /** @hidden */
+        _updateForDualEyeDebugging(): void;
         /**
         /**
          * Sets this camera's transformation based on a non-vr camera
          * Sets this camera's transformation based on a non-vr camera
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          */
          */
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
-        /** @hidden */
-        _updateForDualEyeDebugging(): void;
+        private _updateFromXRSession;
+        private _updateNumberOfRigCameras;
         private _updateReferenceSpace;
         private _updateReferenceSpace;
         private _updateReferenceSpaceOffset;
         private _updateReferenceSpaceOffset;
-        private _updateFromXRSession;
     }
     }
 }
 }
 declare module BABYLON {
 declare module BABYLON {
@@ -43026,12 +43022,12 @@ declare module BABYLON {
          * Observers registered here will be triggered when the state of a button changes
          * Observers registered here will be triggered when the state of a button changes
          * State change is either pressed / touched / value
          * State change is either pressed / touched / value
          */
          */
-        onButtonStateChanged: Observable<WebXRControllerComponent>;
+        onButtonStateChangedObservable: Observable<WebXRControllerComponent>;
         /**
         /**
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * the axes data changes
          * the axes data changes
          */
          */
-        onAxisValueChanged: Observable<{
+        onAxisValueChangedObservable: Observable<{
             x: number;
             x: number;
             y: number;
             y: number;
         }>;
         }>;
@@ -44056,7 +44052,7 @@ declare module BABYLON {
     /**
     /**
      * Represents an XR controller
      * Represents an XR controller
      */
      */
-    export class WebXRController {
+    export class WebXRInputSource {
         private _scene;
         private _scene;
         /** The underlying input source for the controller  */
         /** The underlying input source for the controller  */
         inputSource: XRInputSource;
         inputSource: XRInputSource;
@@ -44090,7 +44086,7 @@ declare module BABYLON {
          * The object provided as event data is this controller, after associated assets were disposed.
          * The object provided as event data is this controller, after associated assets were disposed.
          * uniqueId is still available.
          * uniqueId is still available.
          */
          */
-        onDisposeObservable: Observable<WebXRController>;
+        onDisposeObservable: Observable<WebXRInputSource>;
         private _tmpQuaternion;
         private _tmpQuaternion;
         private _tmpVector;
         private _tmpVector;
         private _uniqueId;
         private _uniqueId;
@@ -44115,10 +44111,11 @@ declare module BABYLON {
          */
          */
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         /**
         /**
-         * Gets a world space ray coming from the controller
+         * Gets a world space ray coming from the pointer or grip
          * @param result the resulting ray
          * @param result the resulting ray
+         * @param gripIfAvailable use the grip mesh instead of the pointer, if available
          */
          */
-        getWorldPointerRayToRef(result: Ray): void;
+        getWorldPointerRayToRef(result: Ray, gripIfAvailable?: boolean): void;
         /**
         /**
          * Disposes of the object
          * Disposes of the object
          */
          */
@@ -44171,18 +44168,18 @@ declare module BABYLON {
         /**
         /**
          * XR controllers being tracked
          * XR controllers being tracked
          */
          */
-        controllers: Array<WebXRController>;
+        controllers: Array<WebXRInputSource>;
         private _frameObserver;
         private _frameObserver;
         private _sessionEndedObserver;
         private _sessionEndedObserver;
         private _sessionInitObserver;
         private _sessionInitObserver;
         /**
         /**
          * Event when a controller has been connected/added
          * Event when a controller has been connected/added
          */
          */
-        onControllerAddedObservable: Observable<WebXRController>;
+        onControllerAddedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Event when a controller has been removed/disconnected
          * Event when a controller has been removed/disconnected
          */
          */
-        onControllerRemovedObservable: Observable<WebXRController>;
+        onControllerRemovedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Initializes the WebXRInput
          * Initializes the WebXRInput
          * @param xrSessionManager the xr session manager for this session
          * @param xrSessionManager the xr session manager for this session
@@ -44374,7 +44371,7 @@ declare module BABYLON {
          * @param id the pointer id to search for
          * @param id the pointer id to search for
          * @returns the controller that correlates to this id or null if not found
          * @returns the controller that correlates to this id or null if not found
          */
          */
-        getXRControllerByPointerId(id: number): Nullable<WebXRController>;
+        getXRControllerByPointerId(id: number): Nullable<WebXRInputSource>;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         private _attachController;
         private _attachController;
         private _attachScreenRayMode;
         private _attachScreenRayMode;
@@ -68770,7 +68767,7 @@ declare module BABYLON {
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * @param xrController the controller to add
          * @param xrController the controller to add
          */
          */
-        addController(xrController: WebXRController): void;
+        addController(xrController: WebXRInputSource): void;
         private _debugMode;
         private _debugMode;
         /**
         /**
          * @hidden
          * @hidden

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 346 - 351
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 69 - 75
dist/preview release/babylon.module.d.ts

@@ -44144,48 +44144,44 @@ declare module "babylonjs/XR/webXRCamera" {
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     /**
     /**
      * WebXR Camera which holds the views for the xrSession
      * WebXR Camera which holds the views for the xrSession
-     * @see https://doc.babylonjs.com/how_to/webxr
+     * @see https://doc.babylonjs.com/how_to/webxr_camera
      */
      */
     export class WebXRCamera extends FreeCamera {
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
         private _xrSessionManager;
-        /**
-         * Should position compensation execute on first frame.
-         * This is used when copying the position from a native (non XR) camera
-         */
-        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _firstFrame;
-        private _referencedPosition;
         private _referenceQuaternion;
         private _referenceQuaternion;
+        private _referencedPosition;
         private _xrInvPositionCache;
         private _xrInvPositionCache;
         private _xrInvQuaternionCache;
         private _xrInvQuaternionCache;
-        private _realWorldHeight;
-        /**
-         * Prevent the camera from calculating the real-world height
-         * If you are not using the user's height disable this for better performance
-         */
-        disableRealWorldHeightCalculation: boolean;
         /**
         /**
-         * Return the user's height, unrelated to the current ground.
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
          */
          */
-        get realWorldHeight(): number;
+        compensateOnFirstFrame: boolean;
         /**
         /**
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * @param name the name of the camera
          * @param name the name of the camera
          * @param scene the scene to add the camera to
          * @param scene the scene to add the camera to
+         * @param _xrSessionManager a constructed xr session manager
          */
          */
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
-        private _updateNumberOfRigCameras;
+        /**
+         * Return the user's height, unrelated to the current ground.
+         * This will be the y position of this camera, when ground level is 0.
+         */
+        get realWorldHeight(): number;
+        /** @hidden */
+        _updateForDualEyeDebugging(): void;
         /**
         /**
          * Sets this camera's transformation based on a non-vr camera
          * Sets this camera's transformation based on a non-vr camera
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          */
          */
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
-        /** @hidden */
-        _updateForDualEyeDebugging(): void;
+        private _updateFromXRSession;
+        private _updateNumberOfRigCameras;
         private _updateReferenceSpace;
         private _updateReferenceSpace;
         private _updateReferenceSpaceOffset;
         private _updateReferenceSpaceOffset;
-        private _updateFromXRSession;
     }
     }
 }
 }
 declare module "babylonjs/XR/webXRFeaturesManager" {
 declare module "babylonjs/XR/webXRFeaturesManager" {
@@ -44439,7 +44435,7 @@ declare module "babylonjs/XR/webXRExperienceHelper" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRControllerComponent" {
 declare module "babylonjs/XR/motionController/webXRControllerComponent" {
-    import { IMinimalMotionControllerObject, MotionControllerComponentType } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { IMinimalMotionControllerObject, MotionControllerComponentType } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
     import { IDisposable } from "babylonjs/scene";
     import { IDisposable } from "babylonjs/scene";
     /**
     /**
@@ -44527,12 +44523,12 @@ declare module "babylonjs/XR/motionController/webXRControllerComponent" {
          * Observers registered here will be triggered when the state of a button changes
          * Observers registered here will be triggered when the state of a button changes
          * State change is either pressed / touched / value
          * State change is either pressed / touched / value
          */
          */
-        onButtonStateChanged: Observable<WebXRControllerComponent>;
+        onButtonStateChangedObservable: Observable<WebXRControllerComponent>;
         /**
         /**
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * the axes data changes
          * the axes data changes
          */
          */
-        onAxisValueChanged: Observable<{
+        onAxisValueChangedObservable: Observable<{
             x: number;
             x: number;
             y: number;
             y: number;
         }>;
         }>;
@@ -45026,7 +45022,7 @@ declare module "babylonjs/Loading/sceneLoader" {
         static ImportAnimationsAsync(rootUrl: string, sceneFilename?: string | File, scene?: Nullable<Scene>, overwriteAnimations?: boolean, animationGroupLoadingMode?: SceneLoaderAnimationGroupLoadingMode, targetConverter?: Nullable<(target: any) => any>, onSuccess?: Nullable<(scene: Scene) => void>, onProgress?: Nullable<(event: SceneLoaderProgressEvent) => void>, onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>): Promise<Scene>;
         static ImportAnimationsAsync(rootUrl: string, sceneFilename?: string | File, scene?: Nullable<Scene>, overwriteAnimations?: boolean, animationGroupLoadingMode?: SceneLoaderAnimationGroupLoadingMode, targetConverter?: Nullable<(target: any) => any>, onSuccess?: Nullable<(scene: Scene) => void>, onProgress?: Nullable<(event: SceneLoaderProgressEvent) => void>, onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>): Promise<Scene>;
     }
     }
 }
 }
-declare module "babylonjs/XR/motionController/webXRAbstractController" {
+declare module "babylonjs/XR/motionController/webXRAbstractMotionController" {
     import { IDisposable, Scene } from "babylonjs/scene";
     import { IDisposable, Scene } from "babylonjs/scene";
     import { WebXRControllerComponent } from "babylonjs/XR/motionController/webXRControllerComponent";
     import { WebXRControllerComponent } from "babylonjs/XR/motionController/webXRControllerComponent";
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
@@ -45383,7 +45379,7 @@ declare module "babylonjs/XR/motionController/webXRAbstractController" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRGenericMotionController" {
 declare module "babylonjs/XR/motionController/webXRGenericMotionController" {
-    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
@@ -45448,7 +45444,7 @@ declare module "babylonjs/Meshes/Builders/sphereBuilder" {
 }
 }
 declare module "babylonjs/XR/motionController/webXRProfiledMotionController" {
 declare module "babylonjs/XR/motionController/webXRProfiledMotionController" {
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
-    import { WebXRAbstractMotionController, IMotionControllerProfile } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMotionControllerProfile } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
      * A profiled motion controller has its profile loaded from an online repository.
      * A profiled motion controller has its profile loaded from an online repository.
@@ -45475,7 +45471,7 @@ declare module "babylonjs/XR/motionController/webXRProfiledMotionController" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRMotionControllerManager" {
 declare module "babylonjs/XR/motionController/webXRMotionControllerManager" {
-    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
      * A construction function type to create a new controller based on an xrInput object
      * A construction function type to create a new controller based on an xrInput object
@@ -45562,12 +45558,12 @@ declare module "babylonjs/XR/motionController/webXRMotionControllerManager" {
         static DefaultFallbacks(): void;
         static DefaultFallbacks(): void;
     }
     }
 }
 }
-declare module "babylonjs/XR/webXRController" {
+declare module "babylonjs/XR/webXRInputSource" {
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Ray } from "babylonjs/Culling/ray";
     import { Ray } from "babylonjs/Culling/ray";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
-    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     /**
     /**
      * Configuration options for the WebXR controller creation
      * Configuration options for the WebXR controller creation
      */
      */
@@ -45590,7 +45586,7 @@ declare module "babylonjs/XR/webXRController" {
     /**
     /**
      * Represents an XR controller
      * Represents an XR controller
      */
      */
-    export class WebXRController {
+    export class WebXRInputSource {
         private _scene;
         private _scene;
         /** The underlying input source for the controller  */
         /** The underlying input source for the controller  */
         inputSource: XRInputSource;
         inputSource: XRInputSource;
@@ -45624,7 +45620,7 @@ declare module "babylonjs/XR/webXRController" {
          * The object provided as event data is this controller, after associated assets were disposed.
          * The object provided as event data is this controller, after associated assets were disposed.
          * uniqueId is still available.
          * uniqueId is still available.
          */
          */
-        onDisposeObservable: Observable<WebXRController>;
+        onDisposeObservable: Observable<WebXRInputSource>;
         private _tmpQuaternion;
         private _tmpQuaternion;
         private _tmpVector;
         private _tmpVector;
         private _uniqueId;
         private _uniqueId;
@@ -45649,10 +45645,11 @@ declare module "babylonjs/XR/webXRController" {
          */
          */
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         /**
         /**
-         * Gets a world space ray coming from the controller
+         * Gets a world space ray coming from the pointer or grip
          * @param result the resulting ray
          * @param result the resulting ray
+         * @param gripIfAvailable use the grip mesh instead of the pointer, if available
          */
          */
-        getWorldPointerRayToRef(result: Ray): void;
+        getWorldPointerRayToRef(result: Ray, gripIfAvailable?: boolean): void;
         /**
         /**
          * Disposes of the object
          * Disposes of the object
          */
          */
@@ -45662,7 +45659,7 @@ declare module "babylonjs/XR/webXRController" {
 declare module "babylonjs/XR/webXRInput" {
 declare module "babylonjs/XR/webXRInput" {
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
     import { IDisposable } from "babylonjs/scene";
     import { IDisposable } from "babylonjs/scene";
-    import { WebXRController } from "babylonjs/XR/webXRController";
+    import { WebXRInputSource } from "babylonjs/XR/webXRInputSource";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRCamera } from "babylonjs/XR/webXRCamera";
     import { WebXRCamera } from "babylonjs/XR/webXRCamera";
     /**
     /**
@@ -45710,18 +45707,18 @@ declare module "babylonjs/XR/webXRInput" {
         /**
         /**
          * XR controllers being tracked
          * XR controllers being tracked
          */
          */
-        controllers: Array<WebXRController>;
+        controllers: Array<WebXRInputSource>;
         private _frameObserver;
         private _frameObserver;
         private _sessionEndedObserver;
         private _sessionEndedObserver;
         private _sessionInitObserver;
         private _sessionInitObserver;
         /**
         /**
          * Event when a controller has been connected/added
          * Event when a controller has been connected/added
          */
          */
-        onControllerAddedObservable: Observable<WebXRController>;
+        onControllerAddedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Event when a controller has been removed/disconnected
          * Event when a controller has been removed/disconnected
          */
          */
-        onControllerRemovedObservable: Observable<WebXRController>;
+        onControllerRemovedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Initializes the WebXRInput
          * Initializes the WebXRInput
          * @param xrSessionManager the xr session manager for this session
          * @param xrSessionManager the xr session manager for this session
@@ -45805,7 +45802,7 @@ declare module "babylonjs/XR/features/WebXRAbstractFeature" {
 declare module "babylonjs/XR/features/WebXRControllerPointerSelection" {
 declare module "babylonjs/XR/features/WebXRControllerPointerSelection" {
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
-    import { WebXRController } from "babylonjs/XR/webXRController";
+    import { WebXRInputSource } from "babylonjs/XR/webXRInputSource";
     import { Nullable } from "babylonjs/types";
     import { Nullable } from "babylonjs/types";
     import { Color3 } from "babylonjs/Maths/math.color";
     import { Color3 } from "babylonjs/Maths/math.color";
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
@@ -45922,7 +45919,7 @@ declare module "babylonjs/XR/features/WebXRControllerPointerSelection" {
          * @param id the pointer id to search for
          * @param id the pointer id to search for
          * @returns the controller that correlates to this id or null if not found
          * @returns the controller that correlates to this id or null if not found
          */
          */
-        getXRControllerByPointerId(id: number): Nullable<WebXRController>;
+        getXRControllerByPointerId(id: number): Nullable<WebXRInputSource>;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         private _attachController;
         private _attachController;
         private _attachScreenRayMode;
         private _attachScreenRayMode;
@@ -72393,7 +72390,7 @@ declare module "babylonjs/XR/features/WebXRBackgroundRemover" {
 }
 }
 declare module "babylonjs/XR/features/WebXRControllerPhysics" {
 declare module "babylonjs/XR/features/WebXRControllerPhysics" {
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
-    import { WebXRController } from "babylonjs/XR/webXRController";
+    import { WebXRInputSource } from "babylonjs/XR/webXRInputSource";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     /**
     /**
@@ -72494,7 +72491,7 @@ declare module "babylonjs/XR/features/WebXRControllerPhysics" {
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * @param xrController the controller to add
          * @param xrController the controller to add
          */
          */
-        addController(xrController: WebXRController): void;
+        addController(xrController: WebXRInputSource): void;
         private _debugMode;
         private _debugMode;
         /**
         /**
          * @hidden
          * @hidden
@@ -72516,7 +72513,7 @@ declare module "babylonjs/XR/features/index" {
     export * from "babylonjs/XR/features/WebXRControllerPhysics";
     export * from "babylonjs/XR/features/WebXRControllerPhysics";
 }
 }
 declare module "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController" {
 declare module "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController" {
-    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
@@ -72600,7 +72597,7 @@ declare module "babylonjs/XR/motionController/webXRMicrosoftMixedRealityControll
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXROculusTouchMotionController" {
 declare module "babylonjs/XR/motionController/webXROculusTouchMotionController" {
-    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
@@ -72644,7 +72641,7 @@ declare module "babylonjs/XR/motionController/webXROculusTouchMotionController"
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRHTCViveMotionController" {
 declare module "babylonjs/XR/motionController/webXRHTCViveMotionController" {
-    import { IMinimalMotionControllerObject, MotionControllerHandness, WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { IMinimalMotionControllerObject, MotionControllerHandness, WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     /**
     /**
@@ -72679,7 +72676,7 @@ declare module "babylonjs/XR/motionController/webXRHTCViveMotionController" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/index" {
 declare module "babylonjs/XR/motionController/index" {
-    export * from "babylonjs/XR/motionController/webXRAbstractController";
+    export * from "babylonjs/XR/motionController/webXRAbstractMotionController";
     export * from "babylonjs/XR/motionController/webXRControllerComponent";
     export * from "babylonjs/XR/motionController/webXRControllerComponent";
     export * from "babylonjs/XR/motionController/webXRGenericMotionController";
     export * from "babylonjs/XR/motionController/webXRGenericMotionController";
     export * from "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController";
     export * from "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController";
@@ -72693,7 +72690,7 @@ declare module "babylonjs/XR/index" {
     export * from "babylonjs/XR/webXREnterExitUI";
     export * from "babylonjs/XR/webXREnterExitUI";
     export * from "babylonjs/XR/webXRExperienceHelper";
     export * from "babylonjs/XR/webXRExperienceHelper";
     export * from "babylonjs/XR/webXRInput";
     export * from "babylonjs/XR/webXRInput";
-    export * from "babylonjs/XR/webXRController";
+    export * from "babylonjs/XR/webXRInputSource";
     export * from "babylonjs/XR/webXRManagedOutputCanvas";
     export * from "babylonjs/XR/webXRManagedOutputCanvas";
     export * from "babylonjs/XR/webXRTypes";
     export * from "babylonjs/XR/webXRTypes";
     export * from "babylonjs/XR/webXRSessionManager";
     export * from "babylonjs/XR/webXRSessionManager";
@@ -115510,48 +115507,44 @@ declare module BABYLON {
 declare module BABYLON {
 declare module BABYLON {
     /**
     /**
      * WebXR Camera which holds the views for the xrSession
      * WebXR Camera which holds the views for the xrSession
-     * @see https://doc.babylonjs.com/how_to/webxr
+     * @see https://doc.babylonjs.com/how_to/webxr_camera
      */
      */
     export class WebXRCamera extends FreeCamera {
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
         private _xrSessionManager;
-        /**
-         * Should position compensation execute on first frame.
-         * This is used when copying the position from a native (non XR) camera
-         */
-        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _firstFrame;
-        private _referencedPosition;
         private _referenceQuaternion;
         private _referenceQuaternion;
+        private _referencedPosition;
         private _xrInvPositionCache;
         private _xrInvPositionCache;
         private _xrInvQuaternionCache;
         private _xrInvQuaternionCache;
-        private _realWorldHeight;
-        /**
-         * Prevent the camera from calculating the real-world height
-         * If you are not using the user's height disable this for better performance
-         */
-        disableRealWorldHeightCalculation: boolean;
         /**
         /**
-         * Return the user's height, unrelated to the current ground.
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
          */
          */
-        get realWorldHeight(): number;
+        compensateOnFirstFrame: boolean;
         /**
         /**
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * @param name the name of the camera
          * @param name the name of the camera
          * @param scene the scene to add the camera to
          * @param scene the scene to add the camera to
+         * @param _xrSessionManager a constructed xr session manager
          */
          */
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
-        private _updateNumberOfRigCameras;
+        /**
+         * Return the user's height, unrelated to the current ground.
+         * This will be the y position of this camera, when ground level is 0.
+         */
+        get realWorldHeight(): number;
+        /** @hidden */
+        _updateForDualEyeDebugging(): void;
         /**
         /**
          * Sets this camera's transformation based on a non-vr camera
          * Sets this camera's transformation based on a non-vr camera
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          */
          */
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
-        /** @hidden */
-        _updateForDualEyeDebugging(): void;
+        private _updateFromXRSession;
+        private _updateNumberOfRigCameras;
         private _updateReferenceSpace;
         private _updateReferenceSpace;
         private _updateReferenceSpaceOffset;
         private _updateReferenceSpaceOffset;
-        private _updateFromXRSession;
     }
     }
 }
 }
 declare module BABYLON {
 declare module BABYLON {
@@ -115882,12 +115875,12 @@ declare module BABYLON {
          * Observers registered here will be triggered when the state of a button changes
          * Observers registered here will be triggered when the state of a button changes
          * State change is either pressed / touched / value
          * State change is either pressed / touched / value
          */
          */
-        onButtonStateChanged: Observable<WebXRControllerComponent>;
+        onButtonStateChangedObservable: Observable<WebXRControllerComponent>;
         /**
         /**
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * the axes data changes
          * the axes data changes
          */
          */
-        onAxisValueChanged: Observable<{
+        onAxisValueChangedObservable: Observable<{
             x: number;
             x: number;
             y: number;
             y: number;
         }>;
         }>;
@@ -116912,7 +116905,7 @@ declare module BABYLON {
     /**
     /**
      * Represents an XR controller
      * Represents an XR controller
      */
      */
-    export class WebXRController {
+    export class WebXRInputSource {
         private _scene;
         private _scene;
         /** The underlying input source for the controller  */
         /** The underlying input source for the controller  */
         inputSource: XRInputSource;
         inputSource: XRInputSource;
@@ -116946,7 +116939,7 @@ declare module BABYLON {
          * The object provided as event data is this controller, after associated assets were disposed.
          * The object provided as event data is this controller, after associated assets were disposed.
          * uniqueId is still available.
          * uniqueId is still available.
          */
          */
-        onDisposeObservable: Observable<WebXRController>;
+        onDisposeObservable: Observable<WebXRInputSource>;
         private _tmpQuaternion;
         private _tmpQuaternion;
         private _tmpVector;
         private _tmpVector;
         private _uniqueId;
         private _uniqueId;
@@ -116971,10 +116964,11 @@ declare module BABYLON {
          */
          */
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         /**
         /**
-         * Gets a world space ray coming from the controller
+         * Gets a world space ray coming from the pointer or grip
          * @param result the resulting ray
          * @param result the resulting ray
+         * @param gripIfAvailable use the grip mesh instead of the pointer, if available
          */
          */
-        getWorldPointerRayToRef(result: Ray): void;
+        getWorldPointerRayToRef(result: Ray, gripIfAvailable?: boolean): void;
         /**
         /**
          * Disposes of the object
          * Disposes of the object
          */
          */
@@ -117027,18 +117021,18 @@ declare module BABYLON {
         /**
         /**
          * XR controllers being tracked
          * XR controllers being tracked
          */
          */
-        controllers: Array<WebXRController>;
+        controllers: Array<WebXRInputSource>;
         private _frameObserver;
         private _frameObserver;
         private _sessionEndedObserver;
         private _sessionEndedObserver;
         private _sessionInitObserver;
         private _sessionInitObserver;
         /**
         /**
          * Event when a controller has been connected/added
          * Event when a controller has been connected/added
          */
          */
-        onControllerAddedObservable: Observable<WebXRController>;
+        onControllerAddedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Event when a controller has been removed/disconnected
          * Event when a controller has been removed/disconnected
          */
          */
-        onControllerRemovedObservable: Observable<WebXRController>;
+        onControllerRemovedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Initializes the WebXRInput
          * Initializes the WebXRInput
          * @param xrSessionManager the xr session manager for this session
          * @param xrSessionManager the xr session manager for this session
@@ -117230,7 +117224,7 @@ declare module BABYLON {
          * @param id the pointer id to search for
          * @param id the pointer id to search for
          * @returns the controller that correlates to this id or null if not found
          * @returns the controller that correlates to this id or null if not found
          */
          */
-        getXRControllerByPointerId(id: number): Nullable<WebXRController>;
+        getXRControllerByPointerId(id: number): Nullable<WebXRInputSource>;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         private _attachController;
         private _attachController;
         private _attachScreenRayMode;
         private _attachScreenRayMode;
@@ -141626,7 +141620,7 @@ declare module BABYLON {
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * @param xrController the controller to add
          * @param xrController the controller to add
          */
          */
-        addController(xrController: WebXRController): void;
+        addController(xrController: WebXRInputSource): void;
         private _debugMode;
         private _debugMode;
         /**
         /**
          * @hidden
          * @hidden

+ 27 - 30
dist/preview release/documentation.d.ts

@@ -42654,48 +42654,44 @@ declare module BABYLON {
 declare module BABYLON {
 declare module BABYLON {
     /**
     /**
      * WebXR Camera which holds the views for the xrSession
      * WebXR Camera which holds the views for the xrSession
-     * @see https://doc.babylonjs.com/how_to/webxr
+     * @see https://doc.babylonjs.com/how_to/webxr_camera
      */
      */
     export class WebXRCamera extends FreeCamera {
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
         private _xrSessionManager;
-        /**
-         * Should position compensation execute on first frame.
-         * This is used when copying the position from a native (non XR) camera
-         */
-        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _firstFrame;
-        private _referencedPosition;
         private _referenceQuaternion;
         private _referenceQuaternion;
+        private _referencedPosition;
         private _xrInvPositionCache;
         private _xrInvPositionCache;
         private _xrInvQuaternionCache;
         private _xrInvQuaternionCache;
-        private _realWorldHeight;
-        /**
-         * Prevent the camera from calculating the real-world height
-         * If you are not using the user's height disable this for better performance
-         */
-        disableRealWorldHeightCalculation: boolean;
         /**
         /**
-         * Return the user's height, unrelated to the current ground.
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
          */
          */
-        get realWorldHeight(): number;
+        compensateOnFirstFrame: boolean;
         /**
         /**
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * @param name the name of the camera
          * @param name the name of the camera
          * @param scene the scene to add the camera to
          * @param scene the scene to add the camera to
+         * @param _xrSessionManager a constructed xr session manager
          */
          */
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
-        private _updateNumberOfRigCameras;
+        /**
+         * Return the user's height, unrelated to the current ground.
+         * This will be the y position of this camera, when ground level is 0.
+         */
+        get realWorldHeight(): number;
+        /** @hidden */
+        _updateForDualEyeDebugging(): void;
         /**
         /**
          * Sets this camera's transformation based on a non-vr camera
          * Sets this camera's transformation based on a non-vr camera
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          */
          */
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
-        /** @hidden */
-        _updateForDualEyeDebugging(): void;
+        private _updateFromXRSession;
+        private _updateNumberOfRigCameras;
         private _updateReferenceSpace;
         private _updateReferenceSpace;
         private _updateReferenceSpaceOffset;
         private _updateReferenceSpaceOffset;
-        private _updateFromXRSession;
     }
     }
 }
 }
 declare module BABYLON {
 declare module BABYLON {
@@ -43026,12 +43022,12 @@ declare module BABYLON {
          * Observers registered here will be triggered when the state of a button changes
          * Observers registered here will be triggered when the state of a button changes
          * State change is either pressed / touched / value
          * State change is either pressed / touched / value
          */
          */
-        onButtonStateChanged: Observable<WebXRControllerComponent>;
+        onButtonStateChangedObservable: Observable<WebXRControllerComponent>;
         /**
         /**
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * the axes data changes
          * the axes data changes
          */
          */
-        onAxisValueChanged: Observable<{
+        onAxisValueChangedObservable: Observable<{
             x: number;
             x: number;
             y: number;
             y: number;
         }>;
         }>;
@@ -44056,7 +44052,7 @@ declare module BABYLON {
     /**
     /**
      * Represents an XR controller
      * Represents an XR controller
      */
      */
-    export class WebXRController {
+    export class WebXRInputSource {
         private _scene;
         private _scene;
         /** The underlying input source for the controller  */
         /** The underlying input source for the controller  */
         inputSource: XRInputSource;
         inputSource: XRInputSource;
@@ -44090,7 +44086,7 @@ declare module BABYLON {
          * The object provided as event data is this controller, after associated assets were disposed.
          * The object provided as event data is this controller, after associated assets were disposed.
          * uniqueId is still available.
          * uniqueId is still available.
          */
          */
-        onDisposeObservable: Observable<WebXRController>;
+        onDisposeObservable: Observable<WebXRInputSource>;
         private _tmpQuaternion;
         private _tmpQuaternion;
         private _tmpVector;
         private _tmpVector;
         private _uniqueId;
         private _uniqueId;
@@ -44115,10 +44111,11 @@ declare module BABYLON {
          */
          */
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         /**
         /**
-         * Gets a world space ray coming from the controller
+         * Gets a world space ray coming from the pointer or grip
          * @param result the resulting ray
          * @param result the resulting ray
+         * @param gripIfAvailable use the grip mesh instead of the pointer, if available
          */
          */
-        getWorldPointerRayToRef(result: Ray): void;
+        getWorldPointerRayToRef(result: Ray, gripIfAvailable?: boolean): void;
         /**
         /**
          * Disposes of the object
          * Disposes of the object
          */
          */
@@ -44171,18 +44168,18 @@ declare module BABYLON {
         /**
         /**
          * XR controllers being tracked
          * XR controllers being tracked
          */
          */
-        controllers: Array<WebXRController>;
+        controllers: Array<WebXRInputSource>;
         private _frameObserver;
         private _frameObserver;
         private _sessionEndedObserver;
         private _sessionEndedObserver;
         private _sessionInitObserver;
         private _sessionInitObserver;
         /**
         /**
          * Event when a controller has been connected/added
          * Event when a controller has been connected/added
          */
          */
-        onControllerAddedObservable: Observable<WebXRController>;
+        onControllerAddedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Event when a controller has been removed/disconnected
          * Event when a controller has been removed/disconnected
          */
          */
-        onControllerRemovedObservable: Observable<WebXRController>;
+        onControllerRemovedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Initializes the WebXRInput
          * Initializes the WebXRInput
          * @param xrSessionManager the xr session manager for this session
          * @param xrSessionManager the xr session manager for this session
@@ -44374,7 +44371,7 @@ declare module BABYLON {
          * @param id the pointer id to search for
          * @param id the pointer id to search for
          * @returns the controller that correlates to this id or null if not found
          * @returns the controller that correlates to this id or null if not found
          */
          */
-        getXRControllerByPointerId(id: number): Nullable<WebXRController>;
+        getXRControllerByPointerId(id: number): Nullable<WebXRInputSource>;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         private _attachController;
         private _attachController;
         private _attachScreenRayMode;
         private _attachScreenRayMode;
@@ -68770,7 +68767,7 @@ declare module BABYLON {
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * @param xrController the controller to add
          * @param xrController the controller to add
          */
          */
-        addController(xrController: WebXRController): void;
+        addController(xrController: WebXRInputSource): void;
         private _debugMode;
         private _debugMode;
         /**
         /**
          * @hidden
          * @hidden

+ 69 - 75
dist/preview release/viewer/babylon.module.d.ts

@@ -44144,48 +44144,44 @@ declare module "babylonjs/XR/webXRCamera" {
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     /**
     /**
      * WebXR Camera which holds the views for the xrSession
      * WebXR Camera which holds the views for the xrSession
-     * @see https://doc.babylonjs.com/how_to/webxr
+     * @see https://doc.babylonjs.com/how_to/webxr_camera
      */
      */
     export class WebXRCamera extends FreeCamera {
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
         private _xrSessionManager;
-        /**
-         * Should position compensation execute on first frame.
-         * This is used when copying the position from a native (non XR) camera
-         */
-        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _firstFrame;
-        private _referencedPosition;
         private _referenceQuaternion;
         private _referenceQuaternion;
+        private _referencedPosition;
         private _xrInvPositionCache;
         private _xrInvPositionCache;
         private _xrInvQuaternionCache;
         private _xrInvQuaternionCache;
-        private _realWorldHeight;
-        /**
-         * Prevent the camera from calculating the real-world height
-         * If you are not using the user's height disable this for better performance
-         */
-        disableRealWorldHeightCalculation: boolean;
         /**
         /**
-         * Return the user's height, unrelated to the current ground.
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
          */
          */
-        get realWorldHeight(): number;
+        compensateOnFirstFrame: boolean;
         /**
         /**
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * @param name the name of the camera
          * @param name the name of the camera
          * @param scene the scene to add the camera to
          * @param scene the scene to add the camera to
+         * @param _xrSessionManager a constructed xr session manager
          */
          */
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
-        private _updateNumberOfRigCameras;
+        /**
+         * Return the user's height, unrelated to the current ground.
+         * This will be the y position of this camera, when ground level is 0.
+         */
+        get realWorldHeight(): number;
+        /** @hidden */
+        _updateForDualEyeDebugging(): void;
         /**
         /**
          * Sets this camera's transformation based on a non-vr camera
          * Sets this camera's transformation based on a non-vr camera
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          */
          */
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
-        /** @hidden */
-        _updateForDualEyeDebugging(): void;
+        private _updateFromXRSession;
+        private _updateNumberOfRigCameras;
         private _updateReferenceSpace;
         private _updateReferenceSpace;
         private _updateReferenceSpaceOffset;
         private _updateReferenceSpaceOffset;
-        private _updateFromXRSession;
     }
     }
 }
 }
 declare module "babylonjs/XR/webXRFeaturesManager" {
 declare module "babylonjs/XR/webXRFeaturesManager" {
@@ -44439,7 +44435,7 @@ declare module "babylonjs/XR/webXRExperienceHelper" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRControllerComponent" {
 declare module "babylonjs/XR/motionController/webXRControllerComponent" {
-    import { IMinimalMotionControllerObject, MotionControllerComponentType } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { IMinimalMotionControllerObject, MotionControllerComponentType } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
     import { IDisposable } from "babylonjs/scene";
     import { IDisposable } from "babylonjs/scene";
     /**
     /**
@@ -44527,12 +44523,12 @@ declare module "babylonjs/XR/motionController/webXRControllerComponent" {
          * Observers registered here will be triggered when the state of a button changes
          * Observers registered here will be triggered when the state of a button changes
          * State change is either pressed / touched / value
          * State change is either pressed / touched / value
          */
          */
-        onButtonStateChanged: Observable<WebXRControllerComponent>;
+        onButtonStateChangedObservable: Observable<WebXRControllerComponent>;
         /**
         /**
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * the axes data changes
          * the axes data changes
          */
          */
-        onAxisValueChanged: Observable<{
+        onAxisValueChangedObservable: Observable<{
             x: number;
             x: number;
             y: number;
             y: number;
         }>;
         }>;
@@ -45026,7 +45022,7 @@ declare module "babylonjs/Loading/sceneLoader" {
         static ImportAnimationsAsync(rootUrl: string, sceneFilename?: string | File, scene?: Nullable<Scene>, overwriteAnimations?: boolean, animationGroupLoadingMode?: SceneLoaderAnimationGroupLoadingMode, targetConverter?: Nullable<(target: any) => any>, onSuccess?: Nullable<(scene: Scene) => void>, onProgress?: Nullable<(event: SceneLoaderProgressEvent) => void>, onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>): Promise<Scene>;
         static ImportAnimationsAsync(rootUrl: string, sceneFilename?: string | File, scene?: Nullable<Scene>, overwriteAnimations?: boolean, animationGroupLoadingMode?: SceneLoaderAnimationGroupLoadingMode, targetConverter?: Nullable<(target: any) => any>, onSuccess?: Nullable<(scene: Scene) => void>, onProgress?: Nullable<(event: SceneLoaderProgressEvent) => void>, onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>): Promise<Scene>;
     }
     }
 }
 }
-declare module "babylonjs/XR/motionController/webXRAbstractController" {
+declare module "babylonjs/XR/motionController/webXRAbstractMotionController" {
     import { IDisposable, Scene } from "babylonjs/scene";
     import { IDisposable, Scene } from "babylonjs/scene";
     import { WebXRControllerComponent } from "babylonjs/XR/motionController/webXRControllerComponent";
     import { WebXRControllerComponent } from "babylonjs/XR/motionController/webXRControllerComponent";
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
@@ -45383,7 +45379,7 @@ declare module "babylonjs/XR/motionController/webXRAbstractController" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRGenericMotionController" {
 declare module "babylonjs/XR/motionController/webXRGenericMotionController" {
-    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
@@ -45448,7 +45444,7 @@ declare module "babylonjs/Meshes/Builders/sphereBuilder" {
 }
 }
 declare module "babylonjs/XR/motionController/webXRProfiledMotionController" {
 declare module "babylonjs/XR/motionController/webXRProfiledMotionController" {
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
-    import { WebXRAbstractMotionController, IMotionControllerProfile } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMotionControllerProfile } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
      * A profiled motion controller has its profile loaded from an online repository.
      * A profiled motion controller has its profile loaded from an online repository.
@@ -45475,7 +45471,7 @@ declare module "babylonjs/XR/motionController/webXRProfiledMotionController" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRMotionControllerManager" {
 declare module "babylonjs/XR/motionController/webXRMotionControllerManager" {
-    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
      * A construction function type to create a new controller based on an xrInput object
      * A construction function type to create a new controller based on an xrInput object
@@ -45562,12 +45558,12 @@ declare module "babylonjs/XR/motionController/webXRMotionControllerManager" {
         static DefaultFallbacks(): void;
         static DefaultFallbacks(): void;
     }
     }
 }
 }
-declare module "babylonjs/XR/webXRController" {
+declare module "babylonjs/XR/webXRInputSource" {
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Ray } from "babylonjs/Culling/ray";
     import { Ray } from "babylonjs/Culling/ray";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
-    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     /**
     /**
      * Configuration options for the WebXR controller creation
      * Configuration options for the WebXR controller creation
      */
      */
@@ -45590,7 +45586,7 @@ declare module "babylonjs/XR/webXRController" {
     /**
     /**
      * Represents an XR controller
      * Represents an XR controller
      */
      */
-    export class WebXRController {
+    export class WebXRInputSource {
         private _scene;
         private _scene;
         /** The underlying input source for the controller  */
         /** The underlying input source for the controller  */
         inputSource: XRInputSource;
         inputSource: XRInputSource;
@@ -45624,7 +45620,7 @@ declare module "babylonjs/XR/webXRController" {
          * The object provided as event data is this controller, after associated assets were disposed.
          * The object provided as event data is this controller, after associated assets were disposed.
          * uniqueId is still available.
          * uniqueId is still available.
          */
          */
-        onDisposeObservable: Observable<WebXRController>;
+        onDisposeObservable: Observable<WebXRInputSource>;
         private _tmpQuaternion;
         private _tmpQuaternion;
         private _tmpVector;
         private _tmpVector;
         private _uniqueId;
         private _uniqueId;
@@ -45649,10 +45645,11 @@ declare module "babylonjs/XR/webXRController" {
          */
          */
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         /**
         /**
-         * Gets a world space ray coming from the controller
+         * Gets a world space ray coming from the pointer or grip
          * @param result the resulting ray
          * @param result the resulting ray
+         * @param gripIfAvailable use the grip mesh instead of the pointer, if available
          */
          */
-        getWorldPointerRayToRef(result: Ray): void;
+        getWorldPointerRayToRef(result: Ray, gripIfAvailable?: boolean): void;
         /**
         /**
          * Disposes of the object
          * Disposes of the object
          */
          */
@@ -45662,7 +45659,7 @@ declare module "babylonjs/XR/webXRController" {
 declare module "babylonjs/XR/webXRInput" {
 declare module "babylonjs/XR/webXRInput" {
     import { Observable } from "babylonjs/Misc/observable";
     import { Observable } from "babylonjs/Misc/observable";
     import { IDisposable } from "babylonjs/scene";
     import { IDisposable } from "babylonjs/scene";
-    import { WebXRController } from "babylonjs/XR/webXRController";
+    import { WebXRInputSource } from "babylonjs/XR/webXRInputSource";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRCamera } from "babylonjs/XR/webXRCamera";
     import { WebXRCamera } from "babylonjs/XR/webXRCamera";
     /**
     /**
@@ -45710,18 +45707,18 @@ declare module "babylonjs/XR/webXRInput" {
         /**
         /**
          * XR controllers being tracked
          * XR controllers being tracked
          */
          */
-        controllers: Array<WebXRController>;
+        controllers: Array<WebXRInputSource>;
         private _frameObserver;
         private _frameObserver;
         private _sessionEndedObserver;
         private _sessionEndedObserver;
         private _sessionInitObserver;
         private _sessionInitObserver;
         /**
         /**
          * Event when a controller has been connected/added
          * Event when a controller has been connected/added
          */
          */
-        onControllerAddedObservable: Observable<WebXRController>;
+        onControllerAddedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Event when a controller has been removed/disconnected
          * Event when a controller has been removed/disconnected
          */
          */
-        onControllerRemovedObservable: Observable<WebXRController>;
+        onControllerRemovedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Initializes the WebXRInput
          * Initializes the WebXRInput
          * @param xrSessionManager the xr session manager for this session
          * @param xrSessionManager the xr session manager for this session
@@ -45805,7 +45802,7 @@ declare module "babylonjs/XR/features/WebXRAbstractFeature" {
 declare module "babylonjs/XR/features/WebXRControllerPointerSelection" {
 declare module "babylonjs/XR/features/WebXRControllerPointerSelection" {
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
-    import { WebXRController } from "babylonjs/XR/webXRController";
+    import { WebXRInputSource } from "babylonjs/XR/webXRInputSource";
     import { Nullable } from "babylonjs/types";
     import { Nullable } from "babylonjs/types";
     import { Color3 } from "babylonjs/Maths/math.color";
     import { Color3 } from "babylonjs/Maths/math.color";
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
@@ -45922,7 +45919,7 @@ declare module "babylonjs/XR/features/WebXRControllerPointerSelection" {
          * @param id the pointer id to search for
          * @param id the pointer id to search for
          * @returns the controller that correlates to this id or null if not found
          * @returns the controller that correlates to this id or null if not found
          */
          */
-        getXRControllerByPointerId(id: number): Nullable<WebXRController>;
+        getXRControllerByPointerId(id: number): Nullable<WebXRInputSource>;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         private _attachController;
         private _attachController;
         private _attachScreenRayMode;
         private _attachScreenRayMode;
@@ -72393,7 +72390,7 @@ declare module "babylonjs/XR/features/WebXRBackgroundRemover" {
 }
 }
 declare module "babylonjs/XR/features/WebXRControllerPhysics" {
 declare module "babylonjs/XR/features/WebXRControllerPhysics" {
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
     import { WebXRAbstractFeature } from "babylonjs/XR/features/WebXRAbstractFeature";
-    import { WebXRController } from "babylonjs/XR/webXRController";
+    import { WebXRInputSource } from "babylonjs/XR/webXRInputSource";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
     import { WebXRInput } from "babylonjs/XR/webXRInput";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
     /**
     /**
@@ -72494,7 +72491,7 @@ declare module "babylonjs/XR/features/WebXRControllerPhysics" {
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * @param xrController the controller to add
          * @param xrController the controller to add
          */
          */
-        addController(xrController: WebXRController): void;
+        addController(xrController: WebXRInputSource): void;
         private _debugMode;
         private _debugMode;
         /**
         /**
          * @hidden
          * @hidden
@@ -72516,7 +72513,7 @@ declare module "babylonjs/XR/features/index" {
     export * from "babylonjs/XR/features/WebXRControllerPhysics";
     export * from "babylonjs/XR/features/WebXRControllerPhysics";
 }
 }
 declare module "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController" {
 declare module "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController" {
-    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
@@ -72600,7 +72597,7 @@ declare module "babylonjs/XR/motionController/webXRMicrosoftMixedRealityControll
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXROculusTouchMotionController" {
 declare module "babylonjs/XR/motionController/webXROculusTouchMotionController" {
-    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { WebXRAbstractMotionController, IMinimalMotionControllerObject, MotionControllerHandness } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     /**
     /**
@@ -72644,7 +72641,7 @@ declare module "babylonjs/XR/motionController/webXROculusTouchMotionController"
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/webXRHTCViveMotionController" {
 declare module "babylonjs/XR/motionController/webXRHTCViveMotionController" {
-    import { IMinimalMotionControllerObject, MotionControllerHandness, WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractController";
+    import { IMinimalMotionControllerObject, MotionControllerHandness, WebXRAbstractMotionController } from "babylonjs/XR/motionController/webXRAbstractMotionController";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     /**
     /**
@@ -72679,7 +72676,7 @@ declare module "babylonjs/XR/motionController/webXRHTCViveMotionController" {
     }
     }
 }
 }
 declare module "babylonjs/XR/motionController/index" {
 declare module "babylonjs/XR/motionController/index" {
-    export * from "babylonjs/XR/motionController/webXRAbstractController";
+    export * from "babylonjs/XR/motionController/webXRAbstractMotionController";
     export * from "babylonjs/XR/motionController/webXRControllerComponent";
     export * from "babylonjs/XR/motionController/webXRControllerComponent";
     export * from "babylonjs/XR/motionController/webXRGenericMotionController";
     export * from "babylonjs/XR/motionController/webXRGenericMotionController";
     export * from "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController";
     export * from "babylonjs/XR/motionController/webXRMicrosoftMixedRealityController";
@@ -72693,7 +72690,7 @@ declare module "babylonjs/XR/index" {
     export * from "babylonjs/XR/webXREnterExitUI";
     export * from "babylonjs/XR/webXREnterExitUI";
     export * from "babylonjs/XR/webXRExperienceHelper";
     export * from "babylonjs/XR/webXRExperienceHelper";
     export * from "babylonjs/XR/webXRInput";
     export * from "babylonjs/XR/webXRInput";
-    export * from "babylonjs/XR/webXRController";
+    export * from "babylonjs/XR/webXRInputSource";
     export * from "babylonjs/XR/webXRManagedOutputCanvas";
     export * from "babylonjs/XR/webXRManagedOutputCanvas";
     export * from "babylonjs/XR/webXRTypes";
     export * from "babylonjs/XR/webXRTypes";
     export * from "babylonjs/XR/webXRSessionManager";
     export * from "babylonjs/XR/webXRSessionManager";
@@ -115510,48 +115507,44 @@ declare module BABYLON {
 declare module BABYLON {
 declare module BABYLON {
     /**
     /**
      * WebXR Camera which holds the views for the xrSession
      * WebXR Camera which holds the views for the xrSession
-     * @see https://doc.babylonjs.com/how_to/webxr
+     * @see https://doc.babylonjs.com/how_to/webxr_camera
      */
      */
     export class WebXRCamera extends FreeCamera {
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
         private _xrSessionManager;
-        /**
-         * Should position compensation execute on first frame.
-         * This is used when copying the position from a native (non XR) camera
-         */
-        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _firstFrame;
-        private _referencedPosition;
         private _referenceQuaternion;
         private _referenceQuaternion;
+        private _referencedPosition;
         private _xrInvPositionCache;
         private _xrInvPositionCache;
         private _xrInvQuaternionCache;
         private _xrInvQuaternionCache;
-        private _realWorldHeight;
-        /**
-         * Prevent the camera from calculating the real-world height
-         * If you are not using the user's height disable this for better performance
-         */
-        disableRealWorldHeightCalculation: boolean;
         /**
         /**
-         * Return the user's height, unrelated to the current ground.
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
          */
          */
-        get realWorldHeight(): number;
+        compensateOnFirstFrame: boolean;
         /**
         /**
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
          * @param name the name of the camera
          * @param name the name of the camera
          * @param scene the scene to add the camera to
          * @param scene the scene to add the camera to
+         * @param _xrSessionManager a constructed xr session manager
          */
          */
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
         constructor(name: string, scene: Scene, _xrSessionManager: WebXRSessionManager);
-        private _updateNumberOfRigCameras;
+        /**
+         * Return the user's height, unrelated to the current ground.
+         * This will be the y position of this camera, when ground level is 0.
+         */
+        get realWorldHeight(): number;
+        /** @hidden */
+        _updateForDualEyeDebugging(): void;
         /**
         /**
          * Sets this camera's transformation based on a non-vr camera
          * Sets this camera's transformation based on a non-vr camera
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param otherCamera the non-vr camera to copy the transformation from
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          * @param resetToBaseReferenceSpace should XR reset to the base reference space
          */
          */
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
         setTransformationFromNonVRCamera(otherCamera?: Camera, resetToBaseReferenceSpace?: boolean): void;
-        /** @hidden */
-        _updateForDualEyeDebugging(): void;
+        private _updateFromXRSession;
+        private _updateNumberOfRigCameras;
         private _updateReferenceSpace;
         private _updateReferenceSpace;
         private _updateReferenceSpaceOffset;
         private _updateReferenceSpaceOffset;
-        private _updateFromXRSession;
     }
     }
 }
 }
 declare module BABYLON {
 declare module BABYLON {
@@ -115882,12 +115875,12 @@ declare module BABYLON {
          * Observers registered here will be triggered when the state of a button changes
          * Observers registered here will be triggered when the state of a button changes
          * State change is either pressed / touched / value
          * State change is either pressed / touched / value
          */
          */
-        onButtonStateChanged: Observable<WebXRControllerComponent>;
+        onButtonStateChangedObservable: Observable<WebXRControllerComponent>;
         /**
         /**
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
          * the axes data changes
          * the axes data changes
          */
          */
-        onAxisValueChanged: Observable<{
+        onAxisValueChangedObservable: Observable<{
             x: number;
             x: number;
             y: number;
             y: number;
         }>;
         }>;
@@ -116912,7 +116905,7 @@ declare module BABYLON {
     /**
     /**
      * Represents an XR controller
      * Represents an XR controller
      */
      */
-    export class WebXRController {
+    export class WebXRInputSource {
         private _scene;
         private _scene;
         /** The underlying input source for the controller  */
         /** The underlying input source for the controller  */
         inputSource: XRInputSource;
         inputSource: XRInputSource;
@@ -116946,7 +116939,7 @@ declare module BABYLON {
          * The object provided as event data is this controller, after associated assets were disposed.
          * The object provided as event data is this controller, after associated assets were disposed.
          * uniqueId is still available.
          * uniqueId is still available.
          */
          */
-        onDisposeObservable: Observable<WebXRController>;
+        onDisposeObservable: Observable<WebXRInputSource>;
         private _tmpQuaternion;
         private _tmpQuaternion;
         private _tmpVector;
         private _tmpVector;
         private _uniqueId;
         private _uniqueId;
@@ -116971,10 +116964,11 @@ declare module BABYLON {
          */
          */
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace): void;
         /**
         /**
-         * Gets a world space ray coming from the controller
+         * Gets a world space ray coming from the pointer or grip
          * @param result the resulting ray
          * @param result the resulting ray
+         * @param gripIfAvailable use the grip mesh instead of the pointer, if available
          */
          */
-        getWorldPointerRayToRef(result: Ray): void;
+        getWorldPointerRayToRef(result: Ray, gripIfAvailable?: boolean): void;
         /**
         /**
          * Disposes of the object
          * Disposes of the object
          */
          */
@@ -117027,18 +117021,18 @@ declare module BABYLON {
         /**
         /**
          * XR controllers being tracked
          * XR controllers being tracked
          */
          */
-        controllers: Array<WebXRController>;
+        controllers: Array<WebXRInputSource>;
         private _frameObserver;
         private _frameObserver;
         private _sessionEndedObserver;
         private _sessionEndedObserver;
         private _sessionInitObserver;
         private _sessionInitObserver;
         /**
         /**
          * Event when a controller has been connected/added
          * Event when a controller has been connected/added
          */
          */
-        onControllerAddedObservable: Observable<WebXRController>;
+        onControllerAddedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Event when a controller has been removed/disconnected
          * Event when a controller has been removed/disconnected
          */
          */
-        onControllerRemovedObservable: Observable<WebXRController>;
+        onControllerRemovedObservable: Observable<WebXRInputSource>;
         /**
         /**
          * Initializes the WebXRInput
          * Initializes the WebXRInput
          * @param xrSessionManager the xr session manager for this session
          * @param xrSessionManager the xr session manager for this session
@@ -117230,7 +117224,7 @@ declare module BABYLON {
          * @param id the pointer id to search for
          * @param id the pointer id to search for
          * @returns the controller that correlates to this id or null if not found
          * @returns the controller that correlates to this id or null if not found
          */
          */
-        getXRControllerByPointerId(id: number): Nullable<WebXRController>;
+        getXRControllerByPointerId(id: number): Nullable<WebXRInputSource>;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         protected _onXRFrame(_xrFrame: XRFrame): void;
         private _attachController;
         private _attachController;
         private _attachScreenRayMode;
         private _attachScreenRayMode;
@@ -141626,7 +141620,7 @@ declare module BABYLON {
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
          * @param xrController the controller to add
          * @param xrController the controller to add
          */
          */
-        addController(xrController: WebXRController): void;
+        addController(xrController: WebXRInputSource): void;
         private _debugMode;
         private _debugMode;
         /**
         /**
          * @hidden
          * @hidden

文件差异内容过多而无法显示
+ 23 - 23
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 2
dist/preview release/what's new.md

@@ -60,7 +60,6 @@
 - Make sure all properties of CascadedShadowMap class are serialized/parsed ([Popov72](https://github.com/Popov72))
 - Make sure all properties of CascadedShadowMap class are serialized/parsed ([Popov72](https://github.com/Popov72))
 - Added `textures/opacity.png` file to the Playground ([Popov72](https://github.com/Popov72))
 - Added `textures/opacity.png` file to the Playground ([Popov72](https://github.com/Popov72))
 - Refactored the shadow generators code ([Popov72](https://github.com/Popov72))
 - Refactored the shadow generators code ([Popov72](https://github.com/Popov72))
-- Added preview area pop up for NME ([Kyle Belfort](https://github.com/belfortk))
 - Supports clip planes with shadows ([sebavan](http://www.github.com/sebavan))
 - Supports clip planes with shadows ([sebavan](http://www.github.com/sebavan))
 - Added Workbench color scheme for VSCode ([drigax](https://github.com/drigax) & [Patrick Ryan](https://github.com/PatrickRyanMS))
 - Added Workbench color scheme for VSCode ([drigax](https://github.com/drigax) & [Patrick Ryan](https://github.com/PatrickRyanMS))
 
 
@@ -107,6 +106,8 @@
 - Added diff navigator in the playground ([sailro](http://www.github.com/sailro))
 - Added diff navigator in the playground ([sailro](http://www.github.com/sailro))
 - Added custom filter to remove internals from the completion in the playground ([sailro](http://www.github.com/sailro))
 - Added custom filter to remove internals from the completion in the playground ([sailro](http://www.github.com/sailro))
 - Added support for tagging deprecated members (both in editor and for completion) in the playground ([sailro](http://www.github.com/sailro))
 - Added support for tagging deprecated members (both in editor and for completion) in the playground ([sailro](http://www.github.com/sailro))
+- Added preview area pop up for NME ([Kyle Belfort](https://github.com/belfortk))
+- Added comments to frames in NME ([Kyle Belfort](https://github.com/belfortk))
 
 
 ### Meshes
 ### Meshes
 
 
@@ -205,7 +206,7 @@
 - Selection has gaze mode (which can be forced) and touch-screen support ([#7395](https://github.com/BabylonJS/Babylon.js/issues/7395)) ([RaananW](https://github.com/RaananW/))
 - Selection has gaze mode (which can be forced) and touch-screen support ([#7395](https://github.com/BabylonJS/Babylon.js/issues/7395)) ([RaananW](https://github.com/RaananW/))
 - Laser pointers can be excluded from lighting influence so that they are always visible in both WebXR and WebVR ([#7323](https://github.com/BabylonJS/Babylon.js/issues/7323)) ([RaananW](https://github.com/RaananW/))
 - Laser pointers can be excluded from lighting influence so that they are always visible in both WebXR and WebVR ([#7323](https://github.com/BabylonJS/Babylon.js/issues/7323)) ([RaananW](https://github.com/RaananW/))
 - Full support for the online motion controller repository ([#7323](https://github.com/BabylonJS/Babylon.js/issues/7323)) ([RaananW](https://github.com/RaananW/))
 - Full support for the online motion controller repository ([#7323](https://github.com/BabylonJS/Babylon.js/issues/7323)) ([RaananW](https://github.com/RaananW/))
-- New feature - XR Controller physics impostor ([RaananW](https://github.com/RaananW/))
+- New feature - XR Controller physics impostor for motion controllers ([RaananW](https://github.com/RaananW/))
 - Teleportation between different ground levels in WebXR is enabled ([RaananW](https://github.com/RaananW/))
 - Teleportation between different ground levels in WebXR is enabled ([RaananW](https://github.com/RaananW/))
 
 
 ### Ray
 ### Ray

+ 106 - 0
gui/src/2D/controls/scrollViewers/scrollViewer.ts

@@ -27,7 +27,11 @@ export class ScrollViewer extends Rectangle {
     private _barColor: string;
     private _barColor: string;
     private _barBackground: string;
     private _barBackground: string;
     private _barImage: Image;
     private _barImage: Image;
+    private _horizontalBarImage: Image;
+    private _verticalBarImage: Image;
     private _barBackgroundImage: Image;
     private _barBackgroundImage: Image;
+    private _horizontalBarBackgroundImage: Image;
+    private _verticalBarBackgroundImage: Image;
     private _barSize: number = 20;
     private _barSize: number = 20;
     private _window: _ScrollViewerWindow;
     private _window: _ScrollViewerWindow;
     private _pointerIsOver: Boolean = false;
     private _pointerIsOver: Boolean = false;
@@ -39,6 +43,8 @@ export class ScrollViewer extends Rectangle {
     private _thumbLength: number = 0.5;
     private _thumbLength: number = 0.5;
     private _thumbHeight: number = 1;
     private _thumbHeight: number = 1;
     private _barImageHeight: number = 1;
     private _barImageHeight: number = 1;
+    private _horizontalBarImageHeight: number = 1;
+    private _verticalBarImageHeight: number = 1;
 
 
     /**
     /**
      * Gets the horizontal scrollbar
      * Gets the horizontal scrollbar
@@ -326,6 +332,36 @@ export class ScrollViewer extends Rectangle {
         vb.thumbImage = value;
         vb.thumbImage = value;
     }
     }
 
 
+    /** Gets or sets the horizontal bar image */
+    public get horizontalThumbImage(): Image {
+        return this._horizontalBarImage;
+    }
+
+    public set horizontalThumbImage(value: Image) {
+        if (this._horizontalBarImage === value) {
+            return;
+        }
+
+        this._horizontalBarImage = value;
+        let hb = <ImageScrollBar>this._horizontalBar;
+        hb.thumbImage = value;
+    }
+
+    /** Gets or sets the vertical bar image */
+    public get verticalThumbImage(): Image {
+        return this._verticalBarImage;
+    }
+
+    public set verticalThumbImage(value: Image) {
+        if (this._verticalBarImage === value) {
+            return;
+        }
+
+        this._verticalBarImage = value;
+        let vb = <ImageScrollBar>this._verticalBar;
+        vb.thumbImage = value;
+    }
+
     /** Gets or sets the size of the bar */
     /** Gets or sets the size of the bar */
     public get barSize(): number {
     public get barSize(): number {
         return this._barSize;
         return this._barSize;
@@ -416,6 +452,48 @@ export class ScrollViewer extends Rectangle {
         this._markAsDirty();
         this._markAsDirty();
     }
     }
 
 
+    /** Gets or sets the height of the horizontal bar image */
+    public get horizontalBarImageHeight(): number {
+        return this._horizontalBarImageHeight;
+    }
+
+    public set horizontalBarImageHeight(value: number) {
+        if (this._horizontalBarImageHeight === value) {
+            return;
+        }
+        if (value <= 0) {
+            value = 0.1;
+        }
+        if (value > 1) {
+            value = 1;
+        }
+        this._horizontalBarImageHeight = value;
+        var hb = <ImageScrollBar>this._horizontalBar;
+        hb.barImageHeight = value;
+        this._markAsDirty();
+    }
+
+    /** Gets or sets the height of the vertical bar image */
+    public get verticalBarImageHeight(): number {
+        return this._verticalBarImageHeight;
+    }
+
+    public set verticalBarImageHeight(value: number) {
+        if (this._verticalBarImageHeight === value) {
+            return;
+        }
+        if (value <= 0) {
+            value = 0.1;
+        }
+        if (value > 1) {
+            value = 1;
+        }
+        this._verticalBarImageHeight = value;
+        var vb = <ImageScrollBar>this._verticalBar;
+        vb.barImageHeight = value;
+        this._markAsDirty();
+    }
+
     /** Gets or sets the bar background */
     /** Gets or sets the bar background */
     public get barBackground(): string {
     public get barBackground(): string {
         return this._barBackground;
         return this._barBackground;
@@ -450,6 +528,34 @@ export class ScrollViewer extends Rectangle {
         vb.backgroundImage = value;
         vb.backgroundImage = value;
     }
     }
 
 
+    /** Gets or sets the horizontal bar background image */
+    public get horizontalBarImage(): Image {
+        return this._horizontalBarBackgroundImage;
+    }
+
+    public set horizontalBarImage(value: Image) {
+        if (this._horizontalBarBackgroundImage === value) {
+        }
+
+        this._horizontalBarBackgroundImage = value;
+        let hb = <ImageScrollBar>this._horizontalBar;
+        hb.backgroundImage = value;
+    }
+
+    /** Gets or sets the vertical bar background image */
+    public get verticalBarImage(): Image {
+        return this._verticalBarBackgroundImage;
+    }
+
+    public set verticalBarImage(value: Image) {
+        if (this._verticalBarBackgroundImage === value) {
+        }
+
+        this._verticalBarBackgroundImage = value;
+        let vb = <ImageScrollBar>this._verticalBar;
+        vb.backgroundImage = value;
+    }
+
     private _setWindowPosition(): void {
     private _setWindowPosition(): void {
         let ratio = this.host.idealRatio;
         let ratio = this.host.idealRatio;
         let windowContentsWidth = this._window._currentMeasure.width;
         let windowContentsWidth = this._window._currentMeasure.width;

+ 33 - 4
nodeEditor/src/diagram/graphFrame.ts

@@ -25,7 +25,8 @@ export class GraphFrame {
     private _headerElement: HTMLDivElement;    
     private _headerElement: HTMLDivElement;    
     private _headerTextElement: HTMLDivElement;        
     private _headerTextElement: HTMLDivElement;        
     private _headerCollapseElement: HTMLDivElement;    
     private _headerCollapseElement: HTMLDivElement;    
-    private _headerCloseElement: HTMLDivElement;    
+    private _headerCloseElement: HTMLDivElement;
+    private _commentsElement: HTMLDivElement;    
     private _portContainer: HTMLDivElement;    
     private _portContainer: HTMLDivElement;    
     private _outputPortContainer: HTMLDivElement;    
     private _outputPortContainer: HTMLDivElement;    
     private _inputPortContainer: HTMLDivElement;    
     private _inputPortContainer: HTMLDivElement;    
@@ -38,6 +39,7 @@ export class GraphFrame {
     private _ports: NodePort[] = [];
     private _ports: NodePort[] = [];
     private _controlledPorts: NodePort[] = [];
     private _controlledPorts: NodePort[] = [];
     private _id: number;
     private _id: number;
+    private _comments: string;
 
 
     public onExpandStateChanged = new Observable<GraphFrame>();
     public onExpandStateChanged = new Observable<GraphFrame>();
 
 
@@ -241,6 +243,24 @@ export class GraphFrame {
         this.element.style.height = `${gridAlignedBottom - this._gridAlignedY}px`;
         this.element.style.height = `${gridAlignedBottom - this._gridAlignedY}px`;
     }
     }
 
 
+    public get comments(): string {
+        return this._comments;
+    }
+
+    public set comments(comments: string) {
+        if (comments.length > 0) {
+            this.element.style.gridTemplateRows = "40px 40px calc(100% - 80px)";
+            this._borderElement.style.gridRow = "1 / span 3";
+            this._portContainer.style.gridRow = "3";
+            this._commentsElement.style.display = "grid";
+            this._commentsElement.style.gridRow = "2";
+            this._commentsElement.style.gridColumn = "1";
+            this._commentsElement.style.paddingLeft = "10px";
+        }
+        this._comments = comments;
+        this._commentsElement.innerText = comments;
+    }
+
     public constructor(candidate: Nullable<HTMLDivElement>, canvas: GraphCanvasComponent, doNotCaptureNodes = false) {
     public constructor(candidate: Nullable<HTMLDivElement>, canvas: GraphCanvasComponent, doNotCaptureNodes = false) {
         this._id = GraphFrame._FrameCounter++;
         this._id = GraphFrame._FrameCounter++;
 
 
@@ -331,8 +351,15 @@ export class GraphFrame {
             } else {
             } else {
                 this.element.classList.remove("selected");
                 this.element.classList.remove("selected");
             }
             }
-        });  
-                
+        }); 
+
+        this._commentsElement = document.createElement('div');
+        this._commentsElement.className = 'frame-comments';
+        this._commentsElement.style.color = 'white';
+        this._commentsElement.style.fontSize = '16px';
+        
+        this.element.appendChild(this._commentsElement);
+
         // Get nodes
         // Get nodes
         if (!doNotCaptureNodes) {
         if (!doNotCaptureNodes) {
             this.refresh();
             this.refresh();
@@ -471,7 +498,8 @@ export class GraphFrame {
             color: this._color.asArray(),
             color: this._color.asArray(),
             name: this.name,
             name: this.name,
             isCollapsed: this.isCollapsed,
             isCollapsed: this.isCollapsed,
-            blocks: this.nodes.map(n => n.block.uniqueId)
+            blocks: this.nodes.map(n => n.block.uniqueId),
+            comments: this._comments
         }
         }
     }
     }
 
 
@@ -491,6 +519,7 @@ export class GraphFrame {
         newFrame.height = serializationData.height;
         newFrame.height = serializationData.height;
         newFrame.name = serializationData.name;
         newFrame.name = serializationData.name;
         newFrame.color = Color3.FromArray(serializationData.color);
         newFrame.color = Color3.FromArray(serializationData.color);
+        newFrame.comments = serializationData.comments;
 
 
         if (serializationData.blocks && map) {
         if (serializationData.blocks && map) {
             for (var blockId of serializationData.blocks) {
             for (var blockId of serializationData.blocks) {

+ 3 - 0
nodeEditor/src/diagram/properties/framePropertyComponent.tsx

@@ -46,6 +46,9 @@ export class FramePropertyTabComponent extends React.Component<IFramePropertyTab
                 <LineContainerComponent title="GENERAL">
                 <LineContainerComponent title="GENERAL">
                     <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.props.frame} />
                     <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.props.frame} />
                     <Color3LineComponent globalState={this.props.globalState} label="Color" target={this.props.frame} propertyName="color"></Color3LineComponent>
                     <Color3LineComponent globalState={this.props.globalState} label="Color" target={this.props.frame} propertyName="color"></Color3LineComponent>
+                    <TextInputLineComponent globalState={this.props.globalState} label="Comments" propertyName="comments" target={this.props.frame}
+                    />
+
                     {
                     {
                         !this.props.frame.isCollapsed &&
                         !this.props.frame.isCollapsed &&
                         <ButtonLineComponent label="Collapse" onClick={() => {
                         <ButtonLineComponent label="Collapse" onClick={() => {

+ 1 - 1
nodeEditor/src/globalState.ts

@@ -35,7 +35,7 @@ export class GlobalState {
     onAnimationCommandActivated = new Observable<void>();
     onAnimationCommandActivated = new Observable<void>();
     onCandidateLinkMoved = new Observable<Nullable<Vector2>>();   
     onCandidateLinkMoved = new Observable<Nullable<Vector2>>();   
     onSelectionBoxMoved = new Observable<ClientRect | DOMRect>();       
     onSelectionBoxMoved = new Observable<ClientRect | DOMRect>();       
-    onFrameCreated = new Observable<GraphFrame>();   
+    onFrameCreated = new Observable<GraphFrame>();
     onCandidatePortSelected = new Observable<Nullable<NodePort>>();
     onCandidatePortSelected = new Observable<Nullable<NodePort>>();
     onGetNodeFromBlock: (block: NodeMaterialBlock) => GraphNode;
     onGetNodeFromBlock: (block: NodeMaterialBlock) => GraphNode;
     onGridSizeChanged = new Observable<void>();
     onGridSizeChanged = new Observable<void>();

+ 1 - 1
nodeEditor/src/graphEditor.tsx

@@ -116,7 +116,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps, State> {
         let nodeType: NodeMaterialBlockConnectionPointTypes = BlockTools.GetConnectionNodeTypeFromString(type);
         let nodeType: NodeMaterialBlockConnectionPointTypes = BlockTools.GetConnectionNodeTypeFromString(type);
 
 
         let newInputBlock = new InputBlock(type, undefined, nodeType);
         let newInputBlock = new InputBlock(type, undefined, nodeType);
-        return this.createNodeFromObject(newInputBlock)
+        return this.createNodeFromObject(newInputBlock);
     }
     }
 
 
     componentDidMount() {
     componentDidMount() {

+ 4 - 3
nodeEditor/src/nodeLocationInfo.ts

@@ -10,9 +10,10 @@ export interface IFrameData {
     width: number;
     width: number;
     height: number;
     height: number;
     color: number[];
     color: number[];
-    name: string,
-    isCollapsed: boolean,
-    blocks: number[]
+    name: string;
+    isCollapsed: boolean;
+    blocks: number[];
+    comments: string;
 }
 }
 
 
 export interface IEditorData {
 export interface IEditorData {

+ 4 - 4
src/XR/features/WebXRControllerPhysics.ts

@@ -1,6 +1,6 @@
 import { WebXRAbstractFeature } from "./WebXRAbstractFeature";
 import { WebXRAbstractFeature } from "./WebXRAbstractFeature";
 import { Vector3, Quaternion } from "../../Maths/math.vector";
 import { Vector3, Quaternion } from "../../Maths/math.vector";
-import { WebXRController } from "../webXRController";
+import { WebXRInputSource } from "../webXRInputSource";
 import { PhysicsImpostor } from "../../Physics/physicsImpostor";
 import { PhysicsImpostor } from "../../Physics/physicsImpostor";
 import { WebXRInput } from "../webXRInput";
 import { WebXRInput } from "../webXRInput";
 import { WebXRSessionManager } from "../webXRSessionManager";
 import { WebXRSessionManager } from "../webXRSessionManager";
@@ -67,7 +67,7 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
 
 
     private _controllers: {
     private _controllers: {
         [id: string]: {
         [id: string]: {
-            xrController: WebXRController;
+            xrController: WebXRInputSource;
             impostorMesh?: AbstractMesh,
             impostorMesh?: AbstractMesh,
             impostor: PhysicsImpostor
             impostor: PhysicsImpostor
             oldPos?: Vector3;
             oldPos?: Vector3;
@@ -154,7 +154,7 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
      * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
      * Manually add a controller (if no xrInput was provided or physics engine was not enabled)
      * @param xrController the controller to add
      * @param xrController the controller to add
      */
      */
-    public addController(xrController: WebXRController) {
+    public addController(xrController: WebXRInputSource) {
         this._attachController(xrController);
         this._attachController(xrController);
     }
     }
 
 
@@ -174,7 +174,7 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
         });
         });
     }
     }
 
 
-    private _attachController = (xrController: WebXRController
+    private _attachController = (xrController: WebXRInputSource
     ) => {
     ) => {
         if (this._controllers[xrController.uniqueId]) {
         if (this._controllers[xrController.uniqueId]) {
             // already attached
             // already attached

+ 10 - 10
src/XR/features/WebXRControllerPointerSelection.ts

@@ -3,7 +3,7 @@ import { WebXRSessionManager } from '../webXRSessionManager';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Observer } from '../../Misc/observable';
 import { Observer } from '../../Misc/observable';
 import { WebXRInput } from '../webXRInput';
 import { WebXRInput } from '../webXRInput';
-import { WebXRController } from '../webXRController';
+import { WebXRInputSource } from '../webXRInputSource';
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
 import { WebXRControllerComponent } from '../motionController/webXRControllerComponent';
 import { WebXRControllerComponent } from '../motionController/webXRControllerComponent';
 import { Nullable } from '../../types';
 import { Nullable } from '../../types';
@@ -115,7 +115,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
 
 
     private _controllers: {
     private _controllers: {
         [controllerUniqueId: string]: {
         [controllerUniqueId: string]: {
-            xrController: WebXRController;
+            xrController: WebXRInputSource;
             selectionComponent?: WebXRControllerComponent;
             selectionComponent?: WebXRControllerComponent;
             onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;
             onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;
             onFrameObserver?: Nullable<Observer<XRFrame>>;
             onFrameObserver?: Nullable<Observer<XRFrame>>;
@@ -183,7 +183,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
      * @param id the pointer id to search for
      * @param id the pointer id to search for
      * @returns the controller that correlates to this id or null if not found
      * @returns the controller that correlates to this id or null if not found
      */
      */
-    public getXRControllerByPointerId(id: number): Nullable<WebXRController> {
+    public getXRControllerByPointerId(id: number): Nullable<WebXRInputSource> {
         const keys = Object.keys(this._controllers);
         const keys = Object.keys(this._controllers);
 
 
         for (let i = 0; i < keys.length; ++i) {
         for (let i = 0; i < keys.length; ++i) {
@@ -231,7 +231,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         });
         });
     }
     }
 
 
-    private _attachController = (xrController: WebXRController) => {
+    private _attachController = (xrController: WebXRInputSource) => {
         if (this._controllers[xrController.uniqueId]) {
         if (this._controllers[xrController.uniqueId]) {
             // already attached
             // already attached
             return;
             return;
@@ -257,7 +257,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         }
         }
     }
     }
 
 
-    private _attachScreenRayMode(xrController: WebXRController) {
+    private _attachScreenRayMode(xrController: WebXRInputSource) {
         const controllerData = this._controllers[xrController.uniqueId];
         const controllerData = this._controllers[xrController.uniqueId];
         let downTriggered = false;
         let downTriggered = false;
         controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {
         controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {
@@ -279,7 +279,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         });
         });
     }
     }
 
 
-    private _attachGazeMode(xrController: WebXRController) {
+    private _attachGazeMode(xrController: WebXRInputSource) {
         const controllerData = this._controllers[xrController.uniqueId];
         const controllerData = this._controllers[xrController.uniqueId];
         // attached when touched, detaches when raised
         // attached when touched, detaches when raised
         const timeToSelect = this._options.timeToSelect || 3000;
         const timeToSelect = this._options.timeToSelect || 3000;
@@ -356,7 +356,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
 
 
     }
     }
 
 
-    private _attachTrackedPointerRayMode(xrController: WebXRController) {
+    private _attachTrackedPointerRayMode(xrController: WebXRInputSource) {
         xrController.onMotionControllerInitObservable.add((motionController) => {
         xrController.onMotionControllerInitObservable.add((motionController) => {
             if (this._options.forceGazeMode) {
             if (this._options.forceGazeMode) {
                 return this._attachGazeMode(xrController);
                 return this._attachGazeMode(xrController);
@@ -388,7 +388,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
                 }
                 }
             });
             });
 
 
-            controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChanged.add((component) => {
+            controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add((component) => {
                 if (component.changes.pressed) {
                 if (component.changes.pressed) {
                     const pressed = component.changes.pressed.current;
                     const pressed = component.changes.pressed.current;
                     if (controllerData.pick) {
                     if (controllerData.pick) {
@@ -409,7 +409,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         if (!controllerData) { return; }
         if (!controllerData) { return; }
         if (controllerData.selectionComponent) {
         if (controllerData.selectionComponent) {
             if (controllerData.onButtonChangedObserver) {
             if (controllerData.onButtonChangedObserver) {
-                controllerData.selectionComponent.onButtonStateChanged.remove(controllerData.onButtonChangedObserver);
+                controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);
             }
             }
         }
         }
         if (controllerData.onFrameObserver) {
         if (controllerData.onFrameObserver) {
@@ -421,7 +421,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         delete this._controllers[xrControllerUniqueId];
         delete this._controllers[xrControllerUniqueId];
     }
     }
 
 
-    private _generateNewMeshPair(xrController: WebXRController) {
+    private _generateNewMeshPair(xrController: WebXRInputSource) {
         const laserPointer = CylinderBuilder.CreateCylinder("laserPointer", {
         const laserPointer = CylinderBuilder.CreateCylinder("laserPointer", {
             height: 1,
             height: 1,
             diameterTop: 0.0002,
             diameterTop: 0.0002,

+ 8 - 8
src/XR/features/WebXRControllerTeleportation.ts

@@ -3,7 +3,7 @@ import { Observer } from '../../Misc/observable';
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { Nullable } from '../../types';
 import { Nullable } from '../../types';
 import { WebXRInput } from '../webXRInput';
 import { WebXRInput } from '../webXRInput';
-import { WebXRController } from '../webXRController';
+import { WebXRInputSource } from '../webXRInputSource';
 import { WebXRControllerComponent, IWebXRMotionControllerAxesValue } from '../motionController/webXRControllerComponent';
 import { WebXRControllerComponent, IWebXRMotionControllerAxesValue } from '../motionController/webXRControllerComponent';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Vector3, Quaternion } from '../../Maths/math.vector';
 import { Vector3, Quaternion } from '../../Maths/math.vector';
@@ -169,7 +169,7 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
 
 
     private _controllers: {
     private _controllers: {
         [controllerUniqueId: string]: {
         [controllerUniqueId: string]: {
-            xrController: WebXRController;
+            xrController: WebXRInputSource;
             teleportationComponent?: WebXRControllerComponent;
             teleportationComponent?: WebXRControllerComponent;
             teleportationState: {
             teleportationState: {
                 forward: boolean;
                 forward: boolean;
@@ -315,7 +315,7 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
 
 
     private _currentTeleportationControllerId: string;
     private _currentTeleportationControllerId: string;
 
 
-    private _attachController = (xrController: WebXRController) => {
+    private _attachController = (xrController: WebXRInputSource) => {
         if (this._controllers[xrController.uniqueId]) {
         if (this._controllers[xrController.uniqueId]) {
             // already attached
             // already attached
             return;
             return;
@@ -341,7 +341,7 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
                     if (!mainComponent) {
                     if (!mainComponent) {
                         return;
                         return;
                     }
                     }
-                    controllerData.onButtonChangedObserver = mainComponent.onButtonStateChanged.add(() => {
+                    controllerData.onButtonChangedObserver = mainComponent.onButtonStateChangedObservable.add(() => {
                         // did "pressed" changed?
                         // did "pressed" changed?
                         if (mainComponent.changes.pressed) {
                         if (mainComponent.changes.pressed) {
                             if (mainComponent.changes.pressed.current) {
                             if (mainComponent.changes.pressed.current) {
@@ -374,13 +374,13 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
                         }
                         }
                     });
                     });
                 } else {
                 } else {
-                    controllerData.onButtonChangedObserver = movementController.onButtonStateChanged.add(() => {
+                    controllerData.onButtonChangedObserver = movementController.onButtonStateChangedObservable.add(() => {
                         if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward && !movementController.touched) {
                         if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward && !movementController.touched) {
                             this._teleportForward(xrController.uniqueId);
                             this._teleportForward(xrController.uniqueId);
                         }
                         }
                     });
                     });
                     // use thumbstick (or touchpad if thumbstick not available)
                     // use thumbstick (or touchpad if thumbstick not available)
-                    controllerData.onAxisChangedObserver = movementController.onAxisValueChanged.add((axesData) => {
+                    controllerData.onAxisChangedObserver = movementController.onAxisValueChangedObservable.add((axesData) => {
                         if (axesData.y <= 0.7 && controllerData.teleportationState.backwards) {
                         if (axesData.y <= 0.7 && controllerData.teleportationState.backwards) {
                             //if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {
                             //if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {
                             controllerData.teleportationState.backwards = false;
                             controllerData.teleportationState.backwards = false;
@@ -462,10 +462,10 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
         if (!controllerData) { return; }
         if (!controllerData) { return; }
         if (controllerData.teleportationComponent) {
         if (controllerData.teleportationComponent) {
             if (controllerData.onAxisChangedObserver) {
             if (controllerData.onAxisChangedObserver) {
-                controllerData.teleportationComponent.onAxisValueChanged.remove(controllerData.onAxisChangedObserver);
+                controllerData.teleportationComponent.onAxisValueChangedObservable.remove(controllerData.onAxisChangedObserver);
             }
             }
             if (controllerData.onButtonChangedObserver) {
             if (controllerData.onButtonChangedObserver) {
-                controllerData.teleportationComponent.onButtonStateChanged.remove(controllerData.onButtonChangedObserver);
+                controllerData.teleportationComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);
             }
             }
         }
         }
         // remove from the map
         // remove from the map

+ 1 - 1
src/XR/index.ts

@@ -2,7 +2,7 @@ export * from "./webXRCamera";
 export * from "./webXREnterExitUI";
 export * from "./webXREnterExitUI";
 export * from "./webXRExperienceHelper";
 export * from "./webXRExperienceHelper";
 export * from "./webXRInput";
 export * from "./webXRInput";
-export * from "./webXRController";
+export * from "./webXRInputSource";
 export * from "./webXRManagedOutputCanvas";
 export * from "./webXRManagedOutputCanvas";
 export * from "./webXRTypes";
 export * from "./webXRTypes";
 export * from "./webXRSessionManager";
 export * from "./webXRSessionManager";

+ 1 - 1
src/XR/motionController/index.ts

@@ -1,4 +1,4 @@
-export * from "./webXRAbstractController";
+export * from "./webXRAbstractMotionController";
 export * from "./webXRControllerComponent";
 export * from "./webXRControllerComponent";
 export * from "./webXRGenericMotionController";
 export * from "./webXRGenericMotionController";
 export * from "./webXRMicrosoftMixedRealityController";
 export * from "./webXRMicrosoftMixedRealityController";

src/XR/motionController/webXRAbstractController.ts → src/XR/motionController/webXRAbstractMotionController.ts


+ 7 - 7
src/XR/motionController/webXRControllerComponent.ts

@@ -1,4 +1,4 @@
-import { IMinimalMotionControllerObject, MotionControllerComponentType } from "./webXRAbstractController";
+import { IMinimalMotionControllerObject, MotionControllerComponentType } from "./webXRAbstractMotionController";
 import { Observable } from '../../Misc/observable';
 import { Observable } from '../../Misc/observable';
 import { IDisposable } from '../../scene';
 import { IDisposable } from '../../scene';
 
 
@@ -80,12 +80,12 @@ export class WebXRControllerComponent implements IDisposable {
      * Observers registered here will be triggered when the state of a button changes
      * Observers registered here will be triggered when the state of a button changes
      * State change is either pressed / touched / value
      * State change is either pressed / touched / value
      */
      */
-    public onButtonStateChanged: Observable<WebXRControllerComponent> = new Observable();
+    public onButtonStateChangedObservable: Observable<WebXRControllerComponent> = new Observable();
     /**
     /**
      * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
      * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when
      * the axes data changes
      * the axes data changes
      */
      */
-    public onAxisValueChanged: Observable<{ x: number, y: number }> = new Observable();
+    public onAxisValueChangedObservable: Observable<{ x: number, y: number }> = new Observable();
 
 
     private _currentValue: number = 0;
     private _currentValue: number = 0;
     private _touched: boolean = false;
     private _touched: boolean = false;
@@ -257,11 +257,11 @@ export class WebXRControllerComponent implements IDisposable {
 
 
         if (buttonUpdated) {
         if (buttonUpdated) {
             this._hasChanges = true;
             this._hasChanges = true;
-            this.onButtonStateChanged.notifyObservers(this);
+            this.onButtonStateChangedObservable.notifyObservers(this);
         }
         }
         if (axesUpdate) {
         if (axesUpdate) {
             this._hasChanges = true;
             this._hasChanges = true;
-            this.onAxisValueChanged.notifyObservers(this._axes);
+            this.onAxisValueChangedObservable.notifyObservers(this._axes);
         }
         }
     }
     }
 
 
@@ -269,7 +269,7 @@ export class WebXRControllerComponent implements IDisposable {
      * Dispose this component
      * Dispose this component
      */
      */
     public dispose(): void {
     public dispose(): void {
-        this.onAxisValueChanged.clear();
-        this.onButtonStateChanged.clear();
+        this.onAxisValueChangedObservable.clear();
+        this.onButtonStateChangedObservable.clear();
     }
     }
 }
 }

+ 1 - 1
src/XR/motionController/webXRGenericMotionController.ts

@@ -3,7 +3,7 @@ import {
     IMinimalMotionControllerObject,
     IMinimalMotionControllerObject,
     MotionControllerHandness,
     MotionControllerHandness,
     IMotionControllerLayoutMap
     IMotionControllerLayoutMap
-} from "./webXRAbstractController";
+} from "./webXRAbstractMotionController";
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
 import { Mesh } from '../../Meshes/mesh';
 import { Mesh } from '../../Meshes/mesh';

+ 2 - 2
src/XR/motionController/webXRHTCViveMotionController.ts

@@ -3,7 +3,7 @@ import {
     IMinimalMotionControllerObject,
     IMinimalMotionControllerObject,
     MotionControllerHandness,
     MotionControllerHandness,
     WebXRAbstractMotionController
     WebXRAbstractMotionController
-} from "./webXRAbstractController";
+} from "./webXRAbstractMotionController";
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Mesh } from '../../Meshes/mesh';
 import { Mesh } from '../../Meshes/mesh';
@@ -43,7 +43,7 @@ export class WebXRHTCViveMotionController extends WebXRAbstractMotionController
         this.getComponentIds().forEach((id) => {
         this.getComponentIds().forEach((id) => {
             const comp = id && this.getComponent(id);
             const comp = id && this.getComponent(id);
             if (comp) {
             if (comp) {
-                comp.onButtonStateChanged.add((component) => {
+                comp.onButtonStateChangedObservable.add((component) => {
 
 
                     if (!this.rootMesh || this.disableAnimation) { return; }
                     if (!this.rootMesh || this.disableAnimation) { return; }
 
 

+ 3 - 3
src/XR/motionController/webXRMicrosoftMixedRealityController.ts

@@ -3,7 +3,7 @@ import {
     IMinimalMotionControllerObject,
     IMinimalMotionControllerObject,
     MotionControllerHandness,
     MotionControllerHandness,
     IMotionControllerLayoutMap
     IMotionControllerLayoutMap
-} from "./webXRAbstractController";
+} from "./webXRAbstractMotionController";
 import { WebXRMotionControllerManager } from './webXRMotionControllerManager';
 import { WebXRMotionControllerManager } from './webXRMotionControllerManager';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
@@ -118,7 +118,7 @@ export class WebXRMicrosoftMixedRealityController extends WebXRAbstractMotionCon
                 if (buttonMap.valueMesh && buttonMap.pressedMesh && buttonMap.unpressedMesh) {
                 if (buttonMap.valueMesh && buttonMap.pressedMesh && buttonMap.unpressedMesh) {
                     const comp = this.getComponent(id);
                     const comp = this.getComponent(id);
                     if (comp) {
                     if (comp) {
-                        comp.onButtonStateChanged.add((component) => {
+                        comp.onButtonStateChangedObservable.add((component) => {
                             this._lerpTransform(buttonMap, component.value);
                             this._lerpTransform(buttonMap, component.value);
                         }, undefined, true);
                         }, undefined, true);
                     }
                     }
@@ -153,7 +153,7 @@ export class WebXRMicrosoftMixedRealityController extends WebXRAbstractMotionCon
 
 
                 if (axisMap.valueMesh && axisMap.minMesh && axisMap.maxMesh) {
                 if (axisMap.valueMesh && axisMap.minMesh && axisMap.maxMesh) {
                     if (comp) {
                     if (comp) {
-                        comp.onAxisValueChanged.add((axisValues) => {
+                        comp.onAxisValueChangedObservable.add((axisValues) => {
                             const value = axis === "x-axis" ? axisValues.x : axisValues.y;
                             const value = axis === "x-axis" ? axisValues.x : axisValues.y;
                             this._lerpTransform(axisMap, value, true);
                             this._lerpTransform(axisMap, value, true);
                         }, undefined, true);
                         }, undefined, true);

+ 1 - 1
src/XR/motionController/webXRMotionControllerManager.ts

@@ -1,6 +1,6 @@
 import {
 import {
     WebXRAbstractMotionController, IMotionControllerProfile,
     WebXRAbstractMotionController, IMotionControllerProfile,
-} from './webXRAbstractController';
+} from './webXRAbstractMotionController';
 import { WebXRGenericTriggerMotionController } from './webXRGenericMotionController';
 import { WebXRGenericTriggerMotionController } from './webXRGenericMotionController';
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
 import { Tools } from '../../Misc/tools';
 import { Tools } from '../../Misc/tools';

+ 2 - 2
src/XR/motionController/webXROculusTouchMotionController.ts

@@ -3,7 +3,7 @@ import {
     IMinimalMotionControllerObject,
     IMinimalMotionControllerObject,
     MotionControllerHandness,
     MotionControllerHandness,
     IMotionControllerLayoutMap
     IMotionControllerLayoutMap
-} from "./webXRAbstractController";
+} from "./webXRAbstractMotionController";
 import { WebXRMotionControllerManager } from './webXRMotionControllerManager';
 import { WebXRMotionControllerManager } from './webXRMotionControllerManager';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
@@ -53,7 +53,7 @@ export class WebXROculusTouchMotionController extends WebXRAbstractMotionControl
         this.getComponentIds().forEach((id) => {
         this.getComponentIds().forEach((id) => {
             const comp = id && this.getComponent(id);
             const comp = id && this.getComponent(id);
             if (comp) {
             if (comp) {
-                comp.onButtonStateChanged.add((component) => {
+                comp.onButtonStateChangedObservable.add((component) => {
 
 
                     if (!this.rootMesh || this.disableAnimation) { return; }
                     if (!this.rootMesh || this.disableAnimation) { return; }
 
 

+ 1 - 1
src/XR/motionController/webXRProfiledMotionController.ts

@@ -1,5 +1,5 @@
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
-import { WebXRAbstractMotionController, IMotionControllerProfile, IMotionControllerMeshMap } from './webXRAbstractController';
+import { WebXRAbstractMotionController, IMotionControllerProfile, IMotionControllerMeshMap } from './webXRAbstractMotionController';
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
 import { SceneLoader } from '../../Loading/sceneLoader';
 import { SceneLoader } from '../../Loading/sceneLoader';
 import { Mesh } from '../../Meshes/mesh';
 import { Mesh } from '../../Meshes/mesh';

+ 113 - 127
src/XR/webXRCamera.ts

@@ -8,41 +8,26 @@ import { Viewport } from '../Maths/math.viewport';
 
 
 /**
 /**
  * WebXR Camera which holds the views for the xrSession
  * WebXR Camera which holds the views for the xrSession
- * @see https://doc.babylonjs.com/how_to/webxr
+ * @see https://doc.babylonjs.com/how_to/webxr_camera
  */
  */
 export class WebXRCamera extends FreeCamera {
 export class WebXRCamera extends FreeCamera {
-
-    /**
-     * Should position compensation execute on first frame.
-     * This is used when copying the position from a native (non XR) camera
-     */
-    public compensateOnFirstFrame: boolean = true;
-
     private _firstFrame = false;
     private _firstFrame = false;
-    private _referencedPosition: Vector3 = new Vector3();
     private _referenceQuaternion: Quaternion = Quaternion.Identity();
     private _referenceQuaternion: Quaternion = Quaternion.Identity();
+    private _referencedPosition: Vector3 = new Vector3();
     private _xrInvPositionCache: Vector3 = new Vector3();
     private _xrInvPositionCache: Vector3 = new Vector3();
     private _xrInvQuaternionCache = Quaternion.Identity();
     private _xrInvQuaternionCache = Quaternion.Identity();
 
 
-    private _realWorldHeight: number = 0;
-
     /**
     /**
-     * Prevent the camera from calculating the real-world height
-     * If you are not using the user's height disable this for better performance
-     */
-    public disableRealWorldHeightCalculation: boolean = false;
-
-    /**
-     * Return the user's height, unrelated to the current ground.
+     * Should position compensation execute on first frame.
+     * This is used when copying the position from a native (non XR) camera
      */
      */
-    public get realWorldHeight(): number {
-        return this._realWorldHeight;
-    }
+    public compensateOnFirstFrame: boolean = true;
 
 
     /**
     /**
      * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
      * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
      * @param name the name of the camera
      * @param name the name of the camera
      * @param scene the scene to add the camera to
      * @param scene the scene to add the camera to
+     * @param _xrSessionManager a constructed xr session manager
      */
      */
     constructor(name: string, scene: Scene, private _xrSessionManager: WebXRSessionManager) {
     constructor(name: string, scene: Scene, private _xrSessionManager: WebXRSessionManager) {
         super(name, Vector3.Zero(), scene);
         super(name, Vector3.Zero(), scene);
@@ -73,24 +58,31 @@ export class WebXRCamera extends FreeCamera {
         }, undefined, true);
         }, undefined, true);
     }
     }
 
 
-    private _updateNumberOfRigCameras(viewCount = 1) {
-        while (this.rigCameras.length < viewCount) {
-            var newCamera = new TargetCamera("XR-RigCamera: " + this.rigCameras.length, Vector3.Zero(), this.getScene());
-            newCamera.minZ = 0.1;
-            newCamera.rotationQuaternion = new Quaternion();
-            newCamera.updateUpVectorFromRotation = true;
-            newCamera.isRigCamera = true;
-            newCamera.rigParent = this;
-            this.rigCameras.push(newCamera);
-        }
-        while (this.rigCameras.length > viewCount) {
-            var removedCamera = this.rigCameras.pop();
-            if (removedCamera) {
-                removedCamera.dispose();
-            }
+    /**
+     * Return the user's height, unrelated to the current ground.
+     * This will be the y position of this camera, when ground level is 0.
+     */
+    public get realWorldHeight(): number {
+        const basePose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(this._xrSessionManager.baseReferenceSpace);
+        if (basePose && basePose.transform) {
+            return basePose.transform.position.y;
+        } else {
+            return 0;
         }
         }
     }
     }
 
 
+    /** @hidden */
+    public _updateForDualEyeDebugging(/*pupilDistance = 0.01*/) {
+        // Create initial camera rigs
+        this._updateNumberOfRigCameras(2);
+        this.rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
+        // this.rigCameras[0].position.x = -pupilDistance / 2;
+        this.rigCameras[0].outputRenderTarget = null;
+        this.rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
+        // this.rigCameras[1].position.x = pupilDistance / 2;
+        this.rigCameras[1].outputRenderTarget = null;
+    }
+
     /**
     /**
      * Sets this camera's transformation based on a non-vr camera
      * Sets this camera's transformation based on a non-vr camera
      * @param otherCamera the non-vr camera to copy the transformation from
      * @param otherCamera the non-vr camera to copy the transformation from
@@ -111,97 +103,7 @@ export class WebXRCamera extends FreeCamera {
         }
         }
     }
     }
 
 
-    /** @hidden */
-    public _updateForDualEyeDebugging(/*pupilDistance = 0.01*/) {
-        // Create initial camera rigs
-        this._updateNumberOfRigCameras(2);
-        this.rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
-        // this.rigCameras[0].position.x = -pupilDistance / 2;
-        this.rigCameras[0].outputRenderTarget = null;
-        this.rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
-        // this.rigCameras[1].position.x = pupilDistance / 2;
-        this.rigCameras[1].outputRenderTarget = null;
-    }
-
-    private _updateReferenceSpace() {
-        // were position & rotation updated OUTSIDE of the xr update loop
-        if (!this.position.equals(this._referencedPosition) || !this.rotationQuaternion.equals(this._referenceQuaternion)) {
-            this.position.subtractToRef(this._referencedPosition, this._referencedPosition);
-            this._referenceQuaternion.conjugateInPlace();
-            this._referenceQuaternion.multiplyToRef(this.rotationQuaternion, this._referenceQuaternion);
-            this._updateReferenceSpaceOffset(this._referencedPosition, this._referenceQuaternion.normalize());
-        }
-    }
-
-    private _updateReferenceSpaceOffset(positionOffset: Vector3, rotationOffset?: Quaternion, ignoreHeight: boolean = false) {
-        if (!this._xrSessionManager.referenceSpace || !this._xrSessionManager.currentFrame) {
-            return;
-        }
-        // Compute the origin offset based on player position/orientation.
-        this._xrInvPositionCache.copyFrom(positionOffset);
-        if (rotationOffset) {
-            this._xrInvQuaternionCache.copyFrom(rotationOffset);
-        } else {
-            this._xrInvQuaternionCache.copyFromFloats(0, 0, 0, 1);
-        }
-
-        // right handed system
-        if (!this._scene.useRightHandedSystem) {
-            this._xrInvPositionCache.z *= -1;
-            this._xrInvQuaternionCache.z *= -1;
-            this._xrInvQuaternionCache.w *= -1;
-        }
-
-        this._xrInvPositionCache.negateInPlace();
-        this._xrInvQuaternionCache.conjugateInPlace();
-        // transform point according to rotation with pivot
-        this._xrInvPositionCache.rotateByQuaternionToRef(this._xrInvQuaternionCache, this._xrInvPositionCache);
-        if (ignoreHeight) {
-            this._xrInvPositionCache.y = 0;
-        }
-        const transform = new XRRigidTransform(
-            { ...this._xrInvPositionCache },
-            { ...this._xrInvQuaternionCache });
-        // Update offset reference to use a new originOffset with the teleported
-        // player position and orientation.
-        // This new offset needs to be applied to the base ref space.
-        const referenceSpace = this._xrSessionManager.referenceSpace.getOffsetReferenceSpace(transform);
-
-        const pose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(referenceSpace);
-
-        if (pose) {
-            const pos = new Vector3();
-            pos.copyFrom(<any>(pose.transform.position));
-            if (!this._scene.useRightHandedSystem) {
-                pos.z *= -1;
-            }
-            this.position.subtractToRef(pos, pos);
-            if (!this._scene.useRightHandedSystem) {
-                pos.z *= -1;
-            }
-            pos.negateInPlace();
-
-            const transform2 = new XRRigidTransform(
-                { ...pos });
-            // Update offset reference to use a new originOffset with the teleported
-            // player position and orientation.
-            // This new offset needs to be applied to the base ref space.
-            this._xrSessionManager.referenceSpace = referenceSpace.getOffsetReferenceSpace(transform2);
-        }
-    }
-
     private _updateFromXRSession() {
     private _updateFromXRSession() {
-
-        // user height
-        if (!this.disableRealWorldHeightCalculation) {
-            const basePose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(this._xrSessionManager.baseReferenceSpace);
-            if (basePose && basePose.transform) {
-                this._realWorldHeight = basePose.transform.position.y;
-            }
-        } else {
-            this._realWorldHeight = 0;
-        }
-
         const pose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(this._xrSessionManager.referenceSpace);
         const pose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(this._xrSessionManager.referenceSpace);
 
 
         if (!pose) {
         if (!pose) {
@@ -227,7 +129,6 @@ export class WebXRCamera extends FreeCamera {
                 // avoid using the head rotation on the first frame.
                 // avoid using the head rotation on the first frame.
                 this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);
                 this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);
                 // update the reference space so that the position will be correct
                 // update the reference space so that the position will be correct
-
             }
             }
             else {
             else {
                 this.rotationQuaternion.copyFrom(this._referenceQuaternion);
                 this.rotationQuaternion.copyFrom(this._referenceQuaternion);
@@ -286,4 +187,89 @@ export class WebXRCamera extends FreeCamera {
             currentRig.outputRenderTarget = this._xrSessionManager.getRenderTargetTextureForEye(view.eye);
             currentRig.outputRenderTarget = this._xrSessionManager.getRenderTargetTextureForEye(view.eye);
         });
         });
     }
     }
+
+    private _updateNumberOfRigCameras(viewCount = 1) {
+        while (this.rigCameras.length < viewCount) {
+            var newCamera = new TargetCamera("XR-RigCamera: " + this.rigCameras.length, Vector3.Zero(), this.getScene());
+            newCamera.minZ = 0.1;
+            newCamera.rotationQuaternion = new Quaternion();
+            newCamera.updateUpVectorFromRotation = true;
+            newCamera.isRigCamera = true;
+            newCamera.rigParent = this;
+            this.rigCameras.push(newCamera);
+        }
+        while (this.rigCameras.length > viewCount) {
+            var removedCamera = this.rigCameras.pop();
+            if (removedCamera) {
+                removedCamera.dispose();
+            }
+        }
+    }
+
+    private _updateReferenceSpace() {
+        // were position & rotation updated OUTSIDE of the xr update loop
+        if (!this.position.equals(this._referencedPosition) || !this.rotationQuaternion.equals(this._referenceQuaternion)) {
+            this.position.subtractToRef(this._referencedPosition, this._referencedPosition);
+            this._referenceQuaternion.conjugateInPlace();
+            this._referenceQuaternion.multiplyToRef(this.rotationQuaternion, this._referenceQuaternion);
+            this._updateReferenceSpaceOffset(this._referencedPosition, this._referenceQuaternion.normalize());
+        }
+    }
+
+    private _updateReferenceSpaceOffset(positionOffset: Vector3, rotationOffset?: Quaternion, ignoreHeight: boolean = false) {
+        if (!this._xrSessionManager.referenceSpace || !this._xrSessionManager.currentFrame) {
+            return;
+        }
+        // Compute the origin offset based on player position/orientation.
+        this._xrInvPositionCache.copyFrom(positionOffset);
+        if (rotationOffset) {
+            this._xrInvQuaternionCache.copyFrom(rotationOffset);
+        } else {
+            this._xrInvQuaternionCache.copyFromFloats(0, 0, 0, 1);
+        }
+
+        // right handed system
+        if (!this._scene.useRightHandedSystem) {
+            this._xrInvPositionCache.z *= -1;
+            this._xrInvQuaternionCache.z *= -1;
+            this._xrInvQuaternionCache.w *= -1;
+        }
+
+        this._xrInvPositionCache.negateInPlace();
+        this._xrInvQuaternionCache.conjugateInPlace();
+        // transform point according to rotation with pivot
+        this._xrInvPositionCache.rotateByQuaternionToRef(this._xrInvQuaternionCache, this._xrInvPositionCache);
+        if (ignoreHeight) {
+            this._xrInvPositionCache.y = 0;
+        }
+        const transform = new XRRigidTransform(
+            { ...this._xrInvPositionCache },
+            { ...this._xrInvQuaternionCache });
+        // Update offset reference to use a new originOffset with the teleported
+        // player position and orientation.
+        // This new offset needs to be applied to the base ref space.
+        const referenceSpace = this._xrSessionManager.referenceSpace.getOffsetReferenceSpace(transform);
+
+        const pose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(referenceSpace);
+
+        if (pose) {
+            const pos = new Vector3();
+            pos.copyFrom(<any>(pose.transform.position));
+            if (!this._scene.useRightHandedSystem) {
+                pos.z *= -1;
+            }
+            this.position.subtractToRef(pos, pos);
+            if (!this._scene.useRightHandedSystem) {
+                pos.z *= -1;
+            }
+            pos.negateInPlace();
+
+            const transform2 = new XRRigidTransform(
+                { ...pos });
+            // Update offset reference to use a new originOffset with the teleported
+            // player position and orientation.
+            // This new offset needs to be applied to the base ref space.
+            this._xrSessionManager.referenceSpace = referenceSpace.getOffsetReferenceSpace(transform2);
+        }
+    }
 }
 }

+ 7 - 7
src/XR/webXRInput.ts

@@ -1,7 +1,7 @@
 import { Nullable } from "../types";
 import { Nullable } from "../types";
 import { Observer, Observable } from "../Misc/observable";
 import { Observer, Observable } from "../Misc/observable";
 import { IDisposable } from "../scene";
 import { IDisposable } from "../scene";
-import { WebXRController } from './webXRController';
+import { WebXRInputSource } from './webXRInputSource';
 import { WebXRSessionManager } from './webXRSessionManager';
 import { WebXRSessionManager } from './webXRSessionManager';
 import { WebXRCamera } from './webXRCamera';
 import { WebXRCamera } from './webXRCamera';
 import { WebXRMotionControllerManager } from './motionController/webXRMotionControllerManager';
 import { WebXRMotionControllerManager } from './motionController/webXRMotionControllerManager';
@@ -46,18 +46,18 @@ export class WebXRInput implements IDisposable {
     /**
     /**
      * XR controllers being tracked
      * XR controllers being tracked
      */
      */
-    public controllers: Array<WebXRController> = [];
+    public controllers: Array<WebXRInputSource> = [];
     private _frameObserver: Nullable<Observer<any>>;
     private _frameObserver: Nullable<Observer<any>>;
     private _sessionEndedObserver: Nullable<Observer<any>>;
     private _sessionEndedObserver: Nullable<Observer<any>>;
     private _sessionInitObserver: Nullable<Observer<any>>;
     private _sessionInitObserver: Nullable<Observer<any>>;
     /**
     /**
      * Event when a controller has been connected/added
      * Event when a controller has been connected/added
      */
      */
-    public onControllerAddedObservable = new Observable<WebXRController>();
+    public onControllerAddedObservable = new Observable<WebXRInputSource>();
     /**
     /**
      * Event when a controller has been removed/disconnected
      * Event when a controller has been removed/disconnected
      */
      */
-    public onControllerRemovedObservable = new Observable<WebXRController>();
+    public onControllerRemovedObservable = new Observable<WebXRInputSource>();
 
 
     /**
     /**
      * Initializes the WebXRInput
      * Initializes the WebXRInput
@@ -114,7 +114,7 @@ export class WebXRInput implements IDisposable {
         let sources = this.controllers.map((c) => { return c.inputSource; });
         let sources = this.controllers.map((c) => { return c.inputSource; });
         for (let input of addInputs) {
         for (let input of addInputs) {
             if (sources.indexOf(input) === -1) {
             if (sources.indexOf(input) === -1) {
-                let controller = new WebXRController(this.xrSessionManager.scene, input, {
+                let controller = new WebXRInputSource(this.xrSessionManager.scene, input, {
                     forceControllerProfile: this.options.forceInputProfile,
                     forceControllerProfile: this.options.forceInputProfile,
                     doNotLoadControllerMesh: this.options.doNotLoadControllerMeshes,
                     doNotLoadControllerMesh: this.options.doNotLoadControllerMeshes,
                     disableMotionControllerAnimation: this.options.disableControllerAnimation
                     disableMotionControllerAnimation: this.options.disableControllerAnimation
@@ -125,8 +125,8 @@ export class WebXRInput implements IDisposable {
         }
         }
 
 
         // Remove and dispose of controllers to be disposed
         // Remove and dispose of controllers to be disposed
-        let keepControllers: Array<WebXRController> = [];
-        let removedControllers: Array<WebXRController> = [];
+        let keepControllers: Array<WebXRInputSource> = [];
+        let removedControllers: Array<WebXRInputSource> = [];
         this.controllers.forEach((c) => {
         this.controllers.forEach((c) => {
             if (removeInputs.indexOf(c.inputSource) === -1) {
             if (removeInputs.indexOf(c.inputSource) === -1) {
                 keepControllers.push(c);
                 keepControllers.push(c);

+ 9 - 7
src/XR/webXRController.ts

@@ -3,7 +3,7 @@ import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Quaternion, Vector3 } from '../Maths/math.vector';
 import { Quaternion, Vector3 } from '../Maths/math.vector';
 import { Ray } from '../Culling/ray';
 import { Ray } from '../Culling/ray';
 import { Scene } from '../scene';
 import { Scene } from '../scene';
-import { WebXRAbstractMotionController } from './motionController/webXRAbstractController';
+import { WebXRAbstractMotionController } from './motionController/webXRAbstractMotionController';
 import { WebXRMotionControllerManager } from './motionController/webXRMotionControllerManager';
 import { WebXRMotionControllerManager } from './motionController/webXRMotionControllerManager';
 
 
 let idCount = 0;
 let idCount = 0;
@@ -33,7 +33,7 @@ export interface IWebXRControllerOptions {
 /**
 /**
  * Represents an XR controller
  * Represents an XR controller
  */
  */
-export class WebXRController {
+export class WebXRInputSource {
     /**
     /**
      * Represents the part of the controller that is held. This may not exist if the controller is the head mounted display itself, if thats the case only the pointer from the head will be availible
      * Represents the part of the controller that is held. This may not exist if the controller is the head mounted display itself, if thats the case only the pointer from the head will be availible
      */
      */
@@ -66,7 +66,7 @@ export class WebXRController {
      * The object provided as event data is this controller, after associated assets were disposed.
      * The object provided as event data is this controller, after associated assets were disposed.
      * uniqueId is still available.
      * uniqueId is still available.
      */
      */
-    public onDisposeObservable = new Observable<WebXRController>();
+    public onDisposeObservable = new Observable<WebXRInputSource>();
 
 
     private _tmpQuaternion = new Quaternion();
     private _tmpQuaternion = new Quaternion();
     private _tmpVector = new Vector3();
     private _tmpVector = new Vector3();
@@ -159,15 +159,17 @@ export class WebXRController {
     }
     }
 
 
     /**
     /**
-     * Gets a world space ray coming from the controller
+     * Gets a world space ray coming from the pointer or grip
      * @param result the resulting ray
      * @param result the resulting ray
+     * @param gripIfAvailable use the grip mesh instead of the pointer, if available
      */
      */
-    public getWorldPointerRayToRef(result: Ray) {
-        let worldMatrix = this.pointer.computeWorldMatrix();
+    public getWorldPointerRayToRef(result: Ray, gripIfAvailable: boolean = false) {
+        const object = gripIfAvailable && this.grip ? this.grip : this.pointer;
+        let worldMatrix = object.computeWorldMatrix();
         worldMatrix.decompose(undefined, this._tmpQuaternion, undefined);
         worldMatrix.decompose(undefined, this._tmpQuaternion, undefined);
         this._tmpVector.set(0, 0, 1);
         this._tmpVector.set(0, 0, 1);
         this._tmpVector.rotateByQuaternionToRef(this._tmpQuaternion, this._tmpVector);
         this._tmpVector.rotateByQuaternionToRef(this._tmpQuaternion, this._tmpVector);
-        result.origin.copyFrom(this.pointer.absolutePosition);
+        result.origin.copyFrom(object.absolutePosition);
         result.direction.copyFrom(this._tmpVector);
         result.direction.copyFrom(this._tmpVector);
         result.length = 1000;
         result.length = 1000;
     }
     }