Browse Source

Ray unit tests.

Ben Houston 12 years ago
parent
commit
e921f46141
4 changed files with 203 additions and 10 deletions
  1. 22 8
      src/math/Ray.js
  2. 1 2
      test/core/Box2.js
  3. 179 0
      test/core/Ray.js
  4. 1 0
      test/index.html

+ 22 - 8
src/math/Ray.js

@@ -23,7 +23,7 @@ THREE.Ray.prototype = {
 
 
 	constructor: THREE.Ray,
 	constructor: THREE.Ray,
 
 
-	set: function ( origin, direction) {
+	set: function ( origin, direction ) {
 
 
 		this.origin.copy( origin );
 		this.origin.copy( origin );
 		this.direction.copy( direction );
 		this.direction.copy( direction );
@@ -61,6 +61,13 @@ THREE.Ray.prototype = {
 
 
 	},
 	},
 
 
+	flip: function () {
+
+		this.direction.negate();
+
+		return this;
+	},
+
 	closestPointToPoint: function ( point ) {
 	closestPointToPoint: function ( point ) {
 
 
 		var result = point.clone().subSelf( this.origin );
 		var result = point.clone().subSelf( this.origin );
@@ -84,10 +91,10 @@ THREE.Ray.prototype = {
 		// Assumes the lines are normalized
 		// Assumes the lines are normalized
 		// based on algorithm in ILM's Imath Plane class.
 		// based on algorithm in ILM's Imath Plane class.
 
 
-	    __v1.copy( this.origin ).subSelf( ray.origin );
-	    var c = this.direction.dot( __v1 );
+	    THREE.Ray.__v1.copy( this.origin ).subSelf( ray.origin );
+	    var c = this.direction.dot( THREE.Ray.__v1 );
 	    var a = ray.direction.dot( this.direction );
 	    var a = ray.direction.dot( this.direction );
-	    var f = ray.direction.dot( __v1 );
+	    var f = ray.direction.dot( THREE.Ray.__v1 );
 	    var num = c - a * f;
 	    var num = c - a * f;
 	    var denom = a*a - 1;
 	    var denom = a*a - 1;
 
 
@@ -105,17 +112,17 @@ THREE.Ray.prototype = {
 		    }
 		    }
 	    }
 	    }
 
 
-	    return this.direction.clone().multipleScalar( num / denom ).addSelf( this.origin );
+	    return this.direction.clone().multiplyScalar( num / denom ).addSelf( this.origin );
 
 
 	},
 	},
 
 
 	distanceToRay: function ( ray ) {
 	distanceToRay: function ( ray ) {
 
 
-		__v1.copy( this.direction ).crossSelf( ray.direction );
-		__v2.copy( ray.origin ).subSelf( this.origin );
+		THREE.Ray.__v1.copy( this.direction ).crossSelf( ray.direction );
+		THREE.Ray.__v2.copy( ray.origin ).subSelf( this.origin );
 
 
 
 
-		var d = __v1.dot( __v2 );
+		var d = THREE.Ray.__v1.dot( THREE.Ray.__v2 );
 		if( d >= 0 ) {
 		if( d >= 0 ) {
 
 
 			return d;
 			return d;
@@ -139,6 +146,13 @@ THREE.Ray.prototype = {
 		var a = plane.normal.dot( this.direction );
 		var a = plane.normal.dot( this.direction );
 		if ( a == 0.0 ) {
 		if ( a == 0.0 ) {
 
 
+			// line is coplanar, return origin
+			if( plane.distanceToPoint( this.origin ) == 0 ) {
+
+				return origin.clone();
+
+			}
+
 			// Unsure if this is the correct method to handle this case.
 			// Unsure if this is the correct method to handle this case.
 			return undefined;
 			return undefined;
 
 

+ 1 - 2
test/core/Box2.js

@@ -1,4 +1,4 @@
-	/**
+/**
  * @author bhouston / http://exocortex.com
  * @author bhouston / http://exocortex.com
  */
  */
 
 
@@ -18,7 +18,6 @@ test( "constructor", function() {
 	ok( a.max.equals( one2 ), "Passed!" );
 	ok( a.max.equals( one2 ), "Passed!" );
 });
 });
 
 
-
 test( "copy", function() {
 test( "copy", function() {
 	var a = new THREE.Box2( zero2, one2 );
 	var a = new THREE.Box2( zero2, one2 );
 	var b = new THREE.Box2().copy( a );
 	var b = new THREE.Box2().copy( a );

+ 179 - 0
test/core/Ray.js

@@ -0,0 +1,179 @@
+/**
+ * @author bhouston / http://exocortex.com
+ */
+
+module( "Ray" );
+
+test( "constructor", function() {
+	var a = new THREE.Ray();
+	ok( a.origin.equals( zero3 ), "Passed!" );
+	ok( a.direction.equals( zero3 ), "Passed!" );
+
+	a = new THREE.Ray( two3, one3 );
+	ok( a.origin.equals( two3 ), "Passed!" );
+	ok( a.direction.equals( one3 ), "Passed!" );
+});
+
+test( "copy", function() {
+	var a = new THREE.Ray( zero3, one3 );
+	var b = new THREE.Ray().copy( a );
+	ok( b.origin.equals( zero3 ), "Passed!" );
+	ok( b.direction.equals( one3 ), "Passed!" );
+
+	// ensure that it is a true copy
+	a.origin = zero3;
+	a.direction = one3;
+	ok( b.origin.equals( zero3 ), "Passed!" );
+	ok( b.direction.equals( one3 ), "Passed!" );
+});
+
+test( "set", function() {
+	var a = new THREE.Ray();
+
+	a.set( one3, one3 )
+	ok( a.origin.equals( one3 ), "Passed!" );
+	ok( a.direction.equals( one3 ), "Passed!" );
+});
+
+test( "at", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+
+	ok( a.at( 0 ).equals( one3 ), "Passed!" );
+	ok( a.at( -1 ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" );
+	ok( a.at( 1 ).equals( new THREE.Vector3( 1, 1, 2 ) ), "Passed!" );
+});
+
+test( "recast/recastSelf", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+
+	ok( a.recastSelf( 0 ).equals( a ), "Passed!" );
+
+	var b = a.clone();
+	ok( b.recastSelf( -1 ).equals( new THREE.Ray( new THREE.Vector3( 1, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ) ), "Passed!" );
+
+	var c = a.clone();
+	ok( c.recastSelf( 1 ).equals( new THREE.Ray( new THREE.Vector3( 1, 1, 2 ), new THREE.Vector3( 0, 0, 1 ) ) ), "Passed!" );
+
+	var d = a.clone();
+	var e = d.recast( 1 );
+	ok( d.equals( a ), "Passed!" );
+	ok( ! e.equals( d ), "Passed!" );
+	ok( e.equals( c ), "Passed!" );
+});
+
+test( "flip", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+
+	var b = a.clone();
+	b.flip();
+	ok( b.direction.equals( new THREE.Vector3( 0, 0, -1 ) ), "Passed!" );
+	ok( ! b.equals( a ), "Passed!" );
+
+	// and let's flip back to original direction
+	b.flip();
+	ok( b.equals( a ), "Passed!" );
+});
+
+test( "closestPointToPoint", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+
+	// nearby the ray
+	var b = a.closestPointToPoint( zero3 );
+	ok( b.equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" );
+
+	// exactly on the ray
+	var c = a.closestPointToPoint( one3 );
+	ok( c.equals( one3 ), "Passed!" );
+});
+
+test( "distanceToPoint", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+
+	// nearby the ray
+	var b = a.distanceToPoint( zero3 );
+	ok( b == Math.sqrt( 2 ), "Passed!" );
+
+	// exactly on the ray
+	var c = a.distanceToPoint( one3 );
+	ok( c == 0, "Passed!" );
+});
+
+test( "distanceToRay", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+	
+	// parallel ray
+	var b = new THREE.Ray( zero3, new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.distanceToRay( b ) == Math.sqrt( 3 ), "Passed!" );
+
+	// perpendical ray that intersects
+	var c = new THREE.Ray( one3, new THREE.Vector3( 1, 0, 0 ) );
+	ok( a.distanceToRay( c ) == 0, "Passed!" );
+
+	// perpendical ray that doesn't intersects
+	var d = new THREE.Ray( one3.clone().subSelf( new THREE.Vector3( 0, 0, -1 ) ), new THREE.Vector3( 1, 0, 0 ) );
+	ok( a.distanceToRay( d ) == 1, "Passed!" );
+});
+
+test( "closestPointToRay", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+	
+	// parallel ray
+	var b = new THREE.Ray( zero3, new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.closestPointToRay( b ).equals( one3 ), "Passed!" );
+
+	// perpendical ray that intersects
+	var c = new THREE.Ray( one3, new THREE.Vector3( 1, 0, 0 ) );
+	ok( a.closestPointToRay( c ).equals( zero3 ), "Passed!" );
+
+	// perpendical ray that doesn't intersects
+	var d = new THREE.Ray( one3.clone().subSelf( new THREE.Vector3( 0, 0, -1 ) ), new THREE.Vector3( 1, 0, 0 ) );
+	ok( a.closestPointToRay( d ).equals( new THREE.Vector3( 0, 0, 1 ) ), "Passed!" );
+});
+
+test( "isIntersectionPlane", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+	
+	// parallel plane behind
+	var b = new THREE.Plane( one3.clone().subSelf( new THREE.Vector3( 0, 0, -1 ) ), new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.isIntersectionPlane( b ), "Passed!" );
+
+	// parallel plane coincident with origin
+	var c = new THREE.Plane( one3.clone().subSelf( new THREE.Vector3( 0, 0, 0 ) ), new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.isIntersectionPlane( c ), "Passed!" );
+
+	// parallel plane infront
+	var d = new THREE.Plane( one3.clone().subSelf( new THREE.Vector3( 0, 0, 1 ) ), new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.isIntersectionPlane( d ), "Passed!" );
+
+	// perpendical ray that overlaps exactly
+	var e = new THREE.Plane( one3, new THREE.Vector3( 1, 0, 0 ) );
+	ok( a.isIntersectionPlane( e ), "Passed!" );
+
+	// perpendical ray that doesn't overlap
+	var f = new THREE.Plane( zero3, new THREE.Vector3( 1, 0, 0 ) );
+	ok( ! a.isIntersectionPlane( f ), "Passed!" );
+});
+
+test( "intersectPlane", function() {
+	var a = new THREE.Ray( one3, new THREE.Vector3( 0, 0, 1 ) );
+	
+	// parallel plane behind
+	var b = new THREE.Plane( one3.clone().subSelf( new THREE.Vector3( 0, 0, -1 ) ), new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.intersectPlane( b ).equals( one3.clone().subSelf( new THREE.Vector3( 0, 0, -1 ) ) ), "Passed!" );
+
+	// parallel plane coincident with origin
+	var c = new THREE.Plane( one3.clone().subSelf( new THREE.Vector3( 0, 0, 0 ) ), new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.intersectPlane( c ).equals( one3.clone().subSelf( new THREE.Vector3( 0, 0, 0 ) ) ), "Passed!" );
+
+	// parallel plane infront
+	var d = new THREE.Plane( one3.clone().subSelf( new THREE.Vector3( 0, 0, 1 ) ), new THREE.Vector3( 0, 0, 1 ) );
+	ok( a.intersectPlane( d ).equals( one3.clone().subSelf( new THREE.Vector3( 0, 0, 1 ) ) ), "Passed!" );
+
+	// perpendical ray that overlaps exactly
+	var e = new THREE.Plane( one3, new THREE.Vector3( 1, 0, 0 ) );
+	ok( a.intersectPlane( e ) === e.origin, "Passed!" );
+
+	// perpendical ray that doesn't overlap
+	var f = new THREE.Plane( zero3, new THREE.Vector3( 1, 0, 0 ) );
+	ok( ! a.intersectPlane( f ) === undefined, "Passed!" );
+});

+ 1 - 0
test/index.html

@@ -20,6 +20,7 @@
   <script src="core/Vector2.js"></script>
   <script src="core/Vector2.js"></script>
   <script src="core/Vector3.js"></script>
   <script src="core/Vector3.js"></script>
   <script src="core/Vector4.js"></script>
   <script src="core/Vector4.js"></script>
+  <script src="core/Ray.js"></script>
   
   
 </body>
 </body>
 </html>
 </html>