Просмотр исходного кода

Merge pull request #7500 from BabylonJS/master

Nightly
David Catuhe 5 лет назад
Родитель
Сommit
7bfd854b64
41 измененных файлов с 826 добавлено и 506 удалено
  1. 65 23
      dist/preview release/babylon.d.ts
  2. 2 2
      dist/preview release/babylon.js
  3. 152 64
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 130 51
      dist/preview release/babylon.module.d.ts
  6. 65 23
      dist/preview release/documentation.d.ts
  7. 25 32
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  8. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.js.map
  9. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  10. 25 32
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  11. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  12. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  13. 25 32
      dist/preview release/loaders/babylon.glTFFileLoader.js
  14. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  15. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  16. 25 32
      dist/preview release/loaders/babylonjs.loaders.js
  17. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  18. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  19. 2 2
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  20. 2 11
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  21. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  22. 1 1
      dist/preview release/packagesSizeBaseLine.json
  23. 130 51
      dist/preview release/viewer/babylon.module.d.ts
  24. 18 18
      dist/preview release/viewer/babylon.viewer.js
  25. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  26. 1 1
      dist/preview release/what's new.md
  27. 25 33
      loaders/src/glTF/glTFFileLoader.ts
  28. 0 12
      nodeEditor/src/diagram/display/inputDisplayManager.ts
  29. 4 6
      nodeEditor/src/diagram/graphCanvas.scss
  30. 1 0
      nodeEditor/src/diagram/properties/gradientNodePropertyComponent.tsx
  31. 19 7
      src/Cameras/XR/features/WebXRAbstractFeature.ts
  32. 6 8
      src/Cameras/XR/features/WebXRAnchorSystem.ts
  33. 7 5
      src/Cameras/XR/features/WebXRBackgroundRemover.ts
  34. 3 5
      src/Cameras/XR/features/WebXRControllerPointerSelection.ts
  35. 3 5
      src/Cameras/XR/features/WebXRControllerTeleportation.ts
  36. 3 8
      src/Cameras/XR/features/WebXRHitTestLegacy.ts
  37. 3 5
      src/Cameras/XR/features/WebXRPlaneDetector.ts
  38. 4 9
      src/Cameras/XR/webXRCamera.ts
  39. 6 1
      src/Cameras/XR/webXRExperienceHelper.ts
  40. 53 7
      src/Cameras/XR/webXRFeaturesManager.ts
  41. 7 6
      src/Cameras/XR/webXRSessionManager.ts

+ 65 - 23
dist/preview release/babylon.d.ts

@@ -14476,6 +14476,11 @@ declare module BABYLON {
          * @returns the world matrix
          */
         computeWorldMatrix(force?: boolean): Matrix;
+        /**
+         * Resets this nodeTransform's local matrix to Matrix.Identity().
+         * @param independentOfChildren indicates if all child nodeTransform's world-space transform should be preserved.
+         */
+        resetLocalMatrix(independentOfChildren?: boolean): void;
         protected _afterComputeWorldMatrix(): void;
         /**
         * If you'd like to be called back after the mesh position, rotation or scaling has been updated.
@@ -24720,9 +24725,10 @@ declare module BABYLON {
          * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
          * Note that, under the hood, this method sets a new VertexBuffer each call.
          * @see http://doc.babylonjs.com/resources/baking_transformations
+         * @param bakeIndependenlyOfChildren indicates whether to preserve all child nodes' World Matrix during baking
          * @returns the current mesh
          */
-        bakeCurrentTransformIntoVertices(): Mesh;
+        bakeCurrentTransformIntoVertices(bakeIndependenlyOfChildren?: boolean): Mesh;
         /** @hidden */
         get _positions(): Nullable<Vector3[]>;
         /** @hidden */
@@ -42545,10 +42551,10 @@ declare module BABYLON {
         initializeSessionAsync(xrSessionMode?: XRSessionMode, xrSessionInit?: XRSessionInit): Promise<XRSession>;
         /**
          * Sets the reference space on the xr session
-         * @param referenceSpace space to set
+         * @param referenceSpaceType space to set
          * @returns a promise that will resolve once the reference space has been set
          */
-        setReferenceSpaceAsync(referenceSpace?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
+        setReferenceSpaceTypeAsync(referenceSpaceType?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
         /**
          * Resets the reference space to the one started the session
          */
@@ -42614,10 +42620,6 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
-        /**
-         * Is the camera in debug mode. Used when using an emulator
-         */
-        debugMode: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -42635,7 +42637,7 @@ declare module BABYLON {
          * @param otherCamera the non-vr camera to copy the transformation from
          * @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 _updateReferenceSpace;
@@ -42653,12 +42655,17 @@ declare module BABYLON {
          */
         attached: boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * Attach the feature to the session
          * Will usually be called by the features manager
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful.
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * Detach the feature from the session
          * Will usually be called by the features manager
@@ -42668,6 +42675,35 @@ declare module BABYLON {
         detach(): boolean;
     }
     /**
+     * A list of the currently available features without referencing them
+     */
+    export class WebXRFeatureName {
+        /**
+         * The name of the hit test feature
+         */
+        static HIT_TEST: string;
+        /**
+         * The name of the anchor system feature
+         */
+        static ANCHOR_SYSTEM: string;
+        /**
+         * The name of the background remover feature
+         */
+        static BACKGROUND_REMOVER: string;
+        /**
+         * The name of the pointer selection feature
+         */
+        static POINTER_SELECTION: string;
+        /**
+         * The name of the teleportation feature
+         */
+        static TELEPORTATION: string;
+        /**
+         * The name of the plane detection feature
+         */
+        static PLANE_DETECTION: string;
+    }
+    /**
      * Defining the constructor of a feature. Used to register the modules.
      */
     export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => IWebXRFeature);
@@ -43957,11 +43993,16 @@ declare module BABYLON {
          */
         get attached(): boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * attach this feature
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful, false is failed or already attached
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * detach this feature.
          *
@@ -43977,7 +44018,7 @@ declare module BABYLON {
          * This function will not execute after the feature is detached.
          * @param _xrFrame the current frame
          */
-        protected _onXRFrame(_xrFrame: XRFrame): void;
+        protected abstract _onXRFrame(_xrFrame: XRFrame): void;
         /**
          * This is used to register callbacks that will automatically be removed when detach is called.
          * @param observable the observable to which the observer will be attached
@@ -44026,12 +44067,12 @@ declare module BABYLON {
     /**
      * A module that will enable pointer selection for motion controllers of XR Input Sources
      */
-    export class WebXRControllerPointerSelection extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         private readonly _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -44346,12 +44387,12 @@ declare module BABYLON {
      * When enabled and attached, the feature will allow a user to move aroundand rotate in the scene using
      * the input of the attached controllers.
      */
-    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -44960,7 +45001,7 @@ declare module BABYLON {
      * Hit test (or raycasting) is used to interact with the real world.
      * For further information read here - https://github.com/immersive-web/hit-test
      */
-    export class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRHitTestLegacy extends WebXRAbstractFeature {
         /**
          * options to use when constructing this feature
          */
@@ -44968,7 +45009,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45074,12 +45115,12 @@ declare module BABYLON {
      * The plane detector is used to detect planes in the real world when in AR
      * For more information see https://github.com/immersive-web/real-world-geometry/
      */
-    export class WebXRPlaneDetector extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRPlaneDetector extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45163,12 +45204,12 @@ declare module BABYLON {
      * will use the frame to create an anchor and not the session or a detected plane
      * For further information see https://github.com/immersive-web/anchors/
      */
-    export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRAnchorSystem extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45277,7 +45318,7 @@ declare module BABYLON {
     /**
      * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.
      */
-    export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRBackgroundRemover extends WebXRAbstractFeature {
         /**
          * read-only options to be used in this module
          */
@@ -45285,7 +45326,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45325,6 +45366,7 @@ declare module BABYLON {
          * Dispose this feature and all of the resources attached
          */
         dispose(): void;
+        protected _onXRFrame(_xrFrame: XRFrame): void;
     }
 }
 declare module BABYLON {

Разница между файлами не показана из-за своего большого размера
+ 2 - 2
dist/preview release/babylon.js


Разница между файлами не показана из-за своего большого размера
+ 152 - 64
dist/preview release/babylon.max.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 130 - 51
dist/preview release/babylon.module.d.ts

@@ -14787,6 +14787,11 @@ declare module "babylonjs/Meshes/transformNode" {
          * @returns the world matrix
          */
         computeWorldMatrix(force?: boolean): Matrix;
+        /**
+         * Resets this nodeTransform's local matrix to Matrix.Identity().
+         * @param independentOfChildren indicates if all child nodeTransform's world-space transform should be preserved.
+         */
+        resetLocalMatrix(independentOfChildren?: boolean): void;
         protected _afterComputeWorldMatrix(): void;
         /**
         * If you'd like to be called back after the mesh position, rotation or scaling has been updated.
@@ -25456,9 +25461,10 @@ declare module "babylonjs/Meshes/mesh" {
          * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
          * Note that, under the hood, this method sets a new VertexBuffer each call.
          * @see http://doc.babylonjs.com/resources/baking_transformations
+         * @param bakeIndependenlyOfChildren indicates whether to preserve all child nodes' World Matrix during baking
          * @returns the current mesh
          */
-        bakeCurrentTransformIntoVertices(): Mesh;
+        bakeCurrentTransformIntoVertices(bakeIndependenlyOfChildren?: boolean): Mesh;
         /** @hidden */
         get _positions(): Nullable<Vector3[]>;
         /** @hidden */
@@ -44027,10 +44033,10 @@ declare module "babylonjs/Cameras/XR/webXRSessionManager" {
         initializeSessionAsync(xrSessionMode?: XRSessionMode, xrSessionInit?: XRSessionInit): Promise<XRSession>;
         /**
          * Sets the reference space on the xr session
-         * @param referenceSpace space to set
+         * @param referenceSpaceType space to set
          * @returns a promise that will resolve once the reference space has been set
          */
-        setReferenceSpaceAsync(referenceSpace?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
+        setReferenceSpaceTypeAsync(referenceSpaceType?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
         /**
          * Resets the reference space to the one started the session
          */
@@ -44100,10 +44106,6 @@ declare module "babylonjs/Cameras/XR/webXRCamera" {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
-        /**
-         * Is the camera in debug mode. Used when using an emulator
-         */
-        debugMode: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -44121,7 +44123,7 @@ declare module "babylonjs/Cameras/XR/webXRCamera" {
          * @param otherCamera the non-vr camera to copy the transformation from
          * @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 _updateReferenceSpace;
@@ -44141,12 +44143,17 @@ declare module "babylonjs/Cameras/XR/webXRFeaturesManager" {
          */
         attached: boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * Attach the feature to the session
          * Will usually be called by the features manager
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful.
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * Detach the feature from the session
          * Will usually be called by the features manager
@@ -44156,6 +44163,35 @@ declare module "babylonjs/Cameras/XR/webXRFeaturesManager" {
         detach(): boolean;
     }
     /**
+     * A list of the currently available features without referencing them
+     */
+    export class WebXRFeatureName {
+        /**
+         * The name of the hit test feature
+         */
+        static HIT_TEST: string;
+        /**
+         * The name of the anchor system feature
+         */
+        static ANCHOR_SYSTEM: string;
+        /**
+         * The name of the background remover feature
+         */
+        static BACKGROUND_REMOVER: string;
+        /**
+         * The name of the pointer selection feature
+         */
+        static POINTER_SELECTION: string;
+        /**
+         * The name of the teleportation feature
+         */
+        static TELEPORTATION: string;
+        /**
+         * The name of the plane detection feature
+         */
+        static PLANE_DETECTION: string;
+    }
+    /**
      * Defining the constructor of a feature. Used to register the modules.
      */
     export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => IWebXRFeature);
@@ -45488,11 +45524,16 @@ declare module "babylonjs/Cameras/XR/features/WebXRAbstractFeature" {
          */
         get attached(): boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * attach this feature
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful, false is failed or already attached
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * detach this feature.
          *
@@ -45508,7 +45549,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRAbstractFeature" {
          * This function will not execute after the feature is detached.
          * @param _xrFrame the current frame
          */
-        protected _onXRFrame(_xrFrame: XRFrame): void;
+        protected abstract _onXRFrame(_xrFrame: XRFrame): void;
         /**
          * This is used to register callbacks that will automatically be removed when detach is called.
          * @param observable the observable to which the observer will be attached
@@ -45518,7 +45559,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRAbstractFeature" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRControllerPointerSelection" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { WebXRInput } from "babylonjs/Cameras/XR/webXRInput";
     import { WebXRController } from "babylonjs/Cameras/XR/webXRController";
@@ -45564,12 +45604,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRControllerPointerSelection" {
     /**
      * A module that will enable pointer selection for motion controllers of XR Input Sources
      */
-    export class WebXRControllerPointerSelection extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         private readonly _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45900,12 +45940,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRControllerTeleportation" {
      * When enabled and attached, the feature will allow a user to move aroundand rotate in the scene using
      * the input of the attached controllers.
      */
-    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46521,7 +46561,6 @@ declare module "babylonjs/Cameras/VR/index" {
     export * from "babylonjs/Cameras/VR/webVRCamera";
 }
 declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { Observable } from "babylonjs/Misc/observable";
     import { Matrix } from "babylonjs/Maths/math.vector";
@@ -46558,7 +46597,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
      * Hit test (or raycasting) is used to interact with the real world.
      * For further information read here - https://github.com/immersive-web/hit-test
      */
-    export class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRHitTestLegacy extends WebXRAbstractFeature {
         /**
          * options to use when constructing this feature
          */
@@ -46566,7 +46605,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46636,7 +46675,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { TransformNode } from "babylonjs/Meshes/transformNode";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { Observable } from "babylonjs/Misc/observable";
@@ -46678,12 +46716,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
      * The plane detector is used to detect planes in the real world when in AR
      * For more information see https://github.com/immersive-web/real-world-geometry/
      */
-    export class WebXRPlaneDetector extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRPlaneDetector extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46726,7 +46764,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRAnchorSystem" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { Observable } from "babylonjs/Misc/observable";
     import { Matrix } from "babylonjs/Maths/math.vector";
@@ -46775,12 +46812,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRAnchorSystem" {
      * will use the frame to create an anchor and not the session or a detected plane
      * For further information see https://github.com/immersive-web/anchors/
      */
-    export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRAnchorSystem extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46859,7 +46896,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRAnchorSystem" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Observable } from "babylonjs/Misc/observable";
@@ -46894,7 +46930,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
     /**
      * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.
      */
-    export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRBackgroundRemover extends WebXRAbstractFeature {
         /**
          * read-only options to be used in this module
          */
@@ -46902,7 +46938,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46942,6 +46978,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
          * Dispose this feature and all of the resources attached
          */
         dispose(): void;
+        protected _onXRFrame(_xrFrame: XRFrame): void;
     }
 }
 declare module "babylonjs/Cameras/XR/features/index" {
@@ -86937,6 +86974,11 @@ declare module BABYLON {
          * @returns the world matrix
          */
         computeWorldMatrix(force?: boolean): Matrix;
+        /**
+         * Resets this nodeTransform's local matrix to Matrix.Identity().
+         * @param independentOfChildren indicates if all child nodeTransform's world-space transform should be preserved.
+         */
+        resetLocalMatrix(independentOfChildren?: boolean): void;
         protected _afterComputeWorldMatrix(): void;
         /**
         * If you'd like to be called back after the mesh position, rotation or scaling has been updated.
@@ -97181,9 +97223,10 @@ declare module BABYLON {
          * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
          * Note that, under the hood, this method sets a new VertexBuffer each call.
          * @see http://doc.babylonjs.com/resources/baking_transformations
+         * @param bakeIndependenlyOfChildren indicates whether to preserve all child nodes' World Matrix during baking
          * @returns the current mesh
          */
-        bakeCurrentTransformIntoVertices(): Mesh;
+        bakeCurrentTransformIntoVertices(bakeIndependenlyOfChildren?: boolean): Mesh;
         /** @hidden */
         get _positions(): Nullable<Vector3[]>;
         /** @hidden */
@@ -115006,10 +115049,10 @@ declare module BABYLON {
         initializeSessionAsync(xrSessionMode?: XRSessionMode, xrSessionInit?: XRSessionInit): Promise<XRSession>;
         /**
          * Sets the reference space on the xr session
-         * @param referenceSpace space to set
+         * @param referenceSpaceType space to set
          * @returns a promise that will resolve once the reference space has been set
          */
-        setReferenceSpaceAsync(referenceSpace?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
+        setReferenceSpaceTypeAsync(referenceSpaceType?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
         /**
          * Resets the reference space to the one started the session
          */
@@ -115075,10 +115118,6 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
-        /**
-         * Is the camera in debug mode. Used when using an emulator
-         */
-        debugMode: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -115096,7 +115135,7 @@ declare module BABYLON {
          * @param otherCamera the non-vr camera to copy the transformation from
          * @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 _updateReferenceSpace;
@@ -115114,12 +115153,17 @@ declare module BABYLON {
          */
         attached: boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * Attach the feature to the session
          * Will usually be called by the features manager
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful.
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * Detach the feature from the session
          * Will usually be called by the features manager
@@ -115129,6 +115173,35 @@ declare module BABYLON {
         detach(): boolean;
     }
     /**
+     * A list of the currently available features without referencing them
+     */
+    export class WebXRFeatureName {
+        /**
+         * The name of the hit test feature
+         */
+        static HIT_TEST: string;
+        /**
+         * The name of the anchor system feature
+         */
+        static ANCHOR_SYSTEM: string;
+        /**
+         * The name of the background remover feature
+         */
+        static BACKGROUND_REMOVER: string;
+        /**
+         * The name of the pointer selection feature
+         */
+        static POINTER_SELECTION: string;
+        /**
+         * The name of the teleportation feature
+         */
+        static TELEPORTATION: string;
+        /**
+         * The name of the plane detection feature
+         */
+        static PLANE_DETECTION: string;
+    }
+    /**
      * Defining the constructor of a feature. Used to register the modules.
      */
     export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => IWebXRFeature);
@@ -116418,11 +116491,16 @@ declare module BABYLON {
          */
         get attached(): boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * attach this feature
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful, false is failed or already attached
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * detach this feature.
          *
@@ -116438,7 +116516,7 @@ declare module BABYLON {
          * This function will not execute after the feature is detached.
          * @param _xrFrame the current frame
          */
-        protected _onXRFrame(_xrFrame: XRFrame): void;
+        protected abstract _onXRFrame(_xrFrame: XRFrame): void;
         /**
          * This is used to register callbacks that will automatically be removed when detach is called.
          * @param observable the observable to which the observer will be attached
@@ -116487,12 +116565,12 @@ declare module BABYLON {
     /**
      * A module that will enable pointer selection for motion controllers of XR Input Sources
      */
-    export class WebXRControllerPointerSelection extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         private readonly _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -116807,12 +116885,12 @@ declare module BABYLON {
      * When enabled and attached, the feature will allow a user to move aroundand rotate in the scene using
      * the input of the attached controllers.
      */
-    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117421,7 +117499,7 @@ declare module BABYLON {
      * Hit test (or raycasting) is used to interact with the real world.
      * For further information read here - https://github.com/immersive-web/hit-test
      */
-    export class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRHitTestLegacy extends WebXRAbstractFeature {
         /**
          * options to use when constructing this feature
          */
@@ -117429,7 +117507,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117535,12 +117613,12 @@ declare module BABYLON {
      * The plane detector is used to detect planes in the real world when in AR
      * For more information see https://github.com/immersive-web/real-world-geometry/
      */
-    export class WebXRPlaneDetector extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRPlaneDetector extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117624,12 +117702,12 @@ declare module BABYLON {
      * will use the frame to create an anchor and not the session or a detected plane
      * For further information see https://github.com/immersive-web/anchors/
      */
-    export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRAnchorSystem extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117738,7 +117816,7 @@ declare module BABYLON {
     /**
      * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.
      */
-    export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRBackgroundRemover extends WebXRAbstractFeature {
         /**
          * read-only options to be used in this module
          */
@@ -117746,7 +117824,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117786,6 +117864,7 @@ declare module BABYLON {
          * Dispose this feature and all of the resources attached
          */
         dispose(): void;
+        protected _onXRFrame(_xrFrame: XRFrame): void;
     }
 }
 declare module BABYLON {

+ 65 - 23
dist/preview release/documentation.d.ts

@@ -14476,6 +14476,11 @@ declare module BABYLON {
          * @returns the world matrix
          */
         computeWorldMatrix(force?: boolean): Matrix;
+        /**
+         * Resets this nodeTransform's local matrix to Matrix.Identity().
+         * @param independentOfChildren indicates if all child nodeTransform's world-space transform should be preserved.
+         */
+        resetLocalMatrix(independentOfChildren?: boolean): void;
         protected _afterComputeWorldMatrix(): void;
         /**
         * If you'd like to be called back after the mesh position, rotation or scaling has been updated.
@@ -24720,9 +24725,10 @@ declare module BABYLON {
          * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
          * Note that, under the hood, this method sets a new VertexBuffer each call.
          * @see http://doc.babylonjs.com/resources/baking_transformations
+         * @param bakeIndependenlyOfChildren indicates whether to preserve all child nodes' World Matrix during baking
          * @returns the current mesh
          */
-        bakeCurrentTransformIntoVertices(): Mesh;
+        bakeCurrentTransformIntoVertices(bakeIndependenlyOfChildren?: boolean): Mesh;
         /** @hidden */
         get _positions(): Nullable<Vector3[]>;
         /** @hidden */
@@ -42545,10 +42551,10 @@ declare module BABYLON {
         initializeSessionAsync(xrSessionMode?: XRSessionMode, xrSessionInit?: XRSessionInit): Promise<XRSession>;
         /**
          * Sets the reference space on the xr session
-         * @param referenceSpace space to set
+         * @param referenceSpaceType space to set
          * @returns a promise that will resolve once the reference space has been set
          */
-        setReferenceSpaceAsync(referenceSpace?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
+        setReferenceSpaceTypeAsync(referenceSpaceType?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
         /**
          * Resets the reference space to the one started the session
          */
@@ -42614,10 +42620,6 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
-        /**
-         * Is the camera in debug mode. Used when using an emulator
-         */
-        debugMode: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -42635,7 +42637,7 @@ declare module BABYLON {
          * @param otherCamera the non-vr camera to copy the transformation from
          * @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 _updateReferenceSpace;
@@ -42653,12 +42655,17 @@ declare module BABYLON {
          */
         attached: boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * Attach the feature to the session
          * Will usually be called by the features manager
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful.
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * Detach the feature from the session
          * Will usually be called by the features manager
@@ -42668,6 +42675,35 @@ declare module BABYLON {
         detach(): boolean;
     }
     /**
+     * A list of the currently available features without referencing them
+     */
+    export class WebXRFeatureName {
+        /**
+         * The name of the hit test feature
+         */
+        static HIT_TEST: string;
+        /**
+         * The name of the anchor system feature
+         */
+        static ANCHOR_SYSTEM: string;
+        /**
+         * The name of the background remover feature
+         */
+        static BACKGROUND_REMOVER: string;
+        /**
+         * The name of the pointer selection feature
+         */
+        static POINTER_SELECTION: string;
+        /**
+         * The name of the teleportation feature
+         */
+        static TELEPORTATION: string;
+        /**
+         * The name of the plane detection feature
+         */
+        static PLANE_DETECTION: string;
+    }
+    /**
      * Defining the constructor of a feature. Used to register the modules.
      */
     export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => IWebXRFeature);
@@ -43957,11 +43993,16 @@ declare module BABYLON {
          */
         get attached(): boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * attach this feature
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful, false is failed or already attached
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * detach this feature.
          *
@@ -43977,7 +44018,7 @@ declare module BABYLON {
          * This function will not execute after the feature is detached.
          * @param _xrFrame the current frame
          */
-        protected _onXRFrame(_xrFrame: XRFrame): void;
+        protected abstract _onXRFrame(_xrFrame: XRFrame): void;
         /**
          * This is used to register callbacks that will automatically be removed when detach is called.
          * @param observable the observable to which the observer will be attached
@@ -44026,12 +44067,12 @@ declare module BABYLON {
     /**
      * A module that will enable pointer selection for motion controllers of XR Input Sources
      */
-    export class WebXRControllerPointerSelection extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         private readonly _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -44346,12 +44387,12 @@ declare module BABYLON {
      * When enabled and attached, the feature will allow a user to move aroundand rotate in the scene using
      * the input of the attached controllers.
      */
-    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -44960,7 +45001,7 @@ declare module BABYLON {
      * Hit test (or raycasting) is used to interact with the real world.
      * For further information read here - https://github.com/immersive-web/hit-test
      */
-    export class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRHitTestLegacy extends WebXRAbstractFeature {
         /**
          * options to use when constructing this feature
          */
@@ -44968,7 +45009,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45074,12 +45115,12 @@ declare module BABYLON {
      * The plane detector is used to detect planes in the real world when in AR
      * For more information see https://github.com/immersive-web/real-world-geometry/
      */
-    export class WebXRPlaneDetector extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRPlaneDetector extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45163,12 +45204,12 @@ declare module BABYLON {
      * will use the frame to create an anchor and not the session or a detected plane
      * For further information see https://github.com/immersive-web/anchors/
      */
-    export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRAnchorSystem extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45277,7 +45318,7 @@ declare module BABYLON {
     /**
      * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.
      */
-    export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRBackgroundRemover extends WebXRAbstractFeature {
         /**
          * read-only options to be used in this module
          */
@@ -45285,7 +45326,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45325,6 +45366,7 @@ declare module BABYLON {
          * Dispose this feature and all of the resources attached
          */
         dispose(): void;
+        protected _onXRFrame(_xrFrame: XRFrame): void;
     }
 }
 declare module BABYLON {

+ 25 - 32
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -3095,7 +3095,10 @@ var GLTFFileLoader = /** @class */ (function () {
                     readAsync: function (byteOffset, byteLength) {
                         return new Promise(function (resolve, reject) {
                             fileRequests_1.push(scene._requestFile(url, function (data, webRequest) {
-                                dataBuffer_1.byteLength = Number(webRequest.getResponseHeader("Content-Range").split("/")[1]);
+                                var contentRange = webRequest.getResponseHeader("Content-Range");
+                                if (contentRange) {
+                                    dataBuffer_1.byteLength = Number(contentRange.split("/")[1]);
+                                }
                                 resolve(new Uint8Array(data));
                             }, onProgress, true, true, function (error) {
                                 reject(error);
@@ -3306,17 +3309,17 @@ var GLTFFileLoader = /** @class */ (function () {
                 _this._log("Binary version: " + version);
             }
             var length = dataReader.readUint32();
-            if (length !== dataReader.buffer.byteLength) {
+            if (dataReader.buffer.byteLength != 0 && length !== dataReader.buffer.byteLength) {
                 throw new Error("Length in header does not match actual data length: " + length + " != " + dataReader.buffer.byteLength);
             }
             var unpacked;
             switch (version) {
                 case 1: {
-                    unpacked = _this._unpackBinaryV1Async(dataReader);
+                    unpacked = _this._unpackBinaryV1Async(dataReader, length);
                     break;
                 }
                 case 2: {
-                    unpacked = _this._unpackBinaryV2Async(dataReader);
+                    unpacked = _this._unpackBinaryV2Async(dataReader, length);
                     break;
                 }
                 default: {
@@ -3327,7 +3330,7 @@ var GLTFFileLoader = /** @class */ (function () {
             return unpacked;
         });
     };
-    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader, length) {
         var ContentFormat = {
             JSON: 0
         };
@@ -3336,7 +3339,7 @@ var GLTFFileLoader = /** @class */ (function () {
         if (contentFormat !== ContentFormat.JSON) {
             throw new Error("Unexpected content format: " + contentFormat);
         }
-        var bodyLength = dataReader.buffer.byteLength - dataReader.byteOffset;
+        var bodyLength = length - dataReader.byteOffset;
         var data = { json: this._parseJson(dataReader.readString(contentLength)), bin: null };
         if (bodyLength !== 0) {
             var startByteOffset_1 = dataReader.byteOffset;
@@ -3347,33 +3350,23 @@ var GLTFFileLoader = /** @class */ (function () {
         }
         return Promise.resolve(data);
     };
-    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader, length) {
         var _this = this;
         var ChunkFormat = {
             JSON: 0x4E4F534A,
             BIN: 0x004E4942
         };
-        // Read the JSON chunk header.
-        var chunkLength = dataReader.readUint32();
-        var chunkFormat = dataReader.readUint32();
-        if (chunkFormat !== ChunkFormat.JSON) {
-            throw new Error("First chunk format is not JSON");
-        }
-        // Bail if there are no other chunks.
-        if (dataReader.byteOffset + chunkLength === dataReader.buffer.byteLength) {
-            return dataReader.loadAsync(chunkLength).then(function () {
-                return { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            });
-        }
-        // Read the JSON chunk and the length and type of the next chunk.
-        return dataReader.loadAsync(chunkLength + 8).then(function () {
-            var data = { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            var readAsync = function () {
-                var chunkLength = dataReader.readUint32();
-                var chunkFormat = dataReader.readUint32();
+        var data = { json: {}, bin: null };
+        var readAsync = function () {
+            var chunkLength = dataReader.readUint32();
+            var chunkFormat = dataReader.readUint32();
+            var finalChunk = (dataReader.byteOffset + chunkLength + 8 > length);
+            // Read the chunk and (if available) the length and type of the next chunk.
+            return dataReader.loadAsync(finalChunk ? chunkLength : chunkLength + 8).then(function () {
                 switch (chunkFormat) {
                     case ChunkFormat.JSON: {
-                        throw new Error("Unexpected JSON chunk");
+                        data.json = _this._parseJson(dataReader.readString(chunkLength));
+                        break;
                     }
                     case ChunkFormat.BIN: {
                         var startByteOffset_2 = dataReader.byteOffset;
@@ -3390,13 +3383,13 @@ var GLTFFileLoader = /** @class */ (function () {
                         break;
                     }
                 }
-                if (dataReader.byteOffset !== dataReader.buffer.byteLength) {
-                    return dataReader.loadAsync(8).then(readAsync);
+                if (finalChunk) {
+                    return data;
                 }
-                return Promise.resolve(data);
-            };
-            return readAsync();
-        });
+                return readAsync();
+            });
+        };
+        return readAsync();
     };
     GLTFFileLoader._parseVersion = function (version) {
         if (version === "1.0" || version === "1.0.1") {

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.js.map


Разница между файлами не показана из-за своего большого размера
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 25 - 32
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -4345,7 +4345,10 @@ var GLTFFileLoader = /** @class */ (function () {
                     readAsync: function (byteOffset, byteLength) {
                         return new Promise(function (resolve, reject) {
                             fileRequests_1.push(scene._requestFile(url, function (data, webRequest) {
-                                dataBuffer_1.byteLength = Number(webRequest.getResponseHeader("Content-Range").split("/")[1]);
+                                var contentRange = webRequest.getResponseHeader("Content-Range");
+                                if (contentRange) {
+                                    dataBuffer_1.byteLength = Number(contentRange.split("/")[1]);
+                                }
                                 resolve(new Uint8Array(data));
                             }, onProgress, true, true, function (error) {
                                 reject(error);
@@ -4556,17 +4559,17 @@ var GLTFFileLoader = /** @class */ (function () {
                 _this._log("Binary version: " + version);
             }
             var length = dataReader.readUint32();
-            if (length !== dataReader.buffer.byteLength) {
+            if (dataReader.buffer.byteLength != 0 && length !== dataReader.buffer.byteLength) {
                 throw new Error("Length in header does not match actual data length: " + length + " != " + dataReader.buffer.byteLength);
             }
             var unpacked;
             switch (version) {
                 case 1: {
-                    unpacked = _this._unpackBinaryV1Async(dataReader);
+                    unpacked = _this._unpackBinaryV1Async(dataReader, length);
                     break;
                 }
                 case 2: {
-                    unpacked = _this._unpackBinaryV2Async(dataReader);
+                    unpacked = _this._unpackBinaryV2Async(dataReader, length);
                     break;
                 }
                 default: {
@@ -4577,7 +4580,7 @@ var GLTFFileLoader = /** @class */ (function () {
             return unpacked;
         });
     };
-    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader, length) {
         var ContentFormat = {
             JSON: 0
         };
@@ -4586,7 +4589,7 @@ var GLTFFileLoader = /** @class */ (function () {
         if (contentFormat !== ContentFormat.JSON) {
             throw new Error("Unexpected content format: " + contentFormat);
         }
-        var bodyLength = dataReader.buffer.byteLength - dataReader.byteOffset;
+        var bodyLength = length - dataReader.byteOffset;
         var data = { json: this._parseJson(dataReader.readString(contentLength)), bin: null };
         if (bodyLength !== 0) {
             var startByteOffset_1 = dataReader.byteOffset;
@@ -4597,33 +4600,23 @@ var GLTFFileLoader = /** @class */ (function () {
         }
         return Promise.resolve(data);
     };
-    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader, length) {
         var _this = this;
         var ChunkFormat = {
             JSON: 0x4E4F534A,
             BIN: 0x004E4942
         };
-        // Read the JSON chunk header.
-        var chunkLength = dataReader.readUint32();
-        var chunkFormat = dataReader.readUint32();
-        if (chunkFormat !== ChunkFormat.JSON) {
-            throw new Error("First chunk format is not JSON");
-        }
-        // Bail if there are no other chunks.
-        if (dataReader.byteOffset + chunkLength === dataReader.buffer.byteLength) {
-            return dataReader.loadAsync(chunkLength).then(function () {
-                return { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            });
-        }
-        // Read the JSON chunk and the length and type of the next chunk.
-        return dataReader.loadAsync(chunkLength + 8).then(function () {
-            var data = { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            var readAsync = function () {
-                var chunkLength = dataReader.readUint32();
-                var chunkFormat = dataReader.readUint32();
+        var data = { json: {}, bin: null };
+        var readAsync = function () {
+            var chunkLength = dataReader.readUint32();
+            var chunkFormat = dataReader.readUint32();
+            var finalChunk = (dataReader.byteOffset + chunkLength + 8 > length);
+            // Read the chunk and (if available) the length and type of the next chunk.
+            return dataReader.loadAsync(finalChunk ? chunkLength : chunkLength + 8).then(function () {
                 switch (chunkFormat) {
                     case ChunkFormat.JSON: {
-                        throw new Error("Unexpected JSON chunk");
+                        data.json = _this._parseJson(dataReader.readString(chunkLength));
+                        break;
                     }
                     case ChunkFormat.BIN: {
                         var startByteOffset_2 = dataReader.byteOffset;
@@ -4640,13 +4633,13 @@ var GLTFFileLoader = /** @class */ (function () {
                         break;
                     }
                 }
-                if (dataReader.byteOffset !== dataReader.buffer.byteLength) {
-                    return dataReader.loadAsync(8).then(readAsync);
+                if (finalChunk) {
+                    return data;
                 }
-                return Promise.resolve(data);
-            };
-            return readAsync();
-        });
+                return readAsync();
+            });
+        };
+        return readAsync();
     };
     GLTFFileLoader._parseVersion = function (version) {
         if (version === "1.0" || version === "1.0.1") {

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 25 - 32
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -6905,7 +6905,10 @@ var GLTFFileLoader = /** @class */ (function () {
                     readAsync: function (byteOffset, byteLength) {
                         return new Promise(function (resolve, reject) {
                             fileRequests_1.push(scene._requestFile(url, function (data, webRequest) {
-                                dataBuffer_1.byteLength = Number(webRequest.getResponseHeader("Content-Range").split("/")[1]);
+                                var contentRange = webRequest.getResponseHeader("Content-Range");
+                                if (contentRange) {
+                                    dataBuffer_1.byteLength = Number(contentRange.split("/")[1]);
+                                }
                                 resolve(new Uint8Array(data));
                             }, onProgress, true, true, function (error) {
                                 reject(error);
@@ -7116,17 +7119,17 @@ var GLTFFileLoader = /** @class */ (function () {
                 _this._log("Binary version: " + version);
             }
             var length = dataReader.readUint32();
-            if (length !== dataReader.buffer.byteLength) {
+            if (dataReader.buffer.byteLength != 0 && length !== dataReader.buffer.byteLength) {
                 throw new Error("Length in header does not match actual data length: " + length + " != " + dataReader.buffer.byteLength);
             }
             var unpacked;
             switch (version) {
                 case 1: {
-                    unpacked = _this._unpackBinaryV1Async(dataReader);
+                    unpacked = _this._unpackBinaryV1Async(dataReader, length);
                     break;
                 }
                 case 2: {
-                    unpacked = _this._unpackBinaryV2Async(dataReader);
+                    unpacked = _this._unpackBinaryV2Async(dataReader, length);
                     break;
                 }
                 default: {
@@ -7137,7 +7140,7 @@ var GLTFFileLoader = /** @class */ (function () {
             return unpacked;
         });
     };
-    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader, length) {
         var ContentFormat = {
             JSON: 0
         };
@@ -7146,7 +7149,7 @@ var GLTFFileLoader = /** @class */ (function () {
         if (contentFormat !== ContentFormat.JSON) {
             throw new Error("Unexpected content format: " + contentFormat);
         }
-        var bodyLength = dataReader.buffer.byteLength - dataReader.byteOffset;
+        var bodyLength = length - dataReader.byteOffset;
         var data = { json: this._parseJson(dataReader.readString(contentLength)), bin: null };
         if (bodyLength !== 0) {
             var startByteOffset_1 = dataReader.byteOffset;
@@ -7157,33 +7160,23 @@ var GLTFFileLoader = /** @class */ (function () {
         }
         return Promise.resolve(data);
     };
-    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader, length) {
         var _this = this;
         var ChunkFormat = {
             JSON: 0x4E4F534A,
             BIN: 0x004E4942
         };
-        // Read the JSON chunk header.
-        var chunkLength = dataReader.readUint32();
-        var chunkFormat = dataReader.readUint32();
-        if (chunkFormat !== ChunkFormat.JSON) {
-            throw new Error("First chunk format is not JSON");
-        }
-        // Bail if there are no other chunks.
-        if (dataReader.byteOffset + chunkLength === dataReader.buffer.byteLength) {
-            return dataReader.loadAsync(chunkLength).then(function () {
-                return { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            });
-        }
-        // Read the JSON chunk and the length and type of the next chunk.
-        return dataReader.loadAsync(chunkLength + 8).then(function () {
-            var data = { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            var readAsync = function () {
-                var chunkLength = dataReader.readUint32();
-                var chunkFormat = dataReader.readUint32();
+        var data = { json: {}, bin: null };
+        var readAsync = function () {
+            var chunkLength = dataReader.readUint32();
+            var chunkFormat = dataReader.readUint32();
+            var finalChunk = (dataReader.byteOffset + chunkLength + 8 > length);
+            // Read the chunk and (if available) the length and type of the next chunk.
+            return dataReader.loadAsync(finalChunk ? chunkLength : chunkLength + 8).then(function () {
                 switch (chunkFormat) {
                     case ChunkFormat.JSON: {
-                        throw new Error("Unexpected JSON chunk");
+                        data.json = _this._parseJson(dataReader.readString(chunkLength));
+                        break;
                     }
                     case ChunkFormat.BIN: {
                         var startByteOffset_2 = dataReader.byteOffset;
@@ -7200,13 +7193,13 @@ var GLTFFileLoader = /** @class */ (function () {
                         break;
                     }
                 }
-                if (dataReader.byteOffset !== dataReader.buffer.byteLength) {
-                    return dataReader.loadAsync(8).then(readAsync);
+                if (finalChunk) {
+                    return data;
                 }
-                return Promise.resolve(data);
-            };
-            return readAsync();
-        });
+                return readAsync();
+            });
+        };
+        return readAsync();
     };
     GLTFFileLoader._parseVersion = function (version) {
         if (version === "1.0" || version === "1.0.1") {

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 25 - 32
dist/preview release/loaders/babylonjs.loaders.js

@@ -8272,7 +8272,10 @@ var GLTFFileLoader = /** @class */ (function () {
                     readAsync: function (byteOffset, byteLength) {
                         return new Promise(function (resolve, reject) {
                             fileRequests_1.push(scene._requestFile(url, function (data, webRequest) {
-                                dataBuffer_1.byteLength = Number(webRequest.getResponseHeader("Content-Range").split("/")[1]);
+                                var contentRange = webRequest.getResponseHeader("Content-Range");
+                                if (contentRange) {
+                                    dataBuffer_1.byteLength = Number(contentRange.split("/")[1]);
+                                }
                                 resolve(new Uint8Array(data));
                             }, onProgress, true, true, function (error) {
                                 reject(error);
@@ -8483,17 +8486,17 @@ var GLTFFileLoader = /** @class */ (function () {
                 _this._log("Binary version: " + version);
             }
             var length = dataReader.readUint32();
-            if (length !== dataReader.buffer.byteLength) {
+            if (dataReader.buffer.byteLength != 0 && length !== dataReader.buffer.byteLength) {
                 throw new Error("Length in header does not match actual data length: " + length + " != " + dataReader.buffer.byteLength);
             }
             var unpacked;
             switch (version) {
                 case 1: {
-                    unpacked = _this._unpackBinaryV1Async(dataReader);
+                    unpacked = _this._unpackBinaryV1Async(dataReader, length);
                     break;
                 }
                 case 2: {
-                    unpacked = _this._unpackBinaryV2Async(dataReader);
+                    unpacked = _this._unpackBinaryV2Async(dataReader, length);
                     break;
                 }
                 default: {
@@ -8504,7 +8507,7 @@ var GLTFFileLoader = /** @class */ (function () {
             return unpacked;
         });
     };
-    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader, length) {
         var ContentFormat = {
             JSON: 0
         };
@@ -8513,7 +8516,7 @@ var GLTFFileLoader = /** @class */ (function () {
         if (contentFormat !== ContentFormat.JSON) {
             throw new Error("Unexpected content format: " + contentFormat);
         }
-        var bodyLength = dataReader.buffer.byteLength - dataReader.byteOffset;
+        var bodyLength = length - dataReader.byteOffset;
         var data = { json: this._parseJson(dataReader.readString(contentLength)), bin: null };
         if (bodyLength !== 0) {
             var startByteOffset_1 = dataReader.byteOffset;
@@ -8524,33 +8527,23 @@ var GLTFFileLoader = /** @class */ (function () {
         }
         return Promise.resolve(data);
     };
-    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader) {
+    GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader, length) {
         var _this = this;
         var ChunkFormat = {
             JSON: 0x4E4F534A,
             BIN: 0x004E4942
         };
-        // Read the JSON chunk header.
-        var chunkLength = dataReader.readUint32();
-        var chunkFormat = dataReader.readUint32();
-        if (chunkFormat !== ChunkFormat.JSON) {
-            throw new Error("First chunk format is not JSON");
-        }
-        // Bail if there are no other chunks.
-        if (dataReader.byteOffset + chunkLength === dataReader.buffer.byteLength) {
-            return dataReader.loadAsync(chunkLength).then(function () {
-                return { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            });
-        }
-        // Read the JSON chunk and the length and type of the next chunk.
-        return dataReader.loadAsync(chunkLength + 8).then(function () {
-            var data = { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            var readAsync = function () {
-                var chunkLength = dataReader.readUint32();
-                var chunkFormat = dataReader.readUint32();
+        var data = { json: {}, bin: null };
+        var readAsync = function () {
+            var chunkLength = dataReader.readUint32();
+            var chunkFormat = dataReader.readUint32();
+            var finalChunk = (dataReader.byteOffset + chunkLength + 8 > length);
+            // Read the chunk and (if available) the length and type of the next chunk.
+            return dataReader.loadAsync(finalChunk ? chunkLength : chunkLength + 8).then(function () {
                 switch (chunkFormat) {
                     case ChunkFormat.JSON: {
-                        throw new Error("Unexpected JSON chunk");
+                        data.json = _this._parseJson(dataReader.readString(chunkLength));
+                        break;
                     }
                     case ChunkFormat.BIN: {
                         var startByteOffset_2 = dataReader.byteOffset;
@@ -8567,13 +8560,13 @@ var GLTFFileLoader = /** @class */ (function () {
                         break;
                     }
                 }
-                if (dataReader.byteOffset !== dataReader.buffer.byteLength) {
-                    return dataReader.loadAsync(8).then(readAsync);
+                if (finalChunk) {
+                    return data;
                 }
-                return Promise.resolve(data);
-            };
-            return readAsync();
-        });
+                return readAsync();
+            });
+        };
+        return readAsync();
     };
     GLTFFileLoader._parseVersion = function (version) {
         if (version === "1.0" || version === "1.0.1") {

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


Разница между файлами не показана из-за своего большого размера
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


Разница между файлами не показана из-за своего большого размера
+ 2 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.js


Разница между файлами не показана из-за своего большого размера
+ 2 - 11
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"thinEngineOnly":112368,"engineOnly":148478,"sceneOnly":502443,"minGridMaterial":633238,"minStandardMaterial":773265}
+{"thinEngineOnly":112368,"engineOnly":148478,"sceneOnly":503038,"minGridMaterial":633672,"minStandardMaterial":773699}

+ 130 - 51
dist/preview release/viewer/babylon.module.d.ts

@@ -14787,6 +14787,11 @@ declare module "babylonjs/Meshes/transformNode" {
          * @returns the world matrix
          */
         computeWorldMatrix(force?: boolean): Matrix;
+        /**
+         * Resets this nodeTransform's local matrix to Matrix.Identity().
+         * @param independentOfChildren indicates if all child nodeTransform's world-space transform should be preserved.
+         */
+        resetLocalMatrix(independentOfChildren?: boolean): void;
         protected _afterComputeWorldMatrix(): void;
         /**
         * If you'd like to be called back after the mesh position, rotation or scaling has been updated.
@@ -25456,9 +25461,10 @@ declare module "babylonjs/Meshes/mesh" {
          * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
          * Note that, under the hood, this method sets a new VertexBuffer each call.
          * @see http://doc.babylonjs.com/resources/baking_transformations
+         * @param bakeIndependenlyOfChildren indicates whether to preserve all child nodes' World Matrix during baking
          * @returns the current mesh
          */
-        bakeCurrentTransformIntoVertices(): Mesh;
+        bakeCurrentTransformIntoVertices(bakeIndependenlyOfChildren?: boolean): Mesh;
         /** @hidden */
         get _positions(): Nullable<Vector3[]>;
         /** @hidden */
@@ -44027,10 +44033,10 @@ declare module "babylonjs/Cameras/XR/webXRSessionManager" {
         initializeSessionAsync(xrSessionMode?: XRSessionMode, xrSessionInit?: XRSessionInit): Promise<XRSession>;
         /**
          * Sets the reference space on the xr session
-         * @param referenceSpace space to set
+         * @param referenceSpaceType space to set
          * @returns a promise that will resolve once the reference space has been set
          */
-        setReferenceSpaceAsync(referenceSpace?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
+        setReferenceSpaceTypeAsync(referenceSpaceType?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
         /**
          * Resets the reference space to the one started the session
          */
@@ -44100,10 +44106,6 @@ declare module "babylonjs/Cameras/XR/webXRCamera" {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
-        /**
-         * Is the camera in debug mode. Used when using an emulator
-         */
-        debugMode: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -44121,7 +44123,7 @@ declare module "babylonjs/Cameras/XR/webXRCamera" {
          * @param otherCamera the non-vr camera to copy the transformation from
          * @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 _updateReferenceSpace;
@@ -44141,12 +44143,17 @@ declare module "babylonjs/Cameras/XR/webXRFeaturesManager" {
          */
         attached: boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * Attach the feature to the session
          * Will usually be called by the features manager
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful.
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * Detach the feature from the session
          * Will usually be called by the features manager
@@ -44156,6 +44163,35 @@ declare module "babylonjs/Cameras/XR/webXRFeaturesManager" {
         detach(): boolean;
     }
     /**
+     * A list of the currently available features without referencing them
+     */
+    export class WebXRFeatureName {
+        /**
+         * The name of the hit test feature
+         */
+        static HIT_TEST: string;
+        /**
+         * The name of the anchor system feature
+         */
+        static ANCHOR_SYSTEM: string;
+        /**
+         * The name of the background remover feature
+         */
+        static BACKGROUND_REMOVER: string;
+        /**
+         * The name of the pointer selection feature
+         */
+        static POINTER_SELECTION: string;
+        /**
+         * The name of the teleportation feature
+         */
+        static TELEPORTATION: string;
+        /**
+         * The name of the plane detection feature
+         */
+        static PLANE_DETECTION: string;
+    }
+    /**
      * Defining the constructor of a feature. Used to register the modules.
      */
     export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => IWebXRFeature);
@@ -45488,11 +45524,16 @@ declare module "babylonjs/Cameras/XR/features/WebXRAbstractFeature" {
          */
         get attached(): boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * attach this feature
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful, false is failed or already attached
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * detach this feature.
          *
@@ -45508,7 +45549,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRAbstractFeature" {
          * This function will not execute after the feature is detached.
          * @param _xrFrame the current frame
          */
-        protected _onXRFrame(_xrFrame: XRFrame): void;
+        protected abstract _onXRFrame(_xrFrame: XRFrame): void;
         /**
          * This is used to register callbacks that will automatically be removed when detach is called.
          * @param observable the observable to which the observer will be attached
@@ -45518,7 +45559,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRAbstractFeature" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRControllerPointerSelection" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { WebXRInput } from "babylonjs/Cameras/XR/webXRInput";
     import { WebXRController } from "babylonjs/Cameras/XR/webXRController";
@@ -45564,12 +45604,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRControllerPointerSelection" {
     /**
      * A module that will enable pointer selection for motion controllers of XR Input Sources
      */
-    export class WebXRControllerPointerSelection extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         private readonly _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -45900,12 +45940,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRControllerTeleportation" {
      * When enabled and attached, the feature will allow a user to move aroundand rotate in the scene using
      * the input of the attached controllers.
      */
-    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46521,7 +46561,6 @@ declare module "babylonjs/Cameras/VR/index" {
     export * from "babylonjs/Cameras/VR/webVRCamera";
 }
 declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { Observable } from "babylonjs/Misc/observable";
     import { Matrix } from "babylonjs/Maths/math.vector";
@@ -46558,7 +46597,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
      * Hit test (or raycasting) is used to interact with the real world.
      * For further information read here - https://github.com/immersive-web/hit-test
      */
-    export class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRHitTestLegacy extends WebXRAbstractFeature {
         /**
          * options to use when constructing this feature
          */
@@ -46566,7 +46605,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46636,7 +46675,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRHitTestLegacy" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { TransformNode } from "babylonjs/Meshes/transformNode";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { Observable } from "babylonjs/Misc/observable";
@@ -46678,12 +46716,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
      * The plane detector is used to detect planes in the real world when in AR
      * For more information see https://github.com/immersive-web/real-world-geometry/
      */
-    export class WebXRPlaneDetector extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRPlaneDetector extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46726,7 +46764,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRAnchorSystem" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { Observable } from "babylonjs/Misc/observable";
     import { Matrix } from "babylonjs/Maths/math.vector";
@@ -46775,12 +46812,12 @@ declare module "babylonjs/Cameras/XR/features/WebXRAnchorSystem" {
      * will use the frame to create an anchor and not the session or a detected plane
      * For further information see https://github.com/immersive-web/anchors/
      */
-    export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRAnchorSystem extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46859,7 +46896,6 @@ declare module "babylonjs/Cameras/XR/features/WebXRAnchorSystem" {
     }
 }
 declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
-    import { IWebXRFeature } from "babylonjs/Cameras/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/Cameras/XR/webXRSessionManager";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Observable } from "babylonjs/Misc/observable";
@@ -46894,7 +46930,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
     /**
      * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.
      */
-    export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRBackgroundRemover extends WebXRAbstractFeature {
         /**
          * read-only options to be used in this module
          */
@@ -46902,7 +46938,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -46942,6 +46978,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRBackgroundRemover" {
          * Dispose this feature and all of the resources attached
          */
         dispose(): void;
+        protected _onXRFrame(_xrFrame: XRFrame): void;
     }
 }
 declare module "babylonjs/Cameras/XR/features/index" {
@@ -86937,6 +86974,11 @@ declare module BABYLON {
          * @returns the world matrix
          */
         computeWorldMatrix(force?: boolean): Matrix;
+        /**
+         * Resets this nodeTransform's local matrix to Matrix.Identity().
+         * @param independentOfChildren indicates if all child nodeTransform's world-space transform should be preserved.
+         */
+        resetLocalMatrix(independentOfChildren?: boolean): void;
         protected _afterComputeWorldMatrix(): void;
         /**
         * If you'd like to be called back after the mesh position, rotation or scaling has been updated.
@@ -97181,9 +97223,10 @@ declare module BABYLON {
          * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
          * Note that, under the hood, this method sets a new VertexBuffer each call.
          * @see http://doc.babylonjs.com/resources/baking_transformations
+         * @param bakeIndependenlyOfChildren indicates whether to preserve all child nodes' World Matrix during baking
          * @returns the current mesh
          */
-        bakeCurrentTransformIntoVertices(): Mesh;
+        bakeCurrentTransformIntoVertices(bakeIndependenlyOfChildren?: boolean): Mesh;
         /** @hidden */
         get _positions(): Nullable<Vector3[]>;
         /** @hidden */
@@ -115006,10 +115049,10 @@ declare module BABYLON {
         initializeSessionAsync(xrSessionMode?: XRSessionMode, xrSessionInit?: XRSessionInit): Promise<XRSession>;
         /**
          * Sets the reference space on the xr session
-         * @param referenceSpace space to set
+         * @param referenceSpaceType space to set
          * @returns a promise that will resolve once the reference space has been set
          */
-        setReferenceSpaceAsync(referenceSpace?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
+        setReferenceSpaceTypeAsync(referenceSpaceType?: XRReferenceSpaceType): Promise<XRReferenceSpace>;
         /**
          * Resets the reference space to the one started the session
          */
@@ -115075,10 +115118,6 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
-        /**
-         * Is the camera in debug mode. Used when using an emulator
-         */
-        debugMode: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -115096,7 +115135,7 @@ declare module BABYLON {
          * @param otherCamera the non-vr camera to copy the transformation from
          * @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 _updateReferenceSpace;
@@ -115114,12 +115153,17 @@ declare module BABYLON {
          */
         attached: boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * Attach the feature to the session
          * Will usually be called by the features manager
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful.
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * Detach the feature from the session
          * Will usually be called by the features manager
@@ -115129,6 +115173,35 @@ declare module BABYLON {
         detach(): boolean;
     }
     /**
+     * A list of the currently available features without referencing them
+     */
+    export class WebXRFeatureName {
+        /**
+         * The name of the hit test feature
+         */
+        static HIT_TEST: string;
+        /**
+         * The name of the anchor system feature
+         */
+        static ANCHOR_SYSTEM: string;
+        /**
+         * The name of the background remover feature
+         */
+        static BACKGROUND_REMOVER: string;
+        /**
+         * The name of the pointer selection feature
+         */
+        static POINTER_SELECTION: string;
+        /**
+         * The name of the teleportation feature
+         */
+        static TELEPORTATION: string;
+        /**
+         * The name of the plane detection feature
+         */
+        static PLANE_DETECTION: string;
+    }
+    /**
      * Defining the constructor of a feature. Used to register the modules.
      */
     export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => IWebXRFeature);
@@ -116418,11 +116491,16 @@ declare module BABYLON {
          */
         get attached(): boolean;
         /**
+         * Should auto-attach be disabled?
+         */
+        disableAutoAttach: boolean;
+        /**
          * attach this feature
          *
+         * @param force should attachment be forced (even when already attached)
          * @returns true if successful, false is failed or already attached
          */
-        attach(): boolean;
+        attach(force?: boolean): boolean;
         /**
          * detach this feature.
          *
@@ -116438,7 +116516,7 @@ declare module BABYLON {
          * This function will not execute after the feature is detached.
          * @param _xrFrame the current frame
          */
-        protected _onXRFrame(_xrFrame: XRFrame): void;
+        protected abstract _onXRFrame(_xrFrame: XRFrame): void;
         /**
          * This is used to register callbacks that will automatically be removed when detach is called.
          * @param observable the observable to which the observer will be attached
@@ -116487,12 +116565,12 @@ declare module BABYLON {
     /**
      * A module that will enable pointer selection for motion controllers of XR Input Sources
      */
-    export class WebXRControllerPointerSelection extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
         private readonly _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -116807,12 +116885,12 @@ declare module BABYLON {
      * When enabled and attached, the feature will allow a user to move aroundand rotate in the scene using
      * the input of the attached controllers.
      */
-    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117421,7 +117499,7 @@ declare module BABYLON {
      * Hit test (or raycasting) is used to interact with the real world.
      * For further information read here - https://github.com/immersive-web/hit-test
      */
-    export class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRHitTestLegacy extends WebXRAbstractFeature {
         /**
          * options to use when constructing this feature
          */
@@ -117429,7 +117507,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117535,12 +117613,12 @@ declare module BABYLON {
      * The plane detector is used to detect planes in the real world when in AR
      * For more information see https://github.com/immersive-web/real-world-geometry/
      */
-    export class WebXRPlaneDetector extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRPlaneDetector extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117624,12 +117702,12 @@ declare module BABYLON {
      * will use the frame to create an anchor and not the session or a detected plane
      * For further information see https://github.com/immersive-web/anchors/
      */
-    export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRAnchorSystem extends WebXRAbstractFeature {
         private _options;
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117738,7 +117816,7 @@ declare module BABYLON {
     /**
      * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.
      */
-    export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWebXRFeature {
+    export class WebXRBackgroundRemover extends WebXRAbstractFeature {
         /**
          * read-only options to be used in this module
          */
@@ -117746,7 +117824,7 @@ declare module BABYLON {
         /**
          * The module's name
          */
-        static readonly Name: string;
+        static readonly Name: string;
         /**
          * The (Babylon) version of this module.
          * This is an integer representing the implementation version.
@@ -117786,6 +117864,7 @@ declare module BABYLON {
          * Dispose this feature and all of the resources attached
          */
         dispose(): void;
+        protected _onXRFrame(_xrFrame: XRFrame): void;
     }
 }
 declare module BABYLON {

Разница между файлами не показана из-за своего большого размера
+ 18 - 18
dist/preview release/viewer/babylon.viewer.js


Разница между файлами не показана из-за своего большого размера
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -193,7 +193,7 @@
 - WebXR teleportation can now be disabled after initialized or before created ([RaananW](https://github.com/RaananW/))
 - New Features Manager for WebXR features ([RaananW](https://github.com/RaananW/))
 - New features - Plane detection, Hit Test, Background remover ([RaananW](https://github.com/RaananW/))
-- Camera's API is Babylon-conform (position, rotationQuaternion, world matrix, direction etc') ([#7239](https://github.com/BabylonJS/Babylon.js/issues/7239)) ([RaananW](https://github.com/RaananW/))
+- XR Camera's API is Babylon-conform (position, rotationQuaternion, world matrix, direction etc') ([#7239](https://github.com/BabylonJS/Babylon.js/issues/7239)) ([RaananW](https://github.com/RaananW/))
 - XR Input now using standard profiles and completely separated from the gamepad class ([#7348](https://github.com/BabylonJS/Babylon.js/issues/7348)) ([RaananW](https://github.com/RaananW/))
 - Teleportation and controller selection are now WebXR features. ([#7290](https://github.com/BabylonJS/Babylon.js/issues/7290)) ([RaananW](https://github.com/RaananW/))
 - Teleportation allows selecting direction before teleporting when using thumbstick or touchpad. ([#7290](https://github.com/BabylonJS/Babylon.js/issues/7290)) ([RaananW](https://github.com/RaananW/))

+ 25 - 33
loaders/src/glTF/glTFFileLoader.ts

@@ -486,7 +486,10 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
                     readAsync: (byteOffset: number, byteLength: number) => {
                         return new Promise<ArrayBufferView>((resolve, reject) => {
                             fileRequests.push(scene._requestFile(url, (data, webRequest) => {
-                                dataBuffer.byteLength = Number(webRequest!.getResponseHeader("Content-Range")!.split("/")[1]);
+                                const contentRange = webRequest!.getResponseHeader("Content-Range");
+                                if (contentRange) {
+                                    dataBuffer.byteLength = Number(contentRange.split("/")[1]);
+                                }
                                 resolve(new Uint8Array(data as ArrayBuffer));
                             }, onProgress, true, true, (error) => {
                                 reject(error);
@@ -727,18 +730,18 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
             }
 
             const length = dataReader.readUint32();
-            if (length !== dataReader.buffer.byteLength) {
+            if (dataReader.buffer.byteLength != 0 && length !== dataReader.buffer.byteLength) {
                 throw new Error(`Length in header does not match actual data length: ${length} != ${dataReader.buffer.byteLength}`);
             }
 
             let unpacked: Promise<IGLTFLoaderData>;
             switch (version) {
                 case 1: {
-                    unpacked = this._unpackBinaryV1Async(dataReader);
+                    unpacked = this._unpackBinaryV1Async(dataReader, length);
                     break;
                 }
                 case 2: {
-                    unpacked = this._unpackBinaryV2Async(dataReader);
+                    unpacked = this._unpackBinaryV2Async(dataReader, length);
                     break;
                 }
                 default: {
@@ -752,7 +755,7 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
         });
     }
 
-    private _unpackBinaryV1Async(dataReader: DataReader): Promise<IGLTFLoaderData> {
+    private _unpackBinaryV1Async(dataReader: DataReader, length: number): Promise<IGLTFLoaderData> {
         const ContentFormat = {
             JSON: 0
         };
@@ -764,7 +767,7 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
             throw new Error(`Unexpected content format: ${contentFormat}`);
         }
 
-        const bodyLength = dataReader.buffer.byteLength - dataReader.byteOffset;
+        const bodyLength = length - dataReader.byteOffset;
 
         const data: IGLTFLoaderData = { json: this._parseJson(dataReader.readString(contentLength)), bin: null };
         if (bodyLength !== 0) {
@@ -778,37 +781,26 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
         return Promise.resolve(data);
     }
 
-    private _unpackBinaryV2Async(dataReader: DataReader): Promise<IGLTFLoaderData> {
+    private _unpackBinaryV2Async(dataReader: DataReader, length: number): Promise<IGLTFLoaderData> {
         const ChunkFormat = {
             JSON: 0x4E4F534A,
             BIN: 0x004E4942
         };
 
-        // Read the JSON chunk header.
-        const chunkLength = dataReader.readUint32();
-        const chunkFormat = dataReader.readUint32();
-        if (chunkFormat !== ChunkFormat.JSON) {
-            throw new Error("First chunk format is not JSON");
-        }
+        const data: IGLTFLoaderData = { json: {}, bin: null };
 
-        // Bail if there are no other chunks.
-        if (dataReader.byteOffset + chunkLength === dataReader.buffer.byteLength) {
-            return dataReader.loadAsync(chunkLength).then(() => {
-                return { json: this._parseJson(dataReader.readString(chunkLength)), bin: null };
-            });
-        }
+        const readAsync = (): Promise<IGLTFLoaderData> => {
+            const chunkLength = dataReader.readUint32();
+            const chunkFormat = dataReader.readUint32();
 
-        // Read the JSON chunk and the length and type of the next chunk.
-        return dataReader.loadAsync(chunkLength + 8).then(() => {
-            const data: IGLTFLoaderData = { json: this._parseJson(dataReader.readString(chunkLength)), bin: null };
-
-            const readAsync = (): Promise<IGLTFLoaderData> => {
-                const chunkLength = dataReader.readUint32();
-                const chunkFormat = dataReader.readUint32();
+            const finalChunk = (dataReader.byteOffset + chunkLength + 8 > length);
 
+            // Read the chunk and (if available) the length and type of the next chunk.
+            return dataReader.loadAsync(finalChunk ? chunkLength : chunkLength + 8).then(() => {
                 switch (chunkFormat) {
                     case ChunkFormat.JSON: {
-                        throw new Error("Unexpected JSON chunk");
+                        data.json = this._parseJson(dataReader.readString(chunkLength));
+                        break;
                     }
                     case ChunkFormat.BIN: {
                         const startByteOffset = dataReader.byteOffset;
@@ -826,15 +818,15 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
                     }
                 }
 
-                if (dataReader.byteOffset !== dataReader.buffer.byteLength) {
-                    return dataReader.loadAsync(8).then(readAsync);
+                if (finalChunk) {
+                    return data;
                 }
 
-                return Promise.resolve(data);
-            };
+                return readAsync();
+            });
+        };
 
-            return readAsync();
-        });
+        return readAsync();
     }
 
     private static _parseVersion(version: string): Nullable<{ major: number, minor: number }> {

+ 0 - 12
nodeEditor/src/diagram/display/inputDisplayManager.ts

@@ -62,8 +62,6 @@ export class InputDisplayManager implements IDisplayManager {
     public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {
         let value = "";
         let inputBlock = block as InputBlock;
-        let isFat = false;
-        let smallFont = false;
 
         if (inputBlock.isAttribute) {
             value = "mesh." + inputBlock.name;
@@ -77,7 +75,6 @@ export class InputDisplayManager implements IDisplayManager {
                     break;
                 case NodeMaterialSystemValues.WorldViewProjection:
                     value = "World x View x Projection";
-                    isFat = true;
                     break;
                 case NodeMaterialSystemValues.View:
                     value = "View";
@@ -116,7 +113,6 @@ export class InputDisplayManager implements IDisplayManager {
                     value = `(${vec3Value.x.toFixed(2)}, ${vec3Value.y.toFixed(2)}, ${vec3Value.z.toFixed(2)})`;
                     break;
                 case NodeMaterialBlockConnectionPointTypes.Vector4:
-                    smallFont = true;
                     let vec4Value = inputBlock.value as Vector4
                     value = `(${vec4Value.x.toFixed(2)}, ${vec4Value.y.toFixed(2)}, ${vec4Value.z.toFixed(2)}, ${vec4Value.w.toFixed(2)})`;
                     break;                        
@@ -125,13 +121,5 @@ export class InputDisplayManager implements IDisplayManager {
 
         contentArea.innerHTML = value;
         contentArea.classList.add("input-block");
-
-        if (isFat) {
-            contentArea.classList.add("fat");
-        }
-
-        if (smallFont) {
-            contentArea.classList.add("small-font");
-        }
     }
 }

+ 4 - 6
nodeEditor/src/diagram/graphCanvas.scss

@@ -352,15 +352,13 @@
 
                     &.input-block {
                         grid-row: 2;
-                        height: 34px;
+                        min-height: 34px;
                         text-align: center;
                         font-size: 18px;
                         font-weight: bold;
-                        margin: 0 10px;
-
-                        &.fat {
-                            height: 54px;
-                        }
+                        margin: 0 10px 5px;
+                        display: grid;
+                        align-content: center;
 
                         &.small-font {                            
                             font-size: 17px;

+ 1 - 0
nodeEditor/src/diagram/properties/gradientNodePropertyComponent.tsx

@@ -55,6 +55,7 @@ export class GradientPropertyTabComponent extends React.Component<IPropertyCompo
             return -1;
         });
 
+        this.props.globalState.onUpdateRequiredObservable.notifyObservers();
         this.forceUpdate();
     }
 

+ 19 - 7
src/Cameras/XR/features/WebXRAbstractFeature.ts

@@ -15,7 +15,6 @@ export abstract class WebXRAbstractFeature implements IWebXRFeature {
      * @param _xrSessionManager the xr session manager for this feature
      */
     constructor(protected _xrSessionManager: WebXRSessionManager) {
-
     }
 
     private _attached: boolean = false;
@@ -32,14 +31,28 @@ export abstract class WebXRAbstractFeature implements IWebXRFeature {
     }
 
     /**
+     * Should auto-attach be disabled?
+     */
+    public disableAutoAttach: boolean = false;
+
+    /**
      * attach this feature
      *
+     * @param force should attachment be forced (even when already attached)
      * @returns true if successful, false is failed or already attached
      */
-    public attach(): boolean {
-        if (this.attached) {
-            return false;
+    public attach(force?: boolean): boolean {
+        if (!force) {
+            if (this.attached) {
+                return false;
+            }
+        } else {
+            if (this.attached) {
+                // detach first, to be sure
+                this.detach();
+            }
         }
+
         this._attached = true;
         this._addNewAttachObserver(this._xrSessionManager.onXRFrameObservable, (frame) => this._onXRFrame(frame));
         return true;
@@ -52,6 +65,7 @@ export abstract class WebXRAbstractFeature implements IWebXRFeature {
      */
     public detach(): boolean {
         if (!this._attached) {
+            this.disableAutoAttach = true;
             return false;
         }
         this._attached = false;
@@ -72,9 +86,7 @@ export abstract class WebXRAbstractFeature implements IWebXRFeature {
      * This function will not execute after the feature is detached.
      * @param _xrFrame the current frame
      */
-    protected _onXRFrame(_xrFrame: XRFrame): void {
-        // no-op
-    }
+    protected abstract _onXRFrame(_xrFrame: XRFrame): void;
 
     /**
      * This is used to register callbacks that will automatically be removed when detach is called.

+ 6 - 8
src/Cameras/XR/features/WebXRAnchorSystem.ts

@@ -1,4 +1,4 @@
-import { IWebXRFeature, WebXRFeaturesManager } from '../webXRFeaturesManager';
+import { WebXRFeatureName } from '../webXRFeaturesManager';
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { Observable } from '../../../Misc/observable';
 import { Matrix } from '../../../Maths/math.vector';
@@ -7,8 +7,6 @@ import { WebXRPlaneDetector } from './WebXRPlaneDetector';
 import { WebXRHitTestLegacy } from './WebXRHitTestLegacy';
 import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 
-const Name = "xr-anchor-system";
-
 /**
  * Configuration options of the anchor system
  */
@@ -54,12 +52,12 @@ let anchorIdProvider = 0;
  * will use the frame to create an anchor and not the session or a detected plane
  * For further information see https://github.com/immersive-web/anchors/
  */
-export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFeature {
+export class WebXRAnchorSystem extends WebXRAbstractFeature {
 
     /**
      * The module's name
      */
-    public static readonly Name = Name;
+    public static readonly Name = WebXRFeatureName.ANCHOR_SYSTEM;
     /**
      * The (Babylon) version of this module.
      * This is an integer representing the implementation version.
@@ -262,6 +260,6 @@ export class WebXRAnchorSystem extends WebXRAbstractFeature implements IWebXRFea
 }
 
 //register the plugin
-WebXRFeaturesManager.AddWebXRFeature(WebXRAnchorSystem.Name, (xrSessionManager, options) => {
-    return () => new WebXRAnchorSystem(xrSessionManager, options);
-}, WebXRAnchorSystem.Version);
+// WebXRFeaturesManager.AddWebXRFeature(WebXRAnchorSystem.Name, (xrSessionManager, options) => {
+//     return () => new WebXRAnchorSystem(xrSessionManager, options);
+// }, WebXRAnchorSystem.Version);

+ 7 - 5
src/Cameras/XR/features/WebXRBackgroundRemover.ts

@@ -1,11 +1,9 @@
-import { WebXRFeaturesManager, IWebXRFeature } from "../webXRFeaturesManager";
+import { WebXRFeaturesManager, WebXRFeatureName } from "../webXRFeaturesManager";
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { AbstractMesh } from '../../../Meshes/abstractMesh';
 import { Observable } from '../../../Misc/observable';
 import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 
-const Name = "xr-background-remover";
-
 /**
  * Options interface for the background remover plugin
  */
@@ -37,12 +35,12 @@ export interface IWebXRBackgroundRemoverOptions {
 /**
  * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.
  */
-export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWebXRFeature {
+export class WebXRBackgroundRemover extends WebXRAbstractFeature {
 
     /**
      * The module's name
      */
-    public static readonly Name = Name;
+    public static readonly Name = WebXRFeatureName.BACKGROUND_REMOVER;
     /**
      * The (Babylon) version of this module.
      * This is an integer representing the implementation version.
@@ -128,6 +126,10 @@ export class WebXRBackgroundRemover extends WebXRAbstractFeature implements IWeb
         super.dispose();
         this.onBackgroundStateChangedObservable.clear();
     }
+
+    protected _onXRFrame(_xrFrame: XRFrame) {
+        // no-op
+    }
 }
 
 //register the plugin

+ 3 - 5
src/Cameras/XR/features/WebXRControllerPointerSelection.ts

@@ -1,4 +1,4 @@
-import { WebXRFeaturesManager, IWebXRFeature } from "../webXRFeaturesManager";
+import { WebXRFeaturesManager, WebXRFeatureName } from "../webXRFeaturesManager";
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { AbstractMesh } from '../../../Meshes/abstractMesh';
 import { Observer } from '../../../Misc/observable';
@@ -17,8 +17,6 @@ import { Ray } from '../../../Culling/ray';
 import { PickingInfo } from '../../../Collisions/pickingInfo';
 import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 
-const Name = "xr-controller-pointer-selection";
-
 /**
  * Options interface for the pointer selection module
  */
@@ -62,12 +60,12 @@ export interface IWebXRControllerPointerSelectionOptions {
 /**
  * A module that will enable pointer selection for motion controllers of XR Input Sources
  */
-export class WebXRControllerPointerSelection extends WebXRAbstractFeature implements IWebXRFeature {
+export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
 
     /**
      * The module's name
      */
-    public static readonly Name = Name;
+    public static readonly Name = WebXRFeatureName.POINTER_SELECTION;
     /**
      * The (Babylon) version of this module.
      * This is an integer representing the implementation version.

+ 3 - 5
src/Cameras/XR/features/WebXRControllerTeleportation.ts

@@ -1,4 +1,4 @@
-import { IWebXRFeature, WebXRFeaturesManager } from '../webXRFeaturesManager';
+import { IWebXRFeature, WebXRFeaturesManager, WebXRFeatureName } from '../webXRFeaturesManager';
 import { Observer } from '../../../Misc/observable';
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { Nullable } from '../../../types';
@@ -22,8 +22,6 @@ import { Curve3 } from '../../../Maths/math.path';
 import { LinesBuilder } from '../../../Meshes/Builders/linesBuilder';
 import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 
-const Name = "xr-controller-teleportation";
-
 /**
  * The options container for the teleportation module
  */
@@ -85,11 +83,11 @@ export interface IWebXRTeleportationOptions {
  * When enabled and attached, the feature will allow a user to move aroundand rotate in the scene using
  * the input of the attached controllers.
  */
-export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature implements IWebXRFeature {
+export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
     /**
      * The module's name
      */
-    public static readonly Name = Name;
+    public static readonly Name = WebXRFeatureName.TELEPORTATION;
     /**
      * The (Babylon) version of this module.
      * This is an integer representing the implementation version.

+ 3 - 8
src/Cameras/XR/features/WebXRHitTestLegacy.ts

@@ -1,15 +1,10 @@
-import { IWebXRFeature, WebXRFeaturesManager } from '../webXRFeaturesManager';
+import { WebXRFeaturesManager, WebXRFeatureName } from '../webXRFeaturesManager';
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { Observable } from '../../../Misc/observable';
 import { Vector3, Matrix } from '../../../Maths/math.vector';
 import { TransformNode } from '../../../Meshes/transformNode';
 import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 
-/**
- * name of module (can be reused with other versions)
- */
-const WebXRHitTestModuleName = "xr-hit-test";
-
 // the plugin is registered at the end of the file
 
 /**
@@ -45,12 +40,12 @@ export interface IWebXRHitResult {
  * Hit test (or raycasting) is used to interact with the real world.
  * For further information read here - https://github.com/immersive-web/hit-test
  */
-export class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRFeature {
+export class WebXRHitTestLegacy extends WebXRAbstractFeature {
 
     /**
      * The module's name
      */
-    public static readonly Name = WebXRHitTestModuleName;
+    public static readonly Name = WebXRFeatureName.HIT_TEST;
     /**
      * The (Babylon) version of this module.
      * This is an integer representing the implementation version.

+ 3 - 5
src/Cameras/XR/features/WebXRPlaneDetector.ts

@@ -1,12 +1,10 @@
-import { WebXRFeaturesManager, IWebXRFeature } from '../webXRFeaturesManager';
+import { WebXRFeaturesManager, WebXRFeatureName } from '../webXRFeaturesManager';
 import { TransformNode } from '../../../Meshes/transformNode';
 import { WebXRSessionManager } from '../webXRSessionManager';
 import { Observable } from '../../../Misc/observable';
 import { Vector3, Matrix } from '../../../Maths/math.vector';
 import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 
-const Name = "xr-plane-detector";
-
 /**
  * Options used in the plane detector module
  */
@@ -47,12 +45,12 @@ let planeIdProvider = 0;
  * The plane detector is used to detect planes in the real world when in AR
  * For more information see https://github.com/immersive-web/real-world-geometry/
  */
-export class WebXRPlaneDetector extends WebXRAbstractFeature implements IWebXRFeature {
+export class WebXRPlaneDetector extends WebXRAbstractFeature {
 
     /**
      * The module's name
      */
-    public static readonly Name = Name;
+    public static readonly Name = WebXRFeatureName.PLANE_DETECTION;
     /**
      * The (Babylon) version of this module.
      * This is an integer representing the implementation version.

+ 4 - 9
src/Cameras/XR/webXRCamera.ts

@@ -12,11 +12,6 @@ import { Viewport } from '../../Maths/math.viewport';
  */
 export class WebXRCamera extends FreeCamera {
 
-    /**
-     * Is the camera in debug mode. Used when using an emulator
-     */
-    public debugMode = false;
-
     private _firstFrame = false;
     private _referencedPosition: Vector3 = new Vector3();
     private _referenceQuaternion: Quaternion = Quaternion.Identity();
@@ -78,7 +73,10 @@ export class WebXRCamera extends FreeCamera {
      * @param otherCamera the non-vr camera to copy the transformation from
      * @param resetToBaseReferenceSpace should XR reset to the base reference space
      */
-    public setTransformationFromNonVRCamera(otherCamera: Camera, resetToBaseReferenceSpace: boolean = true) {
+    public setTransformationFromNonVRCamera(otherCamera: Camera = this.getScene().activeCamera!, resetToBaseReferenceSpace: boolean = true) {
+        if (!otherCamera || otherCamera === this) {
+            return;
+        }
         const mat = otherCamera.computeWorldMatrix();
         mat.decompose(undefined, this.rotationQuaternion, this.position);
         // set the ground level
@@ -250,9 +248,6 @@ export class WebXRCamera extends FreeCamera {
                 currentRig.viewport.x = viewport.x / width;
                 currentRig.viewport.y = viewport.y / height;
             }
-            if (this.debugMode) {
-                this._updateForDualEyeDebugging();
-            }
 
             // Set cameras to render to the session's render target
             currentRig.outputRenderTarget = this._xrSessionManager.getRenderTargetTextureForEye(view.eye);

+ 6 - 1
src/Cameras/XR/webXRExperienceHelper.ts

@@ -23,6 +23,9 @@ export class WebXRExperienceHelper implements IDisposable {
     public state: WebXRState = WebXRState.NOT_IN_XR;
 
     private _setState(val: WebXRState) {
+        if (this.state === val) {
+            return;
+        }
         this.state = val;
         this.onStateChangedObservable.notifyObservers(this.state);
     }
@@ -63,6 +66,7 @@ export class WebXRExperienceHelper implements IDisposable {
             helper._supported = true;
             return helper;
         }).catch((e) => {
+            helper._setState(WebXRState.NOT_IN_XR);
             helper.dispose();
             throw e;
         });
@@ -110,7 +114,7 @@ export class WebXRExperienceHelper implements IDisposable {
         return this.sessionManager.isSessionSupportedAsync(sessionMode).then(() => {
             return this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);
         }).then(() => {
-            return this.sessionManager.setReferenceSpaceAsync(referenceSpaceType);
+            return this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);
         }).then(() => {
             return renderTarget.initializeXRLayerAsync(this.sessionManager.session);
         }).then(() => {
@@ -154,6 +158,7 @@ export class WebXRExperienceHelper implements IDisposable {
         }).catch((e: any) => {
             console.log(e);
             console.log(e.message);
+            this._setState(WebXRState.NOT_IN_XR);
             throw (e);
         });
     }

+ 53 - 7
src/Cameras/XR/webXRFeaturesManager.ts

@@ -10,12 +10,17 @@ export interface IWebXRFeature extends IDisposable {
      */
     attached: boolean;
     /**
+     * Should auto-attach be disabled?
+     */
+    disableAutoAttach: boolean;
+    /**
      * Attach the feature to the session
      * Will usually be called by the features manager
      *
+     * @param force should attachment be forced (even when already attached)
      * @returns true if successful.
      */
-    attach(): boolean;
+    attach(force?: boolean): boolean;
     /**
      * Detach the feature from the session
      * Will usually be called by the features manager
@@ -26,6 +31,36 @@ export interface IWebXRFeature extends IDisposable {
 }
 
 /**
+ * A list of the currently available features without referencing them
+ */
+export class WebXRFeatureName {
+    /**
+     * The name of the hit test feature
+     */
+    public static HIT_TEST = "xr-hit-test";
+    /**
+     * The name of the anchor system feature
+     */
+    public static ANCHOR_SYSTEM = "xr-anchor-system";
+    /**
+     * The name of the background remover feature
+     */
+    public static BACKGROUND_REMOVER = "xr-background-remover";
+    /**
+     * The name of the pointer selection feature
+     */
+    public static POINTER_SELECTION = "xr-controller-pointer-selection";
+    /**
+     * The name of the teleportation feature
+     */
+    public static TELEPORTATION = "xr-controller-teleportation";
+    /**
+     * The name of the plane detection feature
+     */
+    public static PLANE_DETECTION = "xr-plane-detection";
+}
+
+/**
  * Defining the constructor of a feature. Used to register the modules.
  */
 export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => IWebXRFeature);
@@ -139,7 +174,7 @@ export class WebXRFeaturesManager implements IDisposable {
         this._xrSessionManager.onXRSessionInit.add(() => {
             this.getEnabledFeatures().forEach((featureName) => {
                 const feature = this._features[featureName];
-                if (feature.enabled && !feature.featureImplementation.attached) {
+                if (feature.enabled && !feature.featureImplementation.attached && !feature.featureImplementation.disableAutoAttach) {
                     this.attachFeature(featureName);
                 }
             });
@@ -171,12 +206,18 @@ export class WebXRFeaturesManager implements IDisposable {
         const name = typeof featureName === 'string' ? featureName : featureName.Name;
         let versionToLoad = 0;
         if (typeof version === 'string') {
+            if (!version) {
+                throw new Error(`Error in provided version - ${name} (${version})`);
+            }
             if (version === 'stable') {
                 versionToLoad = WebXRFeaturesManager.GetStableVersionOfFeature(name);
             } else if (version === 'latest') {
                 versionToLoad = WebXRFeaturesManager.GetLatestVersionOfFeature(name);
+            } else {
+                // try loading the number the string represents
+                versionToLoad = +version;
             }
-            if (versionToLoad === -1) {
+            if (versionToLoad === -1 || isNaN(versionToLoad)) {
                 throw new Error(`feature not found - ${name} (${version})`);
             }
         } else {
@@ -201,10 +242,15 @@ export class WebXRFeaturesManager implements IDisposable {
             version: versionToLoad
         };
 
-        // if session started already, request and enable
-        if (this._xrSessionManager.session && !feature.featureImplementation.attached && attachIfPossible) {
-            // enable feature
-            this.attachFeature(name);
+        if (attachIfPossible) {
+            // if session started already, request and enable
+            if (this._xrSessionManager.session && !feature.featureImplementation.attached) {
+                // enable feature
+                this.attachFeature(name);
+            }
+        } else {
+            // disable auto-attach when session starts
+            this._features[name].featureImplementation.disableAutoAttach = true;
         }
 
         return this._features[name].featureImplementation;

+ 7 - 6
src/Cameras/XR/webXRSessionManager.ts

@@ -139,17 +139,18 @@ export class WebXRSessionManager implements IDisposable {
 
             // handle when the session is ended (By calling session.end or device ends its own session eg. pressing home button on phone)
             this.session.addEventListener("end", () => {
+                const engine = this.scene.getEngine();
                 this._sessionEnded = true;
                 // Remove render target texture and notify frame obervers
                 this._rttProvider = null;
 
                 // Restore frame buffer to avoid clear on xr framebuffer after session end
-                this.scene.getEngine().restoreDefaultFramebuffer();
+                engine.restoreDefaultFramebuffer();
 
                 // Need to restart render loop as after the session is ended the last request for new frame will never call callback
-                this.scene.getEngine().customAnimationFrameRequester = null;
+                engine.customAnimationFrameRequester = null;
                 this.onXRSessionEnded.notifyObservers(null);
-                this.scene.getEngine()._renderLoop();
+                engine._renderLoop();
             }, { once: true });
             return this.session;
         });
@@ -157,11 +158,11 @@ export class WebXRSessionManager implements IDisposable {
 
     /**
      * Sets the reference space on the xr session
-     * @param referenceSpace space to set
+     * @param referenceSpaceType space to set
      * @returns a promise that will resolve once the reference space has been set
      */
-    public setReferenceSpaceAsync(referenceSpace: XRReferenceSpaceType = "local-floor"): Promise<XRReferenceSpace> {
-        return this.session.requestReferenceSpace(referenceSpace).then((referenceSpace: XRReferenceSpace) => {
+    public setReferenceSpaceTypeAsync(referenceSpaceType: XRReferenceSpaceType = "local-floor"): Promise<XRReferenceSpace> {
+        return this.session.requestReferenceSpace(referenceSpaceType).then((referenceSpace: XRReferenceSpace) => {
             return referenceSpace;
         }, (rejectionReason) => {
             Logger.Error("XR.requestReferenceSpace failed for the following reason: ");