Преглед изворни кода

Merge pull request #7503 from BabylonJS/master

Nightly
David Catuhe пре 5 година
родитељ
комит
7e938302ba

+ 19 - 1
dist/preview release/babylon.d.ts

@@ -42583,7 +42583,7 @@ declare module BABYLON {
         /**
          * Checks if a session would be supported for the creation options specified
          * @param sessionMode session mode to check if supported eg. immersive-vr
-         * @returns true if supported
+         * @returns A Promise that resolves to true if supported and false if not
          */
         isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean>;
         /**
@@ -42620,6 +42620,11 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
+        /**
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
+         */
+        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -44501,6 +44506,12 @@ declare module BABYLON {
          * Should teleportation not initialize. defaults to false.
          */
         disableTeleportation?: boolean;
+        /**
+         * If set to true, the first frame will not be used to reset position
+         * The first frame is mainly used when copying transformation from the old camera
+         * Mainly used in AR
+         */
+        ignoreNativeCameraTransformation?: boolean;
     }
     /**
      * Default experience which provides a similar setup to the previous webVRExperience
@@ -45091,6 +45102,8 @@ declare module BABYLON {
     /**
      * A babylon interface for a webxr plane.
      * A Plane is actually a polygon, built from N points in space
+     *
+     * Supported in chrome 79, not supported in canary 81 ATM
      */
     export interface IWebXRPlane {
         /**
@@ -45149,6 +45162,7 @@ declare module BABYLON {
          * @param _options configuration to use when constructing this feature
          */
         constructor(_xrSessionManager: WebXRSessionManager, _options?: IWebXRPlaneDetectorOptions);
+        private _init;
         protected _onXRFrame(frame: XRFrame): void;
         /**
          * Dispose this feature and all of the resources attached
@@ -58186,6 +58200,10 @@ declare module BABYLON {
          * Gets the output component
          */
         get output(): NodeMaterialConnectionPoint;
+        /**
+         * Gets the isntanceID component
+         */
+        get instanceID(): NodeMaterialConnectionPoint;
         autoConfigure(material: NodeMaterial): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         protected _buildBlock(state: NodeMaterialBuildState): this;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.js


+ 66 - 17
dist/preview release/babylon.max.js

@@ -21780,17 +21780,26 @@ var WebXRPlaneDetector = /** @class */ (function (_super) {
         _this._detectedPlanes = [];
         _this._lastFrameDetected = new Set();
         if (_this._xrSessionManager.session) {
-            _this._xrSessionManager.session.updateWorldTrackingState({ planeDetectionState: { enabled: true } });
-            _this._enabled = true;
+            _this._init();
         }
         else {
             _this._xrSessionManager.onXRSessionInit.addOnce(function () {
-                _this._xrSessionManager.session.updateWorldTrackingState({ planeDetectionState: { enabled: true } });
-                _this._enabled = true;
+                _this._init();
             });
         }
         return _this;
     }
+    WebXRPlaneDetector.prototype._init = function () {
+        if (!this._xrSessionManager.session.updateWorldTrackingState) {
+            // fail silently
+            return;
+        }
+        this._xrSessionManager.session.updateWorldTrackingState({ planeDetectionState: { enabled: true } });
+        this._enabled = true;
+        if (this._detectedPlanes.length) {
+            this._detectedPlanes = [];
+        }
+    };
     WebXRPlaneDetector.prototype._onXRFrame = function (frame) {
         var _this = this;
         if (!this.attached || !this._enabled || !frame) {
@@ -23487,6 +23496,11 @@ var WebXRCamera = /** @class */ (function (_super) {
     function WebXRCamera(name, scene, _xrSessionManager) {
         var _this = _super.call(this, name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), scene) || this;
         _this._xrSessionManager = _xrSessionManager;
+        /**
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
+         */
+        _this.compensateOnFirstFrame = true;
         _this._firstFrame = false;
         _this._referencedPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]();
         _this._referenceQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Identity();
@@ -23502,7 +23516,7 @@ var WebXRCamera = /** @class */ (function (_super) {
             _this._referencedPosition.copyFromFloats(0, 0, 0);
             _this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);
             // first frame - camera's y position should be 0 for the correct offset
-            _this._firstFrame = true;
+            _this._firstFrame = _this.compensateOnFirstFrame;
         });
         // Check transformation changes on each frame. Callback is added to be first so that the transformation will be
         // applied to the rest of the elements using the referenceSpace object
@@ -23895,6 +23909,9 @@ var WebXRDefaultExperience = /** @class */ (function () {
         // Create base experience
         return _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_0__["WebXRExperienceHelper"].CreateAsync(scene).then(function (xrHelper) {
             result.baseExperience = xrHelper;
+            if (options.ignoreNativeCameraTransformation) {
+                result.baseExperience.camera.compensateOnFirstFrame = false;
+            }
             // Add controller support
             result.input = new _webXRInput__WEBPACK_IMPORTED_MODULE_1__["WebXRInput"](xrHelper.sessionManager, xrHelper.camera, options.inputOptions);
             result.pointerSelection = result.baseExperience.featuresManager.enableFeature(_features_WebXRControllerPointerSelection__WEBPACK_IMPORTED_MODULE_2__["WebXRControllerPointerSelection"].Name, "latest", {
@@ -24170,6 +24187,8 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _webXRCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webXRCamera */ "./Cameras/XR/webXRCamera.ts");
 /* harmony import */ var _webXRTypes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./webXRTypes */ "./Cameras/XR/webXRTypes.ts");
 /* harmony import */ var _webXRFeaturesManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./webXRFeaturesManager */ "./Cameras/XR/webXRFeaturesManager.ts");
+/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
+
 
 
 
@@ -24255,14 +24274,21 @@ var WebXRExperienceHelper = /** @class */ (function () {
         var _this = this;
         if (renderTarget === void 0) { renderTarget = this.sessionManager.getWebXRRenderTarget(); }
         if (!this._supported) {
-            throw "XR not available";
+            throw "WebXR not supported";
         }
         this._setState(_webXRTypes__WEBPACK_IMPORTED_MODULE_3__["WebXRState"].ENTERING_XR);
         var sessionCreationOptions = {
             optionalFeatures: (referenceSpaceType !== "viewer" && referenceSpaceType !== "local") ? [referenceSpaceType] : []
         };
+        // we currently recommend "local" space in AR
+        if (sessionMode === "immersive-ar" && referenceSpaceType !== "local") {
+            _Misc_logger__WEBPACK_IMPORTED_MODULE_5__["Logger"].Warn("We recommend using 'local' reference space type when using 'immersive-ar' session mode");
+        }
         // make sure that the session mode is supported
-        return this.sessionManager.isSessionSupportedAsync(sessionMode).then(function () {
+        return this.sessionManager.isSessionSupportedAsync(sessionMode).then(function (supported) {
+            if (!supported) {
+                throw new Error("Session mode \"" + sessionMode + "\" not supported in browser");
+            }
             return _this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);
         }).then(function () {
             return _this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);
@@ -24278,7 +24304,14 @@ var WebXRExperienceHelper = /** @class */ (function () {
             _this._nonVRCamera = _this.scene.activeCamera;
             // Overwrite current scene settings
             _this.scene.autoClear = false;
-            _this._nonXRToXRCamera();
+            _this.scene.activeCamera = _this.camera;
+            // do not compensate when AR session is used
+            if (sessionMode !== 'immersive-ar') {
+                _this._nonXRToXRCamera();
+            }
+            else {
+                _this.camera.compensateOnFirstFrame = false;
+            }
             _this.sessionManager.onXRSessionEnded.addOnce(function () {
                 // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends
                 _this.camera.rigCameras.forEach(function (c) {
@@ -24287,11 +24320,13 @@ var WebXRExperienceHelper = /** @class */ (function () {
                 // Restore scene settings
                 _this.scene.autoClear = _this._originalSceneAutoClear;
                 _this.scene.activeCamera = _this._nonVRCamera;
-                if (_this._nonVRCamera.setPosition) {
-                    _this._nonVRCamera.setPosition(_this.camera.position);
-                }
-                else {
-                    _this._nonVRCamera.position.copyFrom(_this.camera.position);
+                if (sessionMode !== 'immersive-ar' && _this.camera.compensateOnFirstFrame) {
+                    if (_this._nonVRCamera.setPosition) {
+                        _this._nonVRCamera.setPosition(_this.camera.position);
+                    }
+                    else {
+                        _this._nonVRCamera.position.copyFrom(_this.camera.position);
+                    }
                 }
                 _this._setState(_webXRTypes__WEBPACK_IMPORTED_MODULE_3__["WebXRState"].NOT_IN_XR);
             });
@@ -24320,7 +24355,6 @@ var WebXRExperienceHelper = /** @class */ (function () {
         }
     };
     WebXRExperienceHelper.prototype._nonXRToXRCamera = function () {
-        this.scene.activeCamera = this.camera;
         this.camera.setTransformationFromNonVRCamera(this._nonVRCamera);
         this.onInitialXRPoseSetObservable.notifyObservers(this.camera);
     };
@@ -25105,7 +25139,7 @@ var WebXRSessionManager = /** @class */ (function () {
     /**
      * Checks if a session would be supported for the creation options specified
      * @param sessionMode session mode to check if supported eg. immersive-vr
-     * @returns true if supported
+     * @returns A Promise that resolves to true if supported and false if not
      */
     WebXRSessionManager.prototype.isSessionSupportedAsync = function (sessionMode) {
         return WebXRSessionManager.IsSessionSupportedAsync(sessionMode);
@@ -25176,8 +25210,9 @@ var WebXRSessionManager = /** @class */ (function () {
             return Promise.resolve(false);
         }
         else {
-            return functionToUse.call(navigator.xr, sessionMode).then(function () {
-                return Promise.resolve(true);
+            return functionToUse.call(navigator.xr, sessionMode).then(function (result) {
+                var returnValue = (typeof result === "undefined") ? true : result;
+                return Promise.resolve(returnValue);
             }).catch(function (e) {
                 _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn(e);
                 return Promise.resolve(false);
@@ -70044,6 +70079,7 @@ var InstancesBlock = /** @class */ (function (_super) {
         _this.registerInput("world3", _Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4);
         _this.registerInput("world", _Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Matrix, true);
         _this.registerOutput("output", _Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Matrix);
+        _this.registerOutput("instanceID", _Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Float);
         return _this;
     }
     /**
@@ -70113,6 +70149,16 @@ var InstancesBlock = /** @class */ (function (_super) {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(InstancesBlock.prototype, "instanceID", {
+        /**
+         * Gets the isntanceID component
+         */
+        get: function () {
+            return this._outputs[1];
+        },
+        enumerable: true,
+        configurable: true
+    });
     InstancesBlock.prototype.autoConfigure = function (material) {
         if (!this.world0.connectedPoint) {
             var world0Input = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "world0"; });
@@ -70173,14 +70219,17 @@ var InstancesBlock = /** @class */ (function (_super) {
         state.sharedData.blocksWithDefines.push(this);
         // Emit code
         var output = this._outputs[0];
+        var instanceID = this._outputs[1];
         var world0 = this.world0;
         var world1 = this.world1;
         var world2 = this.world2;
         var world3 = this.world3;
         state.compilationString += "#ifdef INSTANCES\r\n";
         state.compilationString += this._declareOutput(output, state) + (" = mat4(" + world0.associatedVariableName + ", " + world1.associatedVariableName + ", " + world2.associatedVariableName + ", " + world3.associatedVariableName + ");\r\n");
+        state.compilationString += this._declareOutput(instanceID, state) + " = float(gl_InstanceID);\r\n";
         state.compilationString += "#else\r\n";
         state.compilationString += this._declareOutput(output, state) + (" = " + this.world.associatedVariableName + ";\r\n");
+        state.compilationString += this._declareOutput(instanceID, state) + " = 0.0;\r\n";
         state.compilationString += "#endif\r\n";
         return this;
     };

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 38 - 2
dist/preview release/babylon.module.d.ts

@@ -44065,7 +44065,7 @@ declare module "babylonjs/Cameras/XR/webXRSessionManager" {
         /**
          * Checks if a session would be supported for the creation options specified
          * @param sessionMode session mode to check if supported eg. immersive-vr
-         * @returns true if supported
+         * @returns A Promise that resolves to true if supported and false if not
          */
         isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean>;
         /**
@@ -44106,6 +44106,11 @@ declare module "babylonjs/Cameras/XR/webXRCamera" {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
+        /**
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
+         */
+        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -46063,6 +46068,12 @@ declare module "babylonjs/Cameras/XR/webXRDefaultExperience" {
          * Should teleportation not initialize. defaults to false.
          */
         disableTeleportation?: boolean;
+        /**
+         * If set to true, the first frame will not be used to reset position
+         * The first frame is mainly used when copying transformation from the old camera
+         * Mainly used in AR
+         */
+        ignoreNativeCameraTransformation?: boolean;
     }
     /**
      * Default experience which provides a similar setup to the previous webVRExperience
@@ -46692,6 +46703,8 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
     /**
      * A babylon interface for a webxr plane.
      * A Plane is actually a polygon, built from N points in space
+     *
+     * Supported in chrome 79, not supported in canary 81 ATM
      */
     export interface IWebXRPlane {
         /**
@@ -46750,6 +46763,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
          * @param _options configuration to use when constructing this feature
          */
         constructor(_xrSessionManager: WebXRSessionManager, _options?: IWebXRPlaneDetectorOptions);
+        private _init;
         protected _onXRFrame(frame: XRFrame): void;
         /**
          * Dispose this feature and all of the resources attached
@@ -60934,6 +60948,10 @@ declare module "babylonjs/Materials/Node/Blocks/Vertex/instancesBlock" {
          * Gets the output component
          */
         get output(): NodeMaterialConnectionPoint;
+        /**
+         * Gets the isntanceID component
+         */
+        get instanceID(): NodeMaterialConnectionPoint;
         autoConfigure(material: NodeMaterial): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         protected _buildBlock(state: NodeMaterialBuildState): this;
@@ -115081,7 +115099,7 @@ declare module BABYLON {
         /**
          * Checks if a session would be supported for the creation options specified
          * @param sessionMode session mode to check if supported eg. immersive-vr
-         * @returns true if supported
+         * @returns A Promise that resolves to true if supported and false if not
          */
         isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean>;
         /**
@@ -115118,6 +115136,11 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
+        /**
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
+         */
+        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -116999,6 +117022,12 @@ declare module BABYLON {
          * Should teleportation not initialize. defaults to false.
          */
         disableTeleportation?: boolean;
+        /**
+         * If set to true, the first frame will not be used to reset position
+         * The first frame is mainly used when copying transformation from the old camera
+         * Mainly used in AR
+         */
+        ignoreNativeCameraTransformation?: boolean;
     }
     /**
      * Default experience which provides a similar setup to the previous webVRExperience
@@ -117589,6 +117618,8 @@ declare module BABYLON {
     /**
      * A babylon interface for a webxr plane.
      * A Plane is actually a polygon, built from N points in space
+     *
+     * Supported in chrome 79, not supported in canary 81 ATM
      */
     export interface IWebXRPlane {
         /**
@@ -117647,6 +117678,7 @@ declare module BABYLON {
          * @param _options configuration to use when constructing this feature
          */
         constructor(_xrSessionManager: WebXRSessionManager, _options?: IWebXRPlaneDetectorOptions);
+        private _init;
         protected _onXRFrame(frame: XRFrame): void;
         /**
          * Dispose this feature and all of the resources attached
@@ -130684,6 +130716,10 @@ declare module BABYLON {
          * Gets the output component
          */
         get output(): NodeMaterialConnectionPoint;
+        /**
+         * Gets the isntanceID component
+         */
+        get instanceID(): NodeMaterialConnectionPoint;
         autoConfigure(material: NodeMaterial): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         protected _buildBlock(state: NodeMaterialBuildState): this;

+ 19 - 1
dist/preview release/documentation.d.ts

@@ -42583,7 +42583,7 @@ declare module BABYLON {
         /**
          * Checks if a session would be supported for the creation options specified
          * @param sessionMode session mode to check if supported eg. immersive-vr
-         * @returns true if supported
+         * @returns A Promise that resolves to true if supported and false if not
          */
         isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean>;
         /**
@@ -42620,6 +42620,11 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
+        /**
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
+         */
+        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -44501,6 +44506,12 @@ declare module BABYLON {
          * Should teleportation not initialize. defaults to false.
          */
         disableTeleportation?: boolean;
+        /**
+         * If set to true, the first frame will not be used to reset position
+         * The first frame is mainly used when copying transformation from the old camera
+         * Mainly used in AR
+         */
+        ignoreNativeCameraTransformation?: boolean;
     }
     /**
      * Default experience which provides a similar setup to the previous webVRExperience
@@ -45091,6 +45102,8 @@ declare module BABYLON {
     /**
      * A babylon interface for a webxr plane.
      * A Plane is actually a polygon, built from N points in space
+     *
+     * Supported in chrome 79, not supported in canary 81 ATM
      */
     export interface IWebXRPlane {
         /**
@@ -45149,6 +45162,7 @@ declare module BABYLON {
          * @param _options configuration to use when constructing this feature
          */
         constructor(_xrSessionManager: WebXRSessionManager, _options?: IWebXRPlaneDetectorOptions);
+        private _init;
         protected _onXRFrame(frame: XRFrame): void;
         /**
          * Dispose this feature and all of the resources attached
@@ -58186,6 +58200,10 @@ declare module BABYLON {
          * Gets the output component
          */
         get output(): NodeMaterialConnectionPoint;
+        /**
+         * Gets the isntanceID component
+         */
+        get instanceID(): NodeMaterialConnectionPoint;
         autoConfigure(material: NodeMaterial): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         protected _buildBlock(state: NodeMaterialBuildState): this;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


+ 2 - 0
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -46155,6 +46155,8 @@ var TexturePropertyGridComponent = /** @class */ (function (_super) {
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Is 2D array", value: texture.is2DArray ? "Yes" : "No" }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Is cube", value: texture.isCube ? "Yes" : "No" }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Is render target", value: texture.isRenderTarget ? "Yes" : "No" }),
+                (texture instanceof babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Texture"]) &&
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Stored as inverted on Y", value: texture.invertY ? "Yes" : "No" }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Has mipmaps", value: !texture.noMipmap ? "Yes" : "No" }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_4__["SliderLineComponent"], { label: "UV set", target: texture, propertyName: "coordinatesIndex", minimum: 0, maximum: 3, step: 1, onPropertyChangedObservable: this.props.onPropertyChangedObservable, decimalCount: 0 }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_9__["OptionsLineComponent"], { label: "Mode", options: coordinatesMode, target: texture, propertyName: "coordinatesMode", onPropertyChangedObservable: this.props.onPropertyChangedObservable, onSelect: function (value) { return texture.updateSamplingMode(value); } }),

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 38 - 2
dist/preview release/viewer/babylon.module.d.ts

@@ -44065,7 +44065,7 @@ declare module "babylonjs/Cameras/XR/webXRSessionManager" {
         /**
          * Checks if a session would be supported for the creation options specified
          * @param sessionMode session mode to check if supported eg. immersive-vr
-         * @returns true if supported
+         * @returns A Promise that resolves to true if supported and false if not
          */
         isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean>;
         /**
@@ -44106,6 +44106,11 @@ declare module "babylonjs/Cameras/XR/webXRCamera" {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
+        /**
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
+         */
+        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -46063,6 +46068,12 @@ declare module "babylonjs/Cameras/XR/webXRDefaultExperience" {
          * Should teleportation not initialize. defaults to false.
          */
         disableTeleportation?: boolean;
+        /**
+         * If set to true, the first frame will not be used to reset position
+         * The first frame is mainly used when copying transformation from the old camera
+         * Mainly used in AR
+         */
+        ignoreNativeCameraTransformation?: boolean;
     }
     /**
      * Default experience which provides a similar setup to the previous webVRExperience
@@ -46692,6 +46703,8 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
     /**
      * A babylon interface for a webxr plane.
      * A Plane is actually a polygon, built from N points in space
+     *
+     * Supported in chrome 79, not supported in canary 81 ATM
      */
     export interface IWebXRPlane {
         /**
@@ -46750,6 +46763,7 @@ declare module "babylonjs/Cameras/XR/features/WebXRPlaneDetector" {
          * @param _options configuration to use when constructing this feature
          */
         constructor(_xrSessionManager: WebXRSessionManager, _options?: IWebXRPlaneDetectorOptions);
+        private _init;
         protected _onXRFrame(frame: XRFrame): void;
         /**
          * Dispose this feature and all of the resources attached
@@ -60934,6 +60948,10 @@ declare module "babylonjs/Materials/Node/Blocks/Vertex/instancesBlock" {
          * Gets the output component
          */
         get output(): NodeMaterialConnectionPoint;
+        /**
+         * Gets the isntanceID component
+         */
+        get instanceID(): NodeMaterialConnectionPoint;
         autoConfigure(material: NodeMaterial): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         protected _buildBlock(state: NodeMaterialBuildState): this;
@@ -115081,7 +115099,7 @@ declare module BABYLON {
         /**
          * Checks if a session would be supported for the creation options specified
          * @param sessionMode session mode to check if supported eg. immersive-vr
-         * @returns true if supported
+         * @returns A Promise that resolves to true if supported and false if not
          */
         isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean>;
         /**
@@ -115118,6 +115136,11 @@ declare module BABYLON {
      */
     export class WebXRCamera extends FreeCamera {
         private _xrSessionManager;
+        /**
+         * Should position compensation execute on first frame.
+         * This is used when copying the position from a native (non XR) camera
+         */
+        compensateOnFirstFrame: boolean;
         private _firstFrame;
         private _referencedPosition;
         private _referenceQuaternion;
@@ -116999,6 +117022,12 @@ declare module BABYLON {
          * Should teleportation not initialize. defaults to false.
          */
         disableTeleportation?: boolean;
+        /**
+         * If set to true, the first frame will not be used to reset position
+         * The first frame is mainly used when copying transformation from the old camera
+         * Mainly used in AR
+         */
+        ignoreNativeCameraTransformation?: boolean;
     }
     /**
      * Default experience which provides a similar setup to the previous webVRExperience
@@ -117589,6 +117618,8 @@ declare module BABYLON {
     /**
      * A babylon interface for a webxr plane.
      * A Plane is actually a polygon, built from N points in space
+     *
+     * Supported in chrome 79, not supported in canary 81 ATM
      */
     export interface IWebXRPlane {
         /**
@@ -117647,6 +117678,7 @@ declare module BABYLON {
          * @param _options configuration to use when constructing this feature
          */
         constructor(_xrSessionManager: WebXRSessionManager, _options?: IWebXRPlaneDetectorOptions);
+        private _init;
         protected _onXRFrame(frame: XRFrame): void;
         /**
          * Dispose this feature and all of the resources attached
@@ -130684,6 +130716,10 @@ declare module BABYLON {
          * Gets the output component
          */
         get output(): NodeMaterialConnectionPoint;
+        /**
+         * Gets the isntanceID component
+         */
+        get instanceID(): NodeMaterialConnectionPoint;
         autoConfigure(material: NodeMaterial): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         protected _buildBlock(state: NodeMaterialBuildState): this;

Разлика између датотеке није приказан због своје велике величине
+ 6 - 6
dist/preview release/viewer/babylon.viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -199,7 +199,7 @@
 - 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/))
 - It is now possible to force a certain profile type for the controllers ([#7348](https://github.com/BabylonJS/Babylon.js/issues/7375)) ([RaananW](https://github.com/RaananW/))
-- WebXR camera is initialized on the first frame ([#7389](https://github.com/BabylonJS/Babylon.js/issues/7389)) ([RaananW](https://github.com/RaananW/))
+- WebXR camera is initialized on the first frame, including copying transformation from native camera (except for in AR) ([#7389](https://github.com/BabylonJS/Babylon.js/issues/7389)) ([RaananW](https://github.com/RaananW/))
 - Selection has gaze mode (which can be forced) and touch-screen support ([#7395](https://github.com/BabylonJS/Babylon.js/issues/7395)) ([RaananW](https://github.com/RaananW/))
 - Laser pointers can be excluded from lighting influence so that they are always visible in both WebXR and WebVR ([#7323](https://github.com/BabylonJS/Babylon.js/issues/7323)) ([RaananW](https://github.com/RaananW/))
 
@@ -301,6 +301,7 @@
 - Disposing of the depthReducer used in CSM ([Popov72](https://github.com/Popov72))
 - Fixed an issue with teleportation detach and attach ([#7419](https://github.com/BabylonJS/Babylon.js/issues/7419)) ([RaananW](https://github.com/RaananW/))
 - Physics compound calculations were incorrect ([#7407](https://github.com/BabylonJS/Babylon.js/issues/7407)) ([RaananW](https://github.com/RaananW/))
+- Fixed an issue with isSessionSupported return value being ignored ([#7501](https://github.com/BabylonJS/Babylon.js/issues/7501)) ([RaananW](https://github.com/RaananW/))
 
 ## Breaking changes
 

+ 4 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/materials/texturePropertyGridComponent.tsx

@@ -172,6 +172,10 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
                     <TextLineComponent label="Is 2D array" value={texture.is2DArray ? "Yes" : "No"} />
                     <TextLineComponent label="Is cube" value={texture.isCube ? "Yes" : "No"} />
                     <TextLineComponent label="Is render target" value={texture.isRenderTarget ? "Yes" : "No"} />
+                    {
+                        (texture instanceof Texture) && 
+                        <TextLineComponent label="Stored as inverted on Y" value={texture.invertY ? "Yes" : "No"} />
+                    }
                     <TextLineComponent label="Has mipmaps" value={!texture.noMipmap ? "Yes" : "No"} />
                     <SliderLineComponent label="UV set" target={texture} propertyName="coordinatesIndex" minimum={0} maximum={3} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} decimalCount={0} />
                     <OptionsLineComponent label="Mode" options={coordinatesMode} target={texture} propertyName="coordinatesMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={(value) => texture.updateSamplingMode(value)} />

+ 16 - 4
src/Cameras/XR/features/WebXRPlaneDetector.ts

@@ -18,6 +18,8 @@ export interface IWebXRPlaneDetectorOptions {
 /**
  * A babylon interface for a webxr plane.
  * A Plane is actually a polygon, built from N points in space
+ *
+ * Supported in chrome 79, not supported in canary 81 ATM
  */
 export interface IWebXRPlane {
     /**
@@ -84,16 +86,26 @@ export class WebXRPlaneDetector extends WebXRAbstractFeature {
     constructor(_xrSessionManager: WebXRSessionManager, private _options: IWebXRPlaneDetectorOptions = {}) {
         super(_xrSessionManager);
         if (this._xrSessionManager.session) {
-            this._xrSessionManager.session.updateWorldTrackingState({ planeDetectionState: { enabled: true } });
-            this._enabled = true;
+            this._init();
         } else {
             this._xrSessionManager.onXRSessionInit.addOnce(() => {
-                this._xrSessionManager.session.updateWorldTrackingState({ planeDetectionState: { enabled: true } });
-                this._enabled = true;
+                this._init();
             });
         }
     }
 
+    private _init() {
+        if (!this._xrSessionManager.session.updateWorldTrackingState) {
+            // fail silently
+            return;
+        }
+        this._xrSessionManager.session.updateWorldTrackingState({ planeDetectionState: { enabled: true } });
+        this._enabled = true;
+        if (this._detectedPlanes.length) {
+            this._detectedPlanes = [];
+        }
+    }
+
     protected _onXRFrame(frame: XRFrame) {
         if (!this.attached || !this._enabled || !frame) { return; }
         // const timestamp = this.xrSessionManager.currentTimestamp;

+ 7 - 1
src/Cameras/XR/webXRCamera.ts

@@ -12,6 +12,12 @@ import { Viewport } from '../../Maths/math.viewport';
  */
 export class WebXRCamera extends FreeCamera {
 
+    /**
+     * Should position compensation execute on first frame.
+     * This is used when copying the position from a native (non XR) camera
+     */
+    public compensateOnFirstFrame: boolean = true;
+
     private _firstFrame = false;
     private _referencedPosition: Vector3 = new Vector3();
     private _referenceQuaternion: Quaternion = Quaternion.Identity();
@@ -37,7 +43,7 @@ export class WebXRCamera extends FreeCamera {
             this._referencedPosition.copyFromFloats(0, 0, 0);
             this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);
             // first frame - camera's y position should be 0 for the correct offset
-            this._firstFrame = true;
+            this._firstFrame = this.compensateOnFirstFrame;
 
         });
 

+ 11 - 0
src/Cameras/XR/webXRDefaultExperience.ts

@@ -42,6 +42,13 @@ export class WebXRDefaultExperienceOptions {
      * Should teleportation not initialize. defaults to false.
      */
     public disableTeleportation?: boolean;
+
+    /**
+     * If set to true, the first frame will not be used to reset position
+     * The first frame is mainly used when copying transformation from the old camera
+     * Mainly used in AR
+     */
+    public ignoreNativeCameraTransformation?: boolean;
 }
 
 /**
@@ -86,6 +93,10 @@ export class WebXRDefaultExperience {
         return WebXRExperienceHelper.CreateAsync(scene).then((xrHelper) => {
             result.baseExperience = xrHelper;
 
+            if (options.ignoreNativeCameraTransformation) {
+                result.baseExperience.camera.compensateOnFirstFrame = false;
+            }
+
             // Add controller support
             result.input = new WebXRInput(xrHelper.sessionManager, xrHelper.camera, options.inputOptions);
             result.pointerSelection = <WebXRControllerPointerSelection>result.baseExperience.featuresManager.enableFeature(WebXRControllerPointerSelection.Name, "latest", {

+ 23 - 8
src/Cameras/XR/webXRExperienceHelper.ts

@@ -6,6 +6,7 @@ import { WebXRSessionManager } from "./webXRSessionManager";
 import { WebXRCamera } from "./webXRCamera";
 import { WebXRState, WebXRRenderTarget } from './webXRTypes';
 import { WebXRFeaturesManager } from './webXRFeaturesManager';
+import { Logger } from '../../Misc/logger';
 
 /**
  * Base set of functionality needed to create an XR experince (WebXRSessionManager, Camera, StateManagement, etc.)
@@ -104,14 +105,21 @@ export class WebXRExperienceHelper implements IDisposable {
      */
     public enterXRAsync(sessionMode: XRSessionMode, referenceSpaceType: XRReferenceSpaceType, renderTarget: WebXRRenderTarget = this.sessionManager.getWebXRRenderTarget()): Promise<WebXRSessionManager> {
         if (!this._supported) {
-            throw "XR not available";
+            throw "WebXR not supported";
         }
         this._setState(WebXRState.ENTERING_XR);
         let sessionCreationOptions: XRSessionInit = {
             optionalFeatures: (referenceSpaceType !== "viewer" && referenceSpaceType !== "local") ? [referenceSpaceType] : []
         };
+        // we currently recommend "local" space in AR
+        if (sessionMode === "immersive-ar" && referenceSpaceType !== "local") {
+            Logger.Warn("We recommend using 'local' reference space type when using 'immersive-ar' session mode");
+        }
         // make sure that the session mode is supported
-        return this.sessionManager.isSessionSupportedAsync(sessionMode).then(() => {
+        return this.sessionManager.isSessionSupportedAsync(sessionMode).then((supported) => {
+            if (!supported) {
+                throw new Error(`Session mode "${sessionMode}" not supported in browser`);
+            }
             return this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);
         }).then(() => {
             return this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);
@@ -129,7 +137,13 @@ export class WebXRExperienceHelper implements IDisposable {
             // Overwrite current scene settings
             this.scene.autoClear = false;
 
-            this._nonXRToXRCamera();
+            this.scene.activeCamera = this.camera;
+            // do not compensate when AR session is used
+            if (sessionMode !== 'immersive-ar') {
+                this._nonXRToXRCamera();
+            } else {
+                this.camera.compensateOnFirstFrame = false;
+            }
 
             this.sessionManager.onXRSessionEnded.addOnce(() => {
                 // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends
@@ -140,10 +154,12 @@ export class WebXRExperienceHelper implements IDisposable {
                 // Restore scene settings
                 this.scene.autoClear = this._originalSceneAutoClear;
                 this.scene.activeCamera = this._nonVRCamera;
-                if ((<any>this._nonVRCamera).setPosition) {
-                    (<any>this._nonVRCamera).setPosition(this.camera.position);
-                } else {
-                    this._nonVRCamera!.position.copyFrom(this.camera.position);
+                if (sessionMode !== 'immersive-ar' && this.camera.compensateOnFirstFrame) {
+                    if ((<any>this._nonVRCamera).setPosition) {
+                        (<any>this._nonVRCamera).setPosition(this.camera.position);
+                    } else {
+                        this._nonVRCamera!.position.copyFrom(this.camera.position);
+                    }
                 }
 
                 this._setState(WebXRState.NOT_IN_XR);
@@ -177,7 +193,6 @@ export class WebXRExperienceHelper implements IDisposable {
     }
 
     private _nonXRToXRCamera() {
-        this.scene.activeCamera = this.camera;
         this.camera.setTransformationFromNonVRCamera(this._nonVRCamera!);
         this.onInitialXRPoseSetObservable.notifyObservers(this.camera);
     }

+ 5 - 4
src/Cameras/XR/webXRSessionManager.ts

@@ -268,9 +268,9 @@ export class WebXRSessionManager implements IDisposable {
     /**
      * Checks if a session would be supported for the creation options specified
      * @param sessionMode session mode to check if supported eg. immersive-vr
-     * @returns true if supported
+     * @returns A Promise that resolves to true if supported and false if not
      */
-    public isSessionSupportedAsync(sessionMode: XRSessionMode) {
+    public isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean> {
         return WebXRSessionManager.IsSessionSupportedAsync(sessionMode);
     }
 
@@ -344,8 +344,9 @@ export class WebXRSessionManager implements IDisposable {
         if (!functionToUse) {
             return Promise.resolve(false);
         } else {
-            return functionToUse.call((navigator as any).xr, sessionMode).then(() => {
-                return Promise.resolve(true);
+            return functionToUse.call((navigator as any).xr, sessionMode).then((result: boolean) => {
+                const returnValue = (typeof result === "undefined") ? true : result;
+                return Promise.resolve(returnValue);
             }).catch((e: any) => {
                 Logger.Warn(e);
                 return Promise.resolve(false);

+ 11 - 0
src/Materials/Node/Blocks/Vertex/instancesBlock.ts

@@ -28,6 +28,7 @@ export class InstancesBlock extends NodeMaterialBlock {
         this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix, true);
 
         this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Matrix);
+        this.registerOutput("instanceID", NodeMaterialBlockConnectionPointTypes.Float);
     }
 
     /**
@@ -80,6 +81,13 @@ export class InstancesBlock extends NodeMaterialBlock {
         return this._outputs[0];
     }
 
+    /**
+     * Gets the isntanceID component
+     */
+    public get instanceID(): NodeMaterialConnectionPoint {
+        return this._outputs[1];
+    }
+
     public autoConfigure(material: NodeMaterial) {
         if (!this.world0.connectedPoint) {
             let world0Input = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === "world0");
@@ -150,6 +158,7 @@ export class InstancesBlock extends NodeMaterialBlock {
 
         // Emit code
         let output = this._outputs[0];
+        let instanceID = this._outputs[1];
         let world0 = this.world0;
         let world1 = this.world1;
         let world2 = this.world2;
@@ -157,8 +166,10 @@ export class InstancesBlock extends NodeMaterialBlock {
 
         state.compilationString += `#ifdef INSTANCES\r\n`;
         state.compilationString += this._declareOutput(output, state) + ` = mat4(${world0.associatedVariableName}, ${world1.associatedVariableName}, ${world2.associatedVariableName}, ${world3.associatedVariableName});\r\n`;
+        state.compilationString += this._declareOutput(instanceID, state) + ` = float(gl_InstanceID);\r\n`;
         state.compilationString += `#else\r\n`;
         state.compilationString += this._declareOutput(output, state) + ` = ${this.world.associatedVariableName};\r\n`;
+        state.compilationString += this._declareOutput(instanceID, state) + ` = 0.0;\r\n`;
         state.compilationString += `#endif\r\n`;
         return this;
     }