浏览代码

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 年之前
父节点
当前提交
11cdf35904
共有 2 个文件被更改,包括 53 次插入9 次删除
  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) {
-            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) {
@@ -1005,7 +1005,7 @@
         };
 
         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) {
@@ -2281,9 +2281,11 @@
     BABYLON.Frustum = Frustum;
 
     var Ray = (function () {
-        function Ray(origin, direction) {
+        function Ray(origin, direction, length) {
+            if (typeof length === "undefined") { length = Number.MAX_VALUE; }
             this.origin = origin;
             this.direction = direction;
+            this.length = length;
         }
         // Methods
         Ray.prototype.intersectsBoxMinMax = function (minimum, maximum) {
@@ -2422,7 +2424,13 @@
                 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
@@ -2436,11 +2444,27 @@
             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) {
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
 
-            return new Ray(newOrigin, newDirection);
+            return new Ray(newOrigin, newDirection, ray.length);
         };
         return Ray;
     })();
@@ -2463,4 +2487,3 @@
     BABYLON.Axis = Axis;
     ;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.math.js.map

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

@@ -2280,7 +2280,7 @@
         private _tvec: 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
@@ -2422,8 +2422,14 @@
             if (bv < 0 || bu + bv > 1.0) {
                 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
@@ -2436,12 +2442,27 @@
 
             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 {
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
 
-            return new Ray(newOrigin, newDirection);
+            return new Ray(newOrigin, newDirection, ray.length);
         }
     }