浏览代码

Merge remote-tracking branch 'bhouston/math-line' into dev

Mr.doob 12 年之前
父节点
当前提交
4cc51004b0

+ 1 - 1
src/core/Raycaster.js

@@ -88,7 +88,7 @@
 
 
 			inverseMatrix.getInverse( object.matrixWorld );
 			inverseMatrix.getInverse( object.matrixWorld );
 
 
-			localRay.copy( raycaster.ray ).transform( inverseMatrix );
+			localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
 
 
 			for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
 			for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
 
 

+ 1 - 1
src/math/Box3.js

@@ -271,7 +271,7 @@ THREE.extend( THREE.Box3.prototype, {
 
 
 	},
 	},
 
 
-	transform: function() {
+	applyMatrix4: function() {
 
 
 		var points = [
 		var points = [
 			new THREE.Vector3(),
 			new THREE.Vector3(),

+ 124 - 0
src/math/Line3.js

@@ -0,0 +1,124 @@
+/**
+ * @author bhouston / http://exocortex.com
+ */
+
+THREE.Line3 = function ( start, end ) {
+
+	this.start = ( start !== undefined ) ? start : new THREE.Vector3();
+	this.end = ( end !== undefined ) ? end : new THREE.Vector3();
+
+};
+
+THREE.extend( THREE.Line3.prototype, {
+
+	set: function ( start, end ) {
+
+		this.start.copy( start );
+		this.end.copy( end );
+
+		return this;
+
+	},
+
+	copy: function ( line ) {
+
+		this.start.copy( line.start );
+		this.end.copy( line.end );
+
+		return this;
+
+	},
+
+	center: function ( optionalTarget ) {
+
+		var result = optionalTarget || new THREE.Vector3();
+		return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
+
+	},
+
+	delta: function ( optionalTarget ) {
+
+		var result = optionalTarget || new THREE.Vector3();
+		return result.subVectors( this.end, this.start );
+
+	},
+
+	distanceSq: function () {
+
+		return this.start.distanceToSquared( this.end );
+
+	},
+
+	distance: function () {
+
+		return this.start.distanceTo( this.end );
+
+	},
+
+	at: function ( t, optionalTarget ) {
+
+		var result = optionalTarget || new THREE.Vector3();
+
+		return this.delta( result ).multiplyScalar( t ).add( this.start );
+
+	},
+
+	closestPointToPointParameter: function() {
+
+		var startP = new THREE.Vector3();
+		var startEnd = new THREE.Vector3();
+
+		return function ( point, clampToLine ) {
+		
+			startP.subVectors( point, this.start );
+			startEnd.subVectors( this.end, this.start );
+
+			var startEnd2 = startEnd.dot( startEnd );
+			var startEnd_startP = startEnd.dot( startP );
+
+			var t = startEnd_startP / startEnd2;
+
+			if( clampToLine ) {
+				
+	        	t = THREE.Math.clamp( t, 0, 1 );
+
+	        }
+
+	        return t;
+
+		};
+
+	}(),
+
+	closestPointToPoint: function ( point, clampToLine, optionalTarget ) {
+
+		var t = this.closestPointToPointParameter( point, clampToLine );
+
+		var result = optionalTarget || new THREE.Vector3();			
+
+        return this.delta( result ).multiplyScalar( t ).add( this.start );
+
+	},
+
+	applyMatrix4: function ( matrix ) {
+
+		this.start.applyMatrix4( matrix );
+		this.end.applyMatrix4( matrix );
+
+		return this;
+
+	},
+
+	equals: function ( line ) {
+
+		return line.start.equals( this.start ) && line.end.equals( this.end );
+
+	},
+
+	clone: function () {
+
+		return new THREE.Line3().copy( this );
+
+	}
+
+} );

+ 36 - 0
src/math/Math.js

@@ -28,6 +28,42 @@ THREE.Math = {
 
 
 	},
 	},
 
 
+	// http://en.wikipedia.org/wiki/Smoothstep
+
+	smoothStep: function ( x, min, max ) {
+
+		if( x <= min ) {
+			return 0;
+		}
+		if( x >= max ) {
+			return 1;
+		}
+
+		// normalize
+		x = ( x - min )/( max - min );
+
+		return x*x*(3 - 2*x);
+
+	},
+
+	// http://en.wikipedia.org/wiki/Smoothstep
+
+	smootherStep: function ( x, min, max ) {
+
+		if( x <= min ) {
+			return 0;
+		}
+		if( x >= max ) {
+			return 1;
+		}
+
+		// normalize
+		x = ( x - min )/( max - min );
+
+		return x*x*x*(x*(x*6 - 15) + 10);
+
+	},
+	
 	// Random float from <0, 1> with 16 bits of randomness
 	// Random float from <0, 1> with 16 bits of randomness
 	// (standard Math.random() creates repetitive patterns when applied over larger space)
 	// (standard Math.random() creates repetitive patterns when applied over larger space)
 
 

+ 10 - 10
src/math/Plane.js

@@ -115,12 +115,12 @@ THREE.extend( THREE.Plane.prototype, {
 
 
 	},
 	},
 
 
-	isIntersectionLine: function ( startPoint, endPoint ) {
+	isIntersectionLine: function ( line ) {
 
 
 		// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
 		// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
 
 
-		var startSign = this.distanceToPoint( startPoint );
-		var endSign = this.distanceToPoint( endPoint );
+		var startSign = this.distanceToPoint( line.start );
+		var endSign = this.distanceToPoint( line.end );
 
 
 		return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
 		return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
 
 
@@ -130,20 +130,20 @@ THREE.extend( THREE.Plane.prototype, {
 
 
 		var v1 = new THREE.Vector3();
 		var v1 = new THREE.Vector3();
 
 
-		return function ( startPoint, endPoint, optionalTarget ) {
+		return function ( line, optionalTarget ) {
 
 
 			var result = optionalTarget || new THREE.Vector3();
 			var result = optionalTarget || new THREE.Vector3();
 
 
-			var direction = v1.subVectors( endPoint, startPoint );
+			var direction = line.delta( v1 );
 
 
 			var denominator = this.normal.dot( direction );
 			var denominator = this.normal.dot( direction );
 
 
 			if ( denominator == 0 ) {
 			if ( denominator == 0 ) {
 
 
 				// line is coplanar, return origin
 				// line is coplanar, return origin
-				if( this.distanceToPoint( startPoint ) == 0 ) {
+				if( this.distanceToPoint( line.start ) == 0 ) {
 
 
-					return result.copy( startPoint );
+					return result.copy( line.start );
 
 
 				}
 				}
 
 
@@ -152,7 +152,7 @@ THREE.extend( THREE.Plane.prototype, {
 
 
 			}
 			}
 
 
-			var t = - ( startPoint.dot( this.normal ) + this.constant ) / denominator;
+			var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
 
 
 			if( t < 0 || t > 1 ) {
 			if( t < 0 || t > 1 ) {
 
 
@@ -160,7 +160,7 @@ THREE.extend( THREE.Plane.prototype, {
 
 
 			}
 			}
 
 
-			return result.copy( direction ).multiplyScalar( t ).add( startPoint );
+			return result.copy( direction ).multiplyScalar( t ).add( line.start );
 
 
 		};
 		};
 
 
@@ -174,7 +174,7 @@ THREE.extend( THREE.Plane.prototype, {
 
 
 	},
 	},
 
 
-	transform: function() {
+	applyMatrix4: function() {
 
 
 		var v1 = new THREE.Vector3();
 		var v1 = new THREE.Vector3();
 		var v2 = new THREE.Vector3();
 		var v2 = new THREE.Vector3();

+ 1 - 1
src/math/Ray.js

@@ -140,7 +140,7 @@ THREE.extend( THREE.Ray.prototype, {
 
 
 	},
 	},
 
 
-	transform: function ( matrix4 ) {
+	applyMatrix4: function ( matrix4 ) {
 
 
 		this.direction.add( this.origin ).applyMatrix4( matrix4 );
 		this.direction.add( this.origin ).applyMatrix4( matrix4 );
 		this.origin.applyMatrix4( matrix4 );
 		this.origin.applyMatrix4( matrix4 );

+ 1 - 1
src/math/Sphere.js

@@ -102,7 +102,7 @@ THREE.extend( THREE.Sphere.prototype, {
 
 
 	},
 	},
 
 
-	transform: function ( matrix ) {
+	applyMatrix4: function ( matrix ) {
 
 
 		this.center.applyMatrix4( matrix );
 		this.center.applyMatrix4( matrix );
 		this.radius = this.radius * matrix.getMaxScaleOnAxis();
 		this.radius = this.radius * matrix.getMaxScaleOnAxis();

+ 5 - 5
test/unit/math/Box3.js

@@ -248,7 +248,7 @@ var compareBox = function ( a, b, threshold ) {
 	a.max.distanceTo( b.max ) < threshold );
 	a.max.distanceTo( b.max ) < threshold );
 };
 };
 
 
-test( "transform", function() {
+test( "applyMatrix4", function() {
 	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
 	var a = new THREE.Box3( zero3.clone(), zero3.clone() );
 	var b = new THREE.Box3( zero3.clone(), one3.clone() );
 	var b = new THREE.Box3( zero3.clone(), one3.clone() );
 	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
 	var c = new THREE.Box3( one3.clone().negate(), one3.clone() );
@@ -257,10 +257,10 @@ test( "transform", function() {
 	var m = new THREE.Matrix4().makeTranslation( 1, -2, 1 );
 	var m = new THREE.Matrix4().makeTranslation( 1, -2, 1 );
 	var t1 = new THREE.Vector3( 1, -2, 1 );
 	var t1 = new THREE.Vector3( 1, -2, 1 );
 
 
-	ok( compareBox( a.clone().transform( m ), a.clone().translate( t1 ) ), "Passed!" );
-	ok( compareBox( b.clone().transform( m ), b.clone().translate( t1 ) ), "Passed!" );
-	ok( compareBox( c.clone().transform( m ), c.clone().translate( t1 ) ), "Passed!" );
-	ok( compareBox( d.clone().transform( m ), d.clone().translate( t1 ) ), "Passed!" );
+	ok( compareBox( a.clone().applyMatrix4( m ), a.clone().translate( t1 ) ), "Passed!" );
+	ok( compareBox( b.clone().applyMatrix4( m ), b.clone().translate( t1 ) ), "Passed!" );
+	ok( compareBox( c.clone().applyMatrix4( m ), c.clone().translate( t1 ) ), "Passed!" );
+	ok( compareBox( d.clone().applyMatrix4( m ), d.clone().translate( t1 ) ), "Passed!" );
 });
 });
 
 
 test( "translate", function() {
 test( "translate", function() {

+ 70 - 0
test/unit/math/Line3.js

@@ -0,0 +1,70 @@
+/**
+ * @author bhouston / http://exocortex.com
+ */
+
+module( "Line3" );
+
+test( "constructor/equals", function() {
+	var a = new THREE.Line3();
+	ok( a.start.equals( zero3 ), "Passed!" );
+	ok( a.end.equals( zero3 ), "Passed!" );
+
+	a = new THREE.Line3( two3.clone(), one3.clone() );
+	ok( a.start.equals( two3 ), "Passed!" );
+	ok( a.end.equals( one3 ), "Passed!" );
+});
+
+test( "copy/equals", function() {
+	var a = new THREE.Line3( zero3.clone(), one3.clone() );
+	var b = new THREE.Line3().copy( a );
+	ok( b.start.equals( zero3 ), "Passed!" );
+	ok( b.end.equals( one3 ), "Passed!" );
+
+	// ensure that it is a true copy
+	a.start = zero3;
+	a.end = one3;
+	ok( b.start.equals( zero3 ), "Passed!" );
+	ok( b.end.equals( one3 ), "Passed!" );
+});
+
+test( "set", function() {
+	var a = new THREE.Line3();
+
+	a.set( one3, one3 );
+	ok( a.start.equals( one3 ), "Passed!" );
+	ok( a.end.equals( one3 ), "Passed!" );
+});
+
+test( "at", function() {
+	var a = new THREE.Line3( one3.clone(), new THREE.Vector3( 1, 1, 2 ) );
+
+	ok( a.at( -1 ).distanceTo( new THREE.Vector3( 1, 1, 0 ) ) < 0.0001, "Passed!" );
+	ok( a.at( 0 ).distanceTo( one3.clone() ) < 0.0001, "Passed!" );
+	ok( a.at( 1 ).distanceTo( new THREE.Vector3( 1, 1, 2 ) ) < 0.0001, "Passed!" );
+	ok( a.at( 2 ).distanceTo( new THREE.Vector3( 1, 1, 3 ) ) < 0.0001, "Passed!" );
+});
+
+test( "closestPointToPoint/closestPointToPointParameter", function() {
+	var a = new THREE.Line3( one3.clone(), new THREE.Vector3( 1, 1, 2 ) );
+
+	// nearby the ray
+	ok( a.closestPointToPointParameter( zero3.clone(), true ) == 0, "Passed!" );
+	var b1 = a.closestPointToPoint( zero3.clone(), true );
+	ok( b1.distanceTo( new THREE.Vector3( 1, 1, 1 ) ) < 0.0001, "Passed!" );
+
+	// nearby the ray
+	ok( a.closestPointToPointParameter( zero3.clone(), false ) == -1, "Passed!" );
+	var b2 = a.closestPointToPoint( zero3.clone(), false );
+	console.log( b2 );
+	ok( b2.distanceTo( new THREE.Vector3( 1, 1, 0 ) ) < 0.0001, "Passed!" );
+
+	// nearby the ray
+	ok( a.closestPointToPointParameter( new THREE.Vector3( 1, 1, 5 ), true ) == 1, "Passed!" );
+	var b = a.closestPointToPoint( new THREE.Vector3( 1, 1, 5 ), true );
+	ok( b.distanceTo( new THREE.Vector3( 1, 1, 2 ) ) < 0.0001, "Passed!" );
+
+	// exactly on the ray
+	ok( a.closestPointToPointParameter( one3.clone(), true ) == 0, "Passed!" );
+	var c = a.closestPointToPoint( one3.clone(), true );
+	ok( c.distanceTo( one3.clone() ) < 0.0001, "Passed!" );
+});

+ 13 - 13
test/unit/math/Plane.js

@@ -131,28 +131,28 @@ test( "distanceToSphere", function() {
 test( "isInterestionLine/intersectLine", function() {
 test( "isInterestionLine/intersectLine", function() {
 	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
 	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
 
 
-	ok( a.isIntersectionLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ), "Passed!" );
-	ok( a.intersectLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
+	var l1 = new THREE.Line3( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) );
+	ok( a.isIntersectionLine( l1 ), "Passed!" );
+	ok( a.intersectLine( l1 ).equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
 
 
 	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), -3 );
 	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), -3 );
 
 
-	ok( a.isIntersectionLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ), "Passed!" );
-	ok( a.intersectLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ).equals( new THREE.Vector3( 3, 0, 0 ) ), "Passed!" );
+	ok( a.isIntersectionLine( l1 ), "Passed!" );
+	ok( a.intersectLine( l1 ).equals( new THREE.Vector3( 3, 0, 0 ) ), "Passed!" );
 
 
 
 
 	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), -11 );
 	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), -11 );
 
 
-	ok( ! a.isIntersectionLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ), "Passed!" );
-	ok( a.intersectLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ) === undefined, "Passed!" );
+	ok( ! a.isIntersectionLine( l1 ), "Passed!" );
+	ok( a.intersectLine( l1 ) === undefined, "Passed!" );
 	
 	
 	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 11 );
 	a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 11 );
 
 
-	ok( ! a.isIntersectionLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ), "Passed!" );
-	ok( a.intersectLine( new THREE.Vector3( -10, 0, 0 ), new THREE.Vector3( 10, 0, 0 ) ) === undefined, "Passed!" );
+	ok( ! a.isIntersectionLine( l1 ), "Passed!" );
+	ok( a.intersectLine( l1 ) === undefined, "Passed!" );
 
 
 });
 });
 
 
-
 test( "projectPoint", function() {
 test( "projectPoint", function() {
 	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
 	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
 
 
@@ -180,18 +180,18 @@ test( "coplanarPoint", function() {
 	ok( a.distanceToPoint( a.coplanarPoint() ) === 0, "Passed!" );
 	ok( a.distanceToPoint( a.coplanarPoint() ) === 0, "Passed!" );
 });
 });
 
 
-test( "transform/translate", function() {
+test( "applyMatrix4/translate", function() {
 
 
 	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
 	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
 
 
 	var m = new THREE.Matrix4();
 	var m = new THREE.Matrix4();
 	m.makeRotationZ( Math.PI * 0.5 );
 	m.makeRotationZ( Math.PI * 0.5 );
 
 
-	ok( comparePlane( a.clone().transform( m ), new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 0 ) ), "Passed!" );
+	ok( comparePlane( a.clone().applyMatrix4( m ), new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 0 ) ), "Passed!" );
 
 
 	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
 	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
-	ok( comparePlane( a.clone().transform( m ), new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), -1 ) ), "Passed!" );
+	ok( comparePlane( a.clone().applyMatrix4( m ), new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), -1 ) ), "Passed!" );
 
 
 	m.makeTranslation( 1, 1, 1 );
 	m.makeTranslation( 1, 1, 1 );
-	ok( comparePlane( a.clone().transform( m ), a.clone().translate( new THREE.Vector3( 1, 1, 1 ) ) ), "Passed!" );
+	ok( comparePlane( a.clone().applyMatrix4( m ), a.clone().translate( new THREE.Vector3( 1, 1, 1 ) ) ), "Passed!" );
 });
 });

+ 5 - 5
test/unit/math/Ray.js

@@ -149,26 +149,26 @@ test( "intersectPlane", function() {
 });
 });
 
 
 
 
-test( "transform", function() {
+test( "applyMatrix4", function() {
 	var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) );
 	var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) );
 	var m = new THREE.Matrix4().identity();
 	var m = new THREE.Matrix4().identity();
 
 
-	ok( a.clone().transform( m ).equals( a ), "Passed!" );
+	ok( a.clone().applyMatrix4( m ).equals( a ), "Passed!" );
 
 
 	a = new THREE.Ray( zero3.clone(), new THREE.Vector3( 0, 0, 1 ) );
 	a = new THREE.Ray( zero3.clone(), new THREE.Vector3( 0, 0, 1 ) );
 	m.rotateByAxis( new THREE.Vector3( 0, 0, 1 ), Math.PI );
 	m.rotateByAxis( new THREE.Vector3( 0, 0, 1 ), Math.PI );
-	ok( a.clone().transform( m ).equals( a ), "Passed!" );
+	ok( a.clone().applyMatrix4( m ).equals( a ), "Passed!" );
 
 
 	m.identity().rotateX( Math.PI );
 	m.identity().rotateX( Math.PI );
 	var b = a.clone();
 	var b = a.clone();
 	b.direction.negate();
 	b.direction.negate();
-	var a2 = a.clone().transform( m );
+	var a2 = a.clone().applyMatrix4( m );
 	ok( a2.origin.distanceTo( b.origin ) < 0.0001, "Passed!" );
 	ok( a2.origin.distanceTo( b.origin ) < 0.0001, "Passed!" );
 	ok( a2.direction.distanceTo( b.direction ) < 0.0001, "Passed!" );
 	ok( a2.direction.distanceTo( b.direction ) < 0.0001, "Passed!" );
 
 
 	a.origin = new THREE.Vector3( 0, 0, 1 );
 	a.origin = new THREE.Vector3( 0, 0, 1 );
 	b.origin = new THREE.Vector3( 0, 0, -1 );
 	b.origin = new THREE.Vector3( 0, 0, -1 );
-	var a2 = a.clone().transform( m );
+	var a2 = a.clone().applyMatrix4( m );
 	ok( a2.origin.distanceTo( b.origin ) < 0.0001, "Passed!" );
 	ok( a2.origin.distanceTo( b.origin ) < 0.0001, "Passed!" );
 	ok( a2.direction.distanceTo( b.direction ) < 0.0001, "Passed!" );
 	ok( a2.direction.distanceTo( b.direction ) < 0.0001, "Passed!" );
 });
 });

+ 13 - 13
test/unit/math/Sphere.js

@@ -9,13 +9,13 @@ test( "constructor", function() {
 	ok( a.center.equals( zero3 ), "Passed!" );
 	ok( a.center.equals( zero3 ), "Passed!" );
 	ok( a.radius == 0, "Passed!" );
 	ok( a.radius == 0, "Passed!" );
 
 
-	a = new THREE.Sphere( one3, 1 );
+	a = new THREE.Sphere( one3.clone(), 1 );
 	ok( a.center.equals( one3 ), "Passed!" );
 	ok( a.center.equals( one3 ), "Passed!" );
 	ok( a.radius == 1, "Passed!" );
 	ok( a.radius == 1, "Passed!" );
 });
 });
 
 
 test( "copy", function() {
 test( "copy", function() {
-	var a = new THREE.Sphere( one3, 1 );
+	var a = new THREE.Sphere( one3.clone(), 1 );
 	var b = new THREE.Sphere().copy( a );
 	var b = new THREE.Sphere().copy( a );
 
 
 	ok( b.center.equals( one3 ), "Passed!" );
 	ok( b.center.equals( one3 ), "Passed!" );
@@ -47,37 +47,37 @@ test( "empty", function() {
 });
 });
 
 
 test( "containsPoint", function() {
 test( "containsPoint", function() {
-	var a = new THREE.Sphere( one3, 1 );
+	var a = new THREE.Sphere( one3.clone(), 1 );
 
 
 	ok( ! a.containsPoint( zero3 ), "Passed!" );
 	ok( ! a.containsPoint( zero3 ), "Passed!" );
 	ok( a.containsPoint( one3 ), "Passed!" );
 	ok( a.containsPoint( one3 ), "Passed!" );
 });
 });
 
 
 test( "distanceToPoint", function() {
 test( "distanceToPoint", function() {
-	var a = new THREE.Sphere( one3, 1 );
+	var a = new THREE.Sphere( one3.clone(), 1 );
 
 
 	ok( ( a.distanceToPoint( zero3 ) - 0.7320 ) < 0.001, "Passed!" );
 	ok( ( a.distanceToPoint( zero3 ) - 0.7320 ) < 0.001, "Passed!" );
 	ok( a.distanceToPoint( one3 ) === -1, "Passed!" );
 	ok( a.distanceToPoint( one3 ) === -1, "Passed!" );
 });
 });
 
 
 test( "intersectsSphere", function() {
 test( "intersectsSphere", function() {
-	var a = new THREE.Sphere( one3, 1 );
-	var b = new THREE.Sphere( zero3, 1 );
-	var c = new THREE.Sphere( zero3, 0.25 );
+	var a = new THREE.Sphere( one3.clone(), 1 );
+	var b = new THREE.Sphere( zero3.clone(), 1 );
+	var c = new THREE.Sphere( zero3.clone(), 0.25 );
 
 
 	ok( a.intersectsSphere( b ) , "Passed!" );
 	ok( a.intersectsSphere( b ) , "Passed!" );
 	ok( ! a.intersectsSphere( c ) , "Passed!" );
 	ok( ! a.intersectsSphere( c ) , "Passed!" );
 });
 });
 
 
 test( "clampPoint", function() {
 test( "clampPoint", function() {
-	var a = new THREE.Sphere( one3, 1 );
+	var a = new THREE.Sphere( one3.clone(), 1 );
 
 
 	ok( a.clampPoint( new THREE.Vector3( 1, 1, 3 ) ).equals( new THREE.Vector3( 1, 1, 2 ) ), "Passed!" );
 	ok( a.clampPoint( new THREE.Vector3( 1, 1, 3 ) ).equals( new THREE.Vector3( 1, 1, 2 ) ), "Passed!" );
 	ok( a.clampPoint( new THREE.Vector3( 1, 1, -3 ) ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" );
 	ok( a.clampPoint( new THREE.Vector3( 1, 1, -3 ) ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" );
 });
 });
 
 
 test( "getBoundingBox", function() {
 test( "getBoundingBox", function() {
-	var a = new THREE.Sphere( one3, 1 );
+	var a = new THREE.Sphere( one3.clone(), 1 );
 
 
 	ok( a.getBoundingBox().equals( new THREE.Box3( zero3, two3 ) ), "Passed!" );
 	ok( a.getBoundingBox().equals( new THREE.Box3( zero3, two3 ) ), "Passed!" );
 
 
@@ -85,16 +85,16 @@ test( "getBoundingBox", function() {
 	ok( a.getBoundingBox().equals( new THREE.Box3( zero3, zero3 ) ), "Passed!" );
 	ok( a.getBoundingBox().equals( new THREE.Box3( zero3, zero3 ) ), "Passed!" );
 });
 });
 
 
-test( "transform", function() {
-	var a = new THREE.Sphere( one3, 1 );
+test( "applyMatrix4", function() {
+	var a = new THREE.Sphere( one3.clone(), 1 );
 
 
 	var m = new THREE.Matrix4().makeTranslation( 1, -2, 1 );
 	var m = new THREE.Matrix4().makeTranslation( 1, -2, 1 );
 
 
-	ok( a.clone().transform( m ).getBoundingBox().equals( a.getBoundingBox().transform( m ) ), "Passed!" );
+	ok( a.clone().applyMatrix4( m ).getBoundingBox().equals( a.getBoundingBox().applyMatrix4( m ) ), "Passed!" );
 });
 });
 
 
 test( "translate", function() {
 test( "translate", function() {
-	var a = new THREE.Sphere( one3, 1 );
+	var a = new THREE.Sphere( one3.clone(), 1 );
 
 
 	a.translate( one3.clone().negate() );
 	a.translate( one3.clone().negate() );
 	ok( a.center.equals( zero3 ), "Passed!" );
 	ok( a.center.equals( zero3 ), "Passed!" );

+ 2 - 2
test/unit/math/Triangle.js

@@ -10,14 +10,14 @@ test( "constructor", function() {
 	ok( a.b.equals( zero3 ), "Passed!" );
 	ok( a.b.equals( zero3 ), "Passed!" );
 	ok( a.c.equals( zero3 ), "Passed!" );
 	ok( a.c.equals( zero3 ), "Passed!" );
 
 
-	a = new THREE.Triangle( one3.clone().negate(), one3, two3 );
+	a = new THREE.Triangle( one3.clone().negate(), one3.clone(), two3.clone() );
 	ok( a.a.equals( one3.clone().negate() ), "Passed!" );
 	ok( a.a.equals( one3.clone().negate() ), "Passed!" );
 	ok( a.b.equals( one3 ), "Passed!" );
 	ok( a.b.equals( one3 ), "Passed!" );
 	ok( a.c.equals( two3 ), "Passed!" );
 	ok( a.c.equals( two3 ), "Passed!" );
 });
 });
 
 
 test( "copy", function() {
 test( "copy", function() {
-	var a = new THREE.Triangle( one3.clone().negate(), one3, two3 );
+	var a = new THREE.Triangle( one3.clone().negate(), one3.clone(), two3.clone() );
 	var b = new THREE.Triangle().copy( a );
 	var b = new THREE.Triangle().copy( a );
 	ok( b.a.equals( one3.clone().negate() ), "Passed!" );
 	ok( b.a.equals( one3.clone().negate() ), "Passed!" );
 	ok( b.b.equals( one3 ), "Passed!" );
 	ok( b.b.equals( one3 ), "Passed!" );

+ 3 - 1
test/unit/unittests_sources.html

@@ -17,6 +17,7 @@
   <script src="../../src/math/Vector2.js"></script>
   <script src="../../src/math/Vector2.js"></script>
   <script src="../../src/math/Vector3.js"></script>
   <script src="../../src/math/Vector3.js"></script>
   <script src="../../src/math/Vector4.js"></script>
   <script src="../../src/math/Vector4.js"></script>
+  <script src="../../src/math/Line3.js"></script>
   <script src="../../src/math/Box2.js"></script>
   <script src="../../src/math/Box2.js"></script>
   <script src="../../src/math/Box3.js"></script>
   <script src="../../src/math/Box3.js"></script>
   <script src="../../src/math/Matrix3.js"></script>
   <script src="../../src/math/Matrix3.js"></script>
@@ -25,7 +26,7 @@
   <script src="../../src/math/Frustum.js"></script>
   <script src="../../src/math/Frustum.js"></script>
   <script src="../../src/math/Plane.js"></script>
   <script src="../../src/math/Plane.js"></script>
   <script src="../../src/math/Sphere.js"></script>
   <script src="../../src/math/Sphere.js"></script>
-  <script src="../../src/math/Math.js"></script>
+  <script src="../../src/math/Math.js"></script>  
   <script src="../../src/math/Triangle.js"></script>
   <script src="../../src/math/Triangle.js"></script>
 
 
   <!-- add class-based unit tests below -->
   <!-- add class-based unit tests below -->
@@ -40,6 +41,7 @@
   <script src="math/Vector2.js"></script>
   <script src="math/Vector2.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector4.js"></script>
   <script src="math/Vector4.js"></script>
+  <script src="math/Line3.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix4.js"></script>
   <script src="math/Matrix4.js"></script>

+ 1 - 0
test/unit/unittests_three-math.html

@@ -25,6 +25,7 @@
   <script src="math/Vector2.js"></script>
   <script src="math/Vector2.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector4.js"></script>
   <script src="math/Vector4.js"></script>
+  <script src="math/Line3.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix4.js"></script>
   <script src="math/Matrix4.js"></script>

+ 1 - 0
test/unit/unittests_three.html

@@ -25,6 +25,7 @@
   <script src="math/Vector2.js"></script>
   <script src="math/Vector2.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector4.js"></script>
   <script src="math/Vector4.js"></script>
+  <script src="math/Line3.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix4.js"></script>
   <script src="math/Matrix4.js"></script>

+ 1 - 0
test/unit/unittests_three.min.html

@@ -25,6 +25,7 @@
   <script src="math/Vector2.js"></script>
   <script src="math/Vector2.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector3.js"></script>
   <script src="math/Vector4.js"></script>
   <script src="math/Vector4.js"></script>
+  <script src="math/Line3.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Quaternion.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix4.js"></script>
   <script src="math/Matrix4.js"></script>

+ 1 - 0
utils/build/includes/math.json

@@ -5,6 +5,7 @@
 	"src/math/Vector2.js",
 	"src/math/Vector2.js",
 	"src/math/Vector3.js",
 	"src/math/Vector3.js",
 	"src/math/Vector4.js",
 	"src/math/Vector4.js",
+	"src/math/Line3.js",
 	"src/math/Box2.js",
 	"src/math/Box2.js",
 	"src/math/Box3.js",
 	"src/math/Box3.js",
 	"src/math/Matrix3.js",
 	"src/math/Matrix3.js",