David Catuhe 4 éve
szülő
commit
3857078ee6

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

@@ -12,6 +12,10 @@
 
 - Added support for EXT_meshopt_compression for glTF loader. ([zeux](https://github.com/zeux))
 
+### Navigation
+
+- Added support for thin instances in navigation mesh creation ([CedricGuillemet](https://github.com/CedricGuillemet))
+
 ### Materials
 
 - Added an `OcclusionMaterial` to simplify depth-only rendering of geometry ([rgerd](https://github.com/rgerd))
@@ -25,6 +29,10 @@
 - Added a `FocusableButton` gui control to simplify creating menus with keyboard navigation ([Flux159](https://github.com/Flux159))
 - Added `focus()` and `blur()` functions for controls that implement `IFocusableControl` ([Flux159](https://github.com/Flux159))
 
+### WebXR
+
+- A browser error preventing the emulator to render scene is now correctly dealt with ([RaananW](https://github.com/RaananW))
+
 ## Bugs
 
 - Fix issue with the Promise polyfill where a return value was expected from resolve() ([Deltakosh](https://github.com/deltakosh))

+ 29 - 13
src/Navigation/Plugins/recastJSPlugin.ts

@@ -3,7 +3,7 @@ import { Logger } from "../../Misc/logger";
 import { VertexData } from "../../Meshes/mesh.vertexData";
 import { Mesh } from "../../Meshes/mesh";
 import { Scene } from "../../scene";
-import { Epsilon, Vector3 } from '../../Maths/math';
+import { Epsilon, Vector3, Matrix } from '../../Maths/math';
 import { TransformNode } from "../../Meshes/transformNode";
 import { Observer } from "../../Misc/observable";
 import { Nullable } from "../../types";
@@ -134,21 +134,37 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
                     continue;
                 }
 
-                const wm = mesh.computeWorldMatrix(true);
-
-                for (tri = 0; tri < meshIndices.length; tri++) {
-                    indices.push(meshIndices[tri] + offset);
+                var worldMatrices = [];
+                const worldMatrix = mesh.computeWorldMatrix(true);
+
+                if (mesh.hasThinInstances) {
+                    let thinMatrices = (mesh as Mesh).thinInstanceGetWorldMatrices();
+                    for (let instanceIndex = 0; instanceIndex < thinMatrices.length; instanceIndex++) {
+                        const tmpMatrix = new Matrix();
+                        let thinMatrix = thinMatrices[instanceIndex];
+                        thinMatrix.multiplyToRef(worldMatrix, tmpMatrix);
+                        worldMatrices.push(tmpMatrix);
+                    }
+                } else {
+                    worldMatrices.push(worldMatrix);
                 }
 
-                var transformed = Vector3.Zero();
-                var position = Vector3.Zero();
-                for (pt = 0; pt < meshPositions.length; pt += 3) {
-                    Vector3.FromArrayToRef(meshPositions, pt, position);
-                    Vector3.TransformCoordinatesToRef(position, wm, transformed);
-                    positions.push(transformed.x, transformed.y, transformed.z);
+                for (let matrixIndex = 0; matrixIndex < worldMatrices.length; matrixIndex ++) {
+                    const wm = worldMatrices[matrixIndex];
+                    for (tri = 0; tri < meshIndices.length; tri++) {
+                        indices.push(meshIndices[tri] + offset);
+                    }
+
+                    var transformed = Vector3.Zero();
+                    var position = Vector3.Zero();
+                    for (pt = 0; pt < meshPositions.length; pt += 3) {
+                        Vector3.FromArrayToRef(meshPositions, pt, position);
+                        Vector3.TransformCoordinatesToRef(position, wm, transformed);
+                        positions.push(transformed.x, transformed.y, transformed.z);
+                    }
+
+                    offset += meshPositions.length / 3;
                 }
-
-                offset += meshPositions.length / 3;
             }
         }
 

+ 16 - 6
src/Probes/reflectionProbe.ts

@@ -118,10 +118,10 @@ export class ReflectionProbe {
                     this._add.copyFromFloats(0, this._invertYAxis ? -1 : 1, 0);
                     break;
                 case 4:
-                    this._add.copyFromFloats(0, 0, 1);
+                    this._add.copyFromFloats(0, 0, scene.useRightHandedSystem ? -1 : 1);
                     break;
                 case 5:
-                    this._add.copyFromFloats(0, 0, -1);
+                    this._add.copyFromFloats(0, 0, scene.useRightHandedSystem ? 1 : -1);
                     break;
 
             }
@@ -132,11 +132,21 @@ export class ReflectionProbe {
 
             this.position.addToRef(this._add, this._target);
 
-            Matrix.LookAtLHToRef(this.position, this._target, Vector3.Up(), this._viewMatrix);
+            if (scene.useRightHandedSystem) {
+                Matrix.LookAtRHToRef(this.position, this._target, Vector3.Up(), this._viewMatrix);
 
-            if (scene.activeCamera) {
-                this._projectionMatrix = Matrix.PerspectiveFovLH(Math.PI / 2, 1, scene.activeCamera.minZ, scene.activeCamera.maxZ);
-                scene.setTransformMatrix(this._viewMatrix, this._projectionMatrix);
+                if (scene.activeCamera) {
+                    this._projectionMatrix = Matrix.PerspectiveFovRH(Math.PI / 2, 1, scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                    scene.setTransformMatrix(this._viewMatrix, this._projectionMatrix);
+                }
+            }
+            else  {
+                Matrix.LookAtLHToRef(this.position, this._target, Vector3.Up(), this._viewMatrix);
+
+                if (scene.activeCamera) {
+                    this._projectionMatrix = Matrix.PerspectiveFovLH(Math.PI / 2, 1, scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                    scene.setTransformMatrix(this._viewMatrix, this._projectionMatrix);
+                }
             }
 
             scene._forcedViewPosition = this.position;

+ 17 - 0
src/XR/features/WebXRHandTracking.ts

@@ -135,6 +135,11 @@ export class WebXRHand implements IDisposable {
     public handPartsDefinition: { [key: string]: number[] };
 
     /**
+     * Observers will be triggered when the mesh for this hand was initialized.
+     */
+    public onHandMeshReadyObservable: Observable<WebXRHand> = new Observable();
+
+    /**
      * Populate the HandPartsDefinition object.
      * This is called as a side effect since certain browsers don't have XRHand defined.
      */
@@ -170,6 +175,7 @@ export class WebXRHand implements IDisposable {
         this._scene = trackedMeshes[0].getScene();
         if (this._handMesh && this._rigMapping) {
             this._defaultHandMesh = false;
+            this.onHandMeshReadyObservable.notifyObservers(this);
         } else {
             if (!disableDefaultHandMesh) {
                 this._generateDefaultHandMesh();
@@ -202,6 +208,13 @@ export class WebXRHand implements IDisposable {
     }
 
     /**
+     * Get the hand mesh. It is possible that the hand mesh is not yet ready!
+     */
+    public get handMesh() {
+        return this._handMesh;
+    }
+
+    /**
      * Update this hand from the latest xr frame
      * @param xrFrame xrFrame to update from
      * @param referenceSpace The current viewer reference space
@@ -265,6 +278,7 @@ export class WebXRHand implements IDisposable {
      */
     public dispose() {
         this.trackedMeshes.forEach((mesh) => mesh.dispose());
+        this.onHandMeshReadyObservable.clear();
         // dispose the hand mesh, if it is the default one
         if (this._defaultHandMesh && this._handMesh) {
             this._handMesh.dispose();
@@ -307,6 +321,7 @@ export class WebXRHand implements IDisposable {
             handNodes.tipFresnel.value = handColors.tipFresnel;
 
             loaded.meshes[1].material = handShader;
+            loaded.meshes[1].alwaysSelectAsActiveMesh = true;
 
             this._defaultHandMesh = true;
             this._handMesh = loaded.meshes[0];
@@ -344,6 +359,7 @@ export class WebXRHand implements IDisposable {
             } else {
                 tm.parent && (tm.parent as AbstractMesh).rotate(Axis.Y, Math.PI);
             }
+            this.onHandMeshReadyObservable.notifyObservers(this);
         } catch (e) {
             Tools.Error("error loading hand mesh");
             console.log(e);
@@ -492,6 +508,7 @@ export class WebXRHandTracking extends WebXRAbstractFeature {
         const hand = xrController.inputSource.hand;
         const trackedMeshes: AbstractMesh[] = [];
         const originalMesh = this.options.jointMeshes?.sourceMesh || SphereBuilder.CreateSphere("jointParent", { diameter: 1 });
+        originalMesh.scaling.set(0.01, 0.01, 0.01);
         originalMesh.isVisible = !!this.options.jointMeshes?.keepOriginalVisible;
         for (let i = 0; i < hand.length; ++i) {
             let newInstance: AbstractMesh = originalMesh.createInstance(`${xrController.uniqueId}-handJoint-${i}`);

+ 15 - 4
src/XR/webXRManagedOutputCanvas.ts

@@ -3,6 +3,7 @@ import { ThinEngine } from "../Engines/thinEngine";
 import { WebXRRenderTarget } from "./webXRTypes";
 import { WebXRSessionManager } from "./webXRSessionManager";
 import { Observable } from "../Misc/observable";
+import { Tools } from "../Misc/tools";
 
 /**
  * COnfiguration object for WebXR output canvas
@@ -118,10 +119,20 @@ export class WebXRManagedOutputCanvas implements WebXRRenderTarget {
             return Promise.resolve(this.xrLayer);
         }
 
-        return (this.canvasContext as any).makeXRCompatible().then(() => {
-            this.xrLayer = createLayer();
-            return this.xrLayer;
-        });
+        return (this.canvasContext as any)
+            .makeXRCompatible()
+            .then(
+                // catch any error and continue. When using the emulator is throws this error for no apparent reason.
+                () => {},
+                () => {
+                    // log the error, continue nonetheless!
+                    Tools.Warn("Error executing makeXRCompatible. This does not mean that the session will work incorrectly.");
+                }
+            )
+            .then(() => {
+                this.xrLayer = createLayer();
+                return this.xrLayer;
+            });
     }
 
     private _addCanvas() {