diff --git a/src/core/Frustum.js b/src/core/Frustum.js index e0bce4601b1f54aff773054d53341629f319bbff..6c3decef5d1f016a4e4a6dae561d98ff489d9cf2 100644 --- a/src/core/Frustum.js +++ b/src/core/Frustum.js @@ -1,18 +1,19 @@ /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ + * @author Ben Houston / ben@exocortex.com / http://github.com/bhouston */ THREE.Frustum = function ( ) { 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 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 ++ ) { - - 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 planes = this.planes; var matrix = object.matrixWorld; - var me = matrix.elements; + var matrixPosition = matrix.getPosition(); var radius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis(); 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; } diff --git a/src/core/Plane.js b/src/core/Plane.js new file mode 100644 index 0000000000000000000000000000000000000000..d8dc736d75c3c5e17056ad731c4ce6f9b3afab00 --- /dev/null +++ b/src/core/Plane.js @@ -0,0 +1,93 @@ +/** + * @author Ben Houston / ben@exocortex.com / 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 ) ); diff --git a/utils/includes/common.json b/utils/includes/common.json index 45c36b15ba9066f518dbc0e746fd20d3a9fff48e..fa753f7fd424a8db7a30613b88e35f416d6cc24a 100644 --- a/utils/includes/common.json +++ b/utils/includes/common.json @@ -10,6 +10,7 @@ "../src/core/Matrix4.js", "../src/core/EventTarget.js", "../src/core/Frustum.js", + "../src/core/Plane.js", "../src/core/Ray.js", "../src/core/Rectangle.js", "../src/core/Math.js",