Jelajahi Sumber

Extending the Ray class functionality

A new static CreateNewFromTo to allow creating ray with two points in
space. The function accepts a matrix to transform the ray. default is
the identity matrix.
The function calculates the direction of the vector and its length (for
trianglular intersections)
Also added length parameter to the ray (default is Number.MAX_VALUE) to
prevent wrong intersection detection of objects that stand behind the
end point. Default behavior is not affected by it. Triangle-Intersection
now checks if the distance is correct and returns null if the ray
doesn't actually touch the object inspected.
Raanan Weber 10 tahun lalu
induk
melakukan
11cdf35904
2 mengubah file dengan 53 tambahan dan 9 penghapusan
  1. 29 6
      Babylon/Math/babylon.math.js
  2. 24 3
      Babylon/Math/babylon.math.ts

+ 29 - 6
Babylon/Math/babylon.math.js

@@ -575,7 +575,7 @@
         };
         };
 
 
         Vector3.prototype.equalsWithEpsilon = function (otherVector) {
         Vector3.prototype.equalsWithEpsilon = function (otherVector) {
-            return Math.abs(this.x - otherVector.x) < BABYLON.Engine.Epsilon && Math.abs(this.y - otherVector.y) < BABYLON.Engine.Epsilon && Math.abs(this.z - otherVector.z) < BABYLON.Engine.Epsilon;
+            return Math.abs(this.x - otherVector.x) < Engine.Epsilon && Math.abs(this.y - otherVector.y) < Engine.Epsilon && Math.abs(this.z - otherVector.z) < Engine.Epsilon;
         };
         };
 
 
         Vector3.prototype.equalsToFloats = function (x, y, z) {
         Vector3.prototype.equalsToFloats = function (x, y, z) {
@@ -1005,7 +1005,7 @@
         };
         };
 
 
         Vector4.prototype.equalsWithEpsilon = function (otherVector) {
         Vector4.prototype.equalsWithEpsilon = function (otherVector) {
-            return Math.abs(this.x - otherVector.x) < BABYLON.Engine.Epsilon && Math.abs(this.y - otherVector.y) < BABYLON.Engine.Epsilon && Math.abs(this.z - otherVector.z) < BABYLON.Engine.Epsilon && Math.abs(this.w - otherVector.w) < BABYLON.Engine.Epsilon;
+            return Math.abs(this.x - otherVector.x) < Engine.Epsilon && Math.abs(this.y - otherVector.y) < Engine.Epsilon && Math.abs(this.z - otherVector.z) < Engine.Epsilon && Math.abs(this.w - otherVector.w) < Engine.Epsilon;
         };
         };
 
 
         Vector4.prototype.equalsToFloats = function (x, y, z, w) {
         Vector4.prototype.equalsToFloats = function (x, y, z, w) {
@@ -2281,9 +2281,11 @@
     BABYLON.Frustum = Frustum;
     BABYLON.Frustum = Frustum;
 
 
     var Ray = (function () {
     var Ray = (function () {
-        function Ray(origin, direction) {
+        function Ray(origin, direction, length) {
+            if (typeof length === "undefined") { length = Number.MAX_VALUE; }
             this.origin = origin;
             this.origin = origin;
             this.direction = direction;
             this.direction = direction;
+            this.length = length;
         }
         }
         // Methods
         // Methods
         Ray.prototype.intersectsBoxMinMax = function (minimum, maximum) {
         Ray.prototype.intersectsBoxMinMax = function (minimum, maximum) {
@@ -2422,7 +2424,13 @@
                 return null;
                 return null;
             }
             }
 
 
-            return new BABYLON.IntersectionInfo(bu, bv, Vector3.Dot(this._edge2, this._qvec) * invdet);
+            //check if the distance is longer than the predefined length.
+            var distance = Vector3.Dot(this._edge2, this._qvec) * invdet;
+            if (distance > this.length) {
+                return null;
+            }
+
+            return new IntersectionInfo(bu, bv, distance);
         };
         };
 
 
         // Statics
         // Statics
@@ -2436,11 +2444,27 @@
             return new Ray(start, direction);
             return new Ray(start, direction);
         };
         };
 
 
+        /**
+        * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be
+        * transformed to the given world matrix.
+        * @param origin The origin point
+        * @param end The end point
+        * @param world a matrix to transform the ray to. Default is the identity matrix.
+        */
+        Ray.CreateNewFromTo = function (origin, end, world) {
+            if (typeof world === "undefined") { world = BABYLON.Matrix.Identity(); }
+            var direction = end.subtract(origin);
+            var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
+            direction.normalize();
+
+            return Ray.Transform(new Ray(origin, direction, length), world);
+        };
+
         Ray.Transform = function (ray, matrix) {
         Ray.Transform = function (ray, matrix) {
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
 
 
-            return new Ray(newOrigin, newDirection);
+            return new Ray(newOrigin, newDirection, ray.length);
         };
         };
         return Ray;
         return Ray;
     })();
     })();
@@ -2463,4 +2487,3 @@
     BABYLON.Axis = Axis;
     BABYLON.Axis = Axis;
     ;
     ;
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.math.js.map

+ 24 - 3
Babylon/Math/babylon.math.ts

@@ -2280,7 +2280,7 @@
         private _tvec: Vector3;
         private _tvec: Vector3;
         private _qvec: Vector3;
         private _qvec: Vector3;
 
 
-        constructor(public origin: Vector3, public direction: Vector3) {
+        constructor(public origin: Vector3, public direction: Vector3, public length: number = Number.MAX_VALUE) {
         }
         }
 
 
         // Methods
         // Methods
@@ -2422,8 +2422,14 @@
             if (bv < 0 || bu + bv > 1.0) {
             if (bv < 0 || bu + bv > 1.0) {
                 return null;
                 return null;
             }
             }
+			
+			//check if the distance is longer than the predefined length.
+			var distance = Vector3.Dot(this._edge2, this._qvec) * invdet;
+			if(distance > this.length) {
+				return null;
+			}
 
 
-            return new IntersectionInfo(bu, bv, Vector3.Dot(this._edge2, this._qvec) * invdet);
+            return new IntersectionInfo(bu, bv, distance);
         }
         }
 
 
         // Statics
         // Statics
@@ -2436,12 +2442,27 @@
 
 
             return new Ray(start, direction);
             return new Ray(start, direction);
         }
         }
+		
+		/**
+		* Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be 
+		* transformed to the given world matrix.
+		* @param origin The origin point
+		* @param end The end point
+		* @param world a matrix to transform the ray to. Default is the identity matrix.
+		*/
+		public static CreateNewFromTo(origin : BABYLON.Vector3, end : BABYLON.Vector3, world: Matrix = BABYLON.Matrix.Identity()): Ray {
+			var direction = end.subtract(origin);
+			var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
+            direction.normalize();
+			
+			return Ray.Transform(new Ray(origin, direction, length), world);
+		}
 
 
         public static Transform(ray: Ray, matrix: Matrix): Ray {
         public static Transform(ray: Ray, matrix: Matrix): Ray {
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
 
 
-            return new Ray(newOrigin, newDirection);
+            return new Ray(newOrigin, newDirection, ray.length);
         }
         }
     }
     }