Browse Source

implement Plane.js, add to common.js and update Frustum.js to use it instead of Vector4 - issue #2706

Ben Houston 12 years ago
parent
commit
717e9ab6a4
3 changed files with 110 additions and 18 deletions
  1. 16 18
      src/core/Frustum.js
  2. 93 0
      src/core/Plane.js
  3. 1 0
      utils/includes/common.json

+ 16 - 18
src/core/Frustum.js

@@ -1,18 +1,19 @@
 /**
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
+ * @author Ben Houston / [email protected] / http://github.com/bhouston
  */
  */
 
 
 THREE.Frustum = function ( ) {
 THREE.Frustum = function ( ) {
 
 
 	this.planes = [
 	this.planes = [
 
 
-		new THREE.Vector4(),
-		new THREE.Vector4(),
-		new THREE.Vector4(),
-		new THREE.Vector4(),
-		new THREE.Vector4(),
-		new THREE.Vector4()
+		new THREE.Plane(),
+		new THREE.Plane(),
+		new THREE.Plane(),
+		new THREE.Plane(),
+		new THREE.Plane(),
+		new THREE.Plane()
 
 
 	];
 	];
 
 
@@ -29,18 +30,15 @@ THREE.Frustum.prototype.setFromMatrix = function ( m ) {
 	var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
 	var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
 	var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
 	var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
 
 
-	planes[ 0 ].set( me3 - me0, me7 - me4, me11 - me8, me15 - me12 );
-	planes[ 1 ].set( me3 + me0, me7 + me4, me11 + me8, me15 + me12 );
-	planes[ 2 ].set( me3 + me1, me7 + me5, me11 + me9, me15 + me13 );
-	planes[ 3 ].set( me3 - me1, me7 - me5, me11 - me9, me15 - me13 );
-	planes[ 4 ].set( me3 - me2, me7 - me6, me11 - me10, me15 - me14 );
-	planes[ 5 ].set( me3 + me2, me7 + me6, me11 + me10, me15 + me14 );
+	planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 );
+	planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 );
+	planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 );
+	planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 );
+	planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 );
+	planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 );
 
 
 	for ( var i = 0; i < 6; i ++ ) {
 	for ( var i = 0; i < 6; i ++ ) {
-
-		plane = planes[ i ];
-		plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
-
+		planes[ i ].normalize();
 	}
 	}
 
 
 };
 };
@@ -50,12 +48,12 @@ THREE.Frustum.prototype.contains = function ( object ) {
 	var distance = 0.0;
 	var distance = 0.0;
 	var planes = this.planes;
 	var planes = this.planes;
 	var matrix = object.matrixWorld;
 	var matrix = object.matrixWorld;
-	var me = matrix.elements;
+	var matrixPosition = matrix.getPosition();
 	var radius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis();
 	var radius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis();
 
 
 	for ( var i = 0; i < 6; i ++ ) {
 	for ( var i = 0; i < 6; i ++ ) {
 
 
-		distance = planes[ i ].x * me[12] + planes[ i ].y * me[13] + planes[ i ].z * me[14] + planes[ i ].w;
+		distance = planes[ i ].distanceToPoint( matrixPosition );
 		if ( distance <= radius ) return false;
 		if ( distance <= radius ) return false;
 
 
 	}
 	}

+ 93 - 0
src/core/Plane.js

@@ -0,0 +1,93 @@
+/**
+ * @author Ben Houston / [email protected] / http://github.com/bhouston
+ */
+
+( function ( THREE ) {
+
+	THREE.Plane = function ( normal, constant ) {
+		// TODO: ensure that normal is of length 1 and if it isn't readjust both normal and constant?
+		this.normal = normal || new THREE.Vector3();
+		this.constant = constant || 0;
+
+	};
+
+	THREE.Plane.prototype.set = function ( normal, constant ) {
+
+		// TODO: ensure that normal is of length 1 and if it isn't readjust both normal and constant?
+		this.normal = normal;
+		this.constant = constant;
+
+		return this;
+	};
+
+	THREE.Plane.prototype.setComponents = function ( x, y, z, w ) {
+
+		// TODO: ensure that normal is of length 1 and if it isn't readjust both normal and constant?
+		this.normal.x = x;
+		this.normal.y = y;
+		this.normal.z = z;
+		this.constant = w;
+
+		return this;
+	};
+
+	THREE.Plane.prototype.flip = function () {
+
+		// Note: can also be flipped by inverting constant, but I like constant to stay positive generally.
+		this.normal.negate();
+
+		return this;
+	};
+
+	THREE.Plane.prototype.normalize = function () {
+
+		// Note: will lead to a divide by zero if the plane is invalid.
+		var inverseNormalLength = 1.0 / this.normal.length()
+		this.normal.multipleByScalar( inverseNormalLength );
+		this.constant *= inverseNormalLength;
+
+		return this;
+	};
+
+	THREE.Plane.prototype.distanceToPoint = function ( point ) {
+
+		return this.normal.dot( point ) + this.constant;
+	};
+
+	THREE.Plane.prototype.projectPoint = function ( point ) {		
+
+		var perpendicularMagnitude = this.distanceToPoint( point );
+
+		return new THREE.Vector3(
+			point.x - this.normal.x * perpendicularMagnitude,
+			point.y - this.normal.y * perpendicularMagnitude,
+			point.z - this.normal.z * perpendicularMagnitude
+			);
+	};
+
+	THREE.Plane.prototype.orthoPoint = function ( point ) {		
+
+		var perpendicularMagnitude = this.distanceToPoint( point );
+
+		return new THREE.Vector3(
+			this.normal.x * perpendicularMagnitude,
+			this.normal.y * perpendicularMagnitude,
+			this.normal.z * perpendicularMagnitude
+			);
+	};
+
+	THREE.Plane.prototype.intersectsLine = function ( startPoint, endPoint ) {	
+
+		// 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 );
+
+		return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
+	};
+
+	THREE.Plane.prototype.coplanarPoint = function () {		
+		
+		return this.projectPoint( new THREE.Vector3( 0,0,0 ) );
+	};
+
+}( THREE ) );

+ 1 - 0
utils/includes/common.json

@@ -10,6 +10,7 @@
 	"../src/core/Matrix4.js",
 	"../src/core/Matrix4.js",
 	"../src/core/EventTarget.js",
 	"../src/core/EventTarget.js",
 	"../src/core/Frustum.js",
 	"../src/core/Frustum.js",
+	"../src/core/Plane.js",
 	"../src/core/Ray.js",
 	"../src/core/Ray.js",
 	"../src/core/Rectangle.js",
 	"../src/core/Rectangle.js",
 	"../src/core/Math.js",
 	"../src/core/Math.js",