Browse Source

Merge remote-tracking branch 'upstream/master' into libToModules

sebastien 6 years ago
parent
commit
43f579b22b

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

@@ -43,6 +43,7 @@
   - Prevented code from doing useless and possible time consuming computation when disposing the `ShaderMaterial` of a `LinesMesh`
   - Make a better use of the `isIdentity` cached value wihtin a `Matrix`
   - Make sure we browse all the submeshes only once in `Material.markAsDirty` function
+  - Added an `Vector3.UnprojectRayToRef` static function to avoid computing and inverting the projection matrix twice when updating a Ray.
 - Align `BoundingBox` and `BoundingSphere` API and behavior for clarity and simplicity. As a consequence, the `BoundingBox`'s method `setWorldMatrix` has been removed and the underlying world matrix cannot be modified but by calling `reConstruct` or `update`. ([barroij](https://github.com/barroij))
 - Make sure that `Material.markAsDirty` and all the `markXXXDirty` methods early out when `scene.blockMaterialDirtyMechanism` is true. ([barroij](https://github.com/barroij))
 
@@ -55,6 +56,7 @@
 ### Materials Library
 
 ## Bug fixes
+- Refocusing on input gui with pointer events ([TrevorDev](https://github.com/TrevorDev))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))

File diff suppressed because it is too large
+ 570 - 559
gui/src/2D/controls/inputText.ts


+ 37 - 31
src/Culling/babylon.ray.ts

@@ -3,14 +3,7 @@ module BABYLON {
      * Class representing a ray with position and direction
      */
     export class Ray {
-        private static readonly _edge1 = Vector3.Zero();
-        private static readonly _edge2 = Vector3.Zero();
-        private static readonly _pvec = Vector3.Zero();
-        private static readonly _tvec = Vector3.Zero();
-        private static readonly _qvec = Vector3.Zero();
-        private static readonly _min = Vector3.Zero();
-        private static readonly _max = Vector3.Zero();
-
+        private static readonly TmpVector3 = Tools.BuildArray(6, Vector3.Zero);
         private _tmpRay: Ray;
 
         /**
@@ -37,8 +30,8 @@ module BABYLON {
          * @returns if the box was hit
          */
         public intersectsBoxMinMax(minimum: Vector3, maximum: Vector3, intersectionTreshold: number = 0): boolean {
-            const newMinimum = Ray._min.copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);
-            const newMaximum = Ray._max.copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);
+            const newMinimum = Ray.TmpVector3[0].copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);
+            const newMaximum = Ray.TmpVector3[1].copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);
             var d = 0.0;
             var maxValue = Number.MAX_VALUE;
             var inv: number;
@@ -176,10 +169,16 @@ module BABYLON {
          * @returns intersection information if hit
          */
         public intersectsTriangle(vertex0: Vector3, vertex1: Vector3, vertex2: Vector3): Nullable<IntersectionInfo> {
-            vertex1.subtractToRef(vertex0, Ray._edge1);
-            vertex2.subtractToRef(vertex0, Ray._edge2);
-            Vector3.CrossToRef(this.direction, Ray._edge2, Ray._pvec);
-            var det = Vector3.Dot(Ray._edge1, Ray._pvec);
+            const edge1 = Ray.TmpVector3[0];
+            const edge2 = Ray.TmpVector3[1];
+            const pvec = Ray.TmpVector3[2];
+            const tvec = Ray.TmpVector3[3];
+            const qvec =  Ray.TmpVector3[4];
+
+            vertex1.subtractToRef(vertex0, edge1);
+            vertex2.subtractToRef(vertex0, edge2);
+            Vector3.CrossToRef(this.direction, edge2, pvec);
+            var det = Vector3.Dot(edge1, pvec);
 
             if (det === 0) {
                 return null;
@@ -187,24 +186,24 @@ module BABYLON {
 
             var invdet = 1 / det;
 
-            this.origin.subtractToRef(vertex0, Ray._tvec);
+            this.origin.subtractToRef(vertex0, tvec);
 
-            var bu = Vector3.Dot(Ray._tvec, Ray._pvec) * invdet;
+            var bu = Vector3.Dot(tvec, pvec) * invdet;
 
             if (bu < 0 || bu > 1.0) {
                 return null;
             }
 
-            Vector3.CrossToRef(Ray._tvec, Ray._edge1, Ray._qvec);
+            Vector3.CrossToRef(tvec, edge1, qvec);
 
-            var bv = Vector3.Dot(this.direction, Ray._qvec) * invdet;
+            var bv = Vector3.Dot(this.direction, qvec) * invdet;
 
             if (bv < 0 || bu + bv > 1.0) {
                 return null;
             }
 
             //check if the distance is longer than the predefined length.
-            var distance = Vector3.Dot(Ray._edge2, Ray._qvec) * invdet;
+            var distance = Vector3.Dot(edge2, qvec) * invdet;
             if (distance > this.length) {
                 return null;
             }
@@ -312,11 +311,19 @@ module BABYLON {
          * @return the distance from the ray origin to the intersection point if there's intersection, or -1 if there's no intersection
          */
         intersectionSegment(sega: Vector3, segb: Vector3, threshold: number): number {
-            var rsegb = this.origin.add(this.direction.multiplyByFloats(Ray.rayl, Ray.rayl, Ray.rayl));
+            const o = this.origin;
+            const u =  Tmp.Vector3[0];
+            const rsegb  = Tmp.Vector3[1];
+            const v =  Tmp.Vector3[2];
+            const w =  Tmp.Vector3[3];
+
+            segb.subtractToRef(sega, u);
+
+            this.direction.scaleToRef(Ray.rayl, v);
+            o.addToRef(v, rsegb);
+
+            sega.subtractToRef(o, w);
 
-            var u = segb.subtract(sega);
-            var v = rsegb.subtract(this.origin);
-            var w = sega.subtract(this.origin);
             var a = Vector3.Dot(u, u);                  // always >= 0
             var b = Vector3.Dot(u, v);
             var c = Vector3.Dot(v, v);                  // always >= 0
@@ -376,8 +383,11 @@ module BABYLON {
             tc = (Math.abs(tN) < Ray.smallnum ? 0.0 : tN / tD);
 
             // get the difference of the two closest points
-            let qtc = v.multiplyByFloats(tc, tc, tc);
-            var dP = w.add(u.multiplyByFloats(sc, sc, sc)).subtract(qtc);  // = S1(sc) - S2(tc)
+            const qtc = Tmp.Vector3[4];
+            v.scaleToRef(tc, qtc);
+            const dP = Tmp.Vector3[5];
+            u.scaleToRef(sc, dP);
+            dP.addInPlace(w).subtractInPlace(qtc);  // = S1(sc) - S2(tc)
 
             var isIntersected = (tc > 0) && (tc <= this.length) && (dP.lengthSquared() < (threshold * threshold));   // return intersection result
 
@@ -398,12 +408,8 @@ module BABYLON {
          * @param projection projection matrix
          * @returns this ray updated
          */
-        public update(x: number, y: number, viewportWidth: number, viewportHeight: number, world: Matrix, view: Matrix, projection: Matrix): Ray {
-            Vector3.UnprojectFloatsToRef(x, y, 0, viewportWidth, viewportHeight, world, view, projection, this.origin);
-            Vector3.UnprojectFloatsToRef(x, y, 1, viewportWidth, viewportHeight, world, view, projection, Tmp.Vector3[0]);
-
-            Tmp.Vector3[0].subtractToRef(this.origin, this.direction);
-            this.direction.normalize();
+        public update(x: number, y: number, viewportWidth: number, viewportHeight: number, world: Readonly<Matrix>, view: Readonly<Matrix>, projection: Readonly<Matrix>): Ray {
+            Vector3.UnprojectRayToRef(x, y, viewportWidth, viewportHeight, world, view, projection, this);
             return this;
         }
 

+ 43 - 14
src/Math/babylon.math.ts

@@ -2495,6 +2495,16 @@ module BABYLON {
             return Vector3.TransformCoordinates(vector, matrix);
         }
 
+        /** @hidden */
+        private static UnprojectFromInvertedMatrixToRef(source: Vector3, matrix: Readonly<Matrix>, result: Vector3) {
+            Vector3.TransformCoordinatesToRef(source, matrix, result);
+            const m = matrix.m;
+            var num = source.x * m[3] + source.y * m[7] + source.z * m[11] + m[15];
+            if (Scalar.WithinEpsilon(num, 1.0)) {
+                result.scaleInPlace(1.0 / num);
+            }
+        }
+
         /**
          * Unproject from screen space to object space
          * @param source defines the screen space Vector3 to use
@@ -2510,14 +2520,8 @@ module BABYLON {
             matrix.invert();
             source.x = source.x / viewportWidth * 2 - 1;
             source.y = -(source.y / viewportHeight * 2 - 1);
-            var vector = Vector3.TransformCoordinates(source, matrix);
-            const m = matrix.m;
-            var num = source.x * m[3] + source.y * m[7] + source.z * m[11] + m[15];
-
-            if (Scalar.WithinEpsilon(num, 1.0)) {
-                vector = vector.scale(1.0 / num);
-            }
-
+            const vector = new Vector3();
+            Vector3.UnprojectFromInvertedMatrixToRef(source, matrix, vector);
             return vector;
         }
 
@@ -2574,13 +2578,38 @@ module BABYLON {
             screenSource.x = sourceX / viewportWidth * 2 - 1;
             screenSource.y = -(sourceY / viewportHeight * 2 - 1);
             screenSource.z = 2 * sourceZ - 1.0;
-            Vector3.TransformCoordinatesToRef(screenSource, matrix, result);
-            const m = matrix.m;
-            var num = screenSource.x * m[3] + screenSource.y * m[7] + screenSource.z * m[11] + m[15];
+            Vector3.UnprojectFromInvertedMatrixToRef(screenSource, matrix, result);
+        }
 
-            if (Scalar.WithinEpsilon(num, 1.0)) {
-                result.scaleInPlace(1.0 / num);
-            }
+       /**
+         * Unproject a ray from screen space to object space
+         * @param sourceX defines the screen space x coordinate to use
+         * @param sourceY defines the screen space y coordinate to use
+         * @param viewportWidth defines the current width of the viewport
+         * @param viewportHeight defines the current height of the viewport
+         * @param world defines the world matrix to use (can be set to Identity to go to world space)
+         * @param view defines the view matrix to use
+         * @param projection defines the projection matrix to use
+         * @param ray defines the Ray where to store the result
+         */
+        public static UnprojectRayToRef(sourceX: float, sourceY: float, viewportWidth: number, viewportHeight: number, world: Readonly<Matrix>, view: Readonly<Matrix>, projection: Readonly<Matrix>, ray: Ray): void {
+            var matrix = MathTmp.Matrix[0];
+            world.multiplyToRef(view, matrix);
+            matrix.multiplyToRef(projection, matrix);
+            matrix.invert();
+            var nearScreenSource = MathTmp.Vector3[0];
+            nearScreenSource.x = sourceX / viewportWidth * 2 - 1;
+            nearScreenSource.y = -(sourceY / viewportHeight * 2 - 1);
+            nearScreenSource.z = -1.0;
+            var farScreenSource = MathTmp.Vector3[1].copyFromFloats(nearScreenSource.x, nearScreenSource.y, 1.0);
+            const nearVec3 = MathTmp.Vector3[2];
+            const farVec3 = MathTmp.Vector3[3];
+            Vector3.UnprojectFromInvertedMatrixToRef(nearScreenSource, matrix, nearVec3);
+            Vector3.UnprojectFromInvertedMatrixToRef(farScreenSource, matrix, farVec3);
+
+            ray.origin.copyFrom(nearVec3);
+            farVec3.subtractToRef(nearVec3, ray.direction);
+            ray.direction.normalize();
         }
 
         /**

+ 3 - 3
src/babylon.scene.ts

@@ -2005,6 +2005,8 @@ module BABYLON {
                 }
 
                 this._initClickEvent(this.onPrePointerObservable, this.onPointerObservable, evt, (clickInfo: ClickInfo, pickResult: Nullable<PickingInfo>) => {
+                    this._pointerCaptures[evt.pointerId] = false;
+
                     // PreObservable support
                     if (this.onPrePointerObservable.hasObservers()) {
                         if (!clickInfo.ignore) {
@@ -2030,8 +2032,6 @@ module BABYLON {
                         return;
                     }
 
-                    this._pointerCaptures[evt.pointerId] = false;
-
                     if (!this.pointerUpPredicate) {
                         this.pointerUpPredicate = (mesh: AbstractMesh): boolean => {
                             return mesh.isPickable && mesh.isVisible && mesh.isReady() && mesh.isEnabled();
@@ -5001,7 +5001,7 @@ module BABYLON {
             x = x / this._engine.getHardwareScalingLevel() - viewport.x;
             y = y / this._engine.getHardwareScalingLevel() - (this._engine.getRenderHeight() - viewport.y - viewport.height);
 
-            result.update(x, y, viewport.width, viewport.height, world ? world : Matrix.Identity(), cameraViewSpace ? Matrix.Identity() : camera.getViewMatrix(), camera.getProjectionMatrix());
+            result.update(x, y, viewport.width, viewport.height, world ? world : Matrix.IdentityReadOnly, cameraViewSpace ? Matrix.IdentityReadOnly : camera.getViewMatrix(), camera.getProjectionMatrix());
             return this;
         }