123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- import { Matrix3 } from './Matrix3.js';
- import { Vector3 } from './Vector3.js';
- const _vector1 = /*@__PURE__*/ new Vector3();
- const _vector2 = /*@__PURE__*/ new Vector3();
- const _normalMatrix = /*@__PURE__*/ new Matrix3();
- class Plane {
- constructor( normal = new Vector3( 1, 0, 0 ), constant = 0 ) {
- this.isPlane = true;
- // normal is assumed to be normalized
- this.normal = normal;
- this.constant = constant;
- }
- set( normal, constant ) {
- this.normal.copy( normal );
- this.constant = constant;
- return this;
- }
- setComponents( x, y, z, w ) {
- this.normal.set( x, y, z );
- this.constant = w;
- return this;
- }
- setFromNormalAndCoplanarPoint( normal, point ) {
- this.normal.copy( normal );
- this.constant = - point.dot( this.normal );
- return this;
- }
- setFromCoplanarPoints( a, b, c ) {
- const normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize();
- // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
- this.setFromNormalAndCoplanarPoint( normal, a );
- return this;
- }
- copy( plane ) {
- this.normal.copy( plane.normal );
- this.constant = plane.constant;
- return this;
- }
- normalize() {
- // Note: will lead to a divide by zero if the plane is invalid.
- const inverseNormalLength = 1.0 / this.normal.length();
- this.normal.multiplyScalar( inverseNormalLength );
- this.constant *= inverseNormalLength;
- return this;
- }
- negate() {
- this.constant *= - 1;
- this.normal.negate();
- return this;
- }
- distanceToPoint( point ) {
- return this.normal.dot( point ) + this.constant;
- }
- distanceToSphere( sphere ) {
- return this.distanceToPoint( sphere.center ) - sphere.radius;
- }
- projectPoint( point, target ) {
- return target.copy( point ).addScaledVector( this.normal, - this.distanceToPoint( point ) );
- }
- intersectLine( line, target ) {
- const direction = line.delta( _vector1 );
- const denominator = this.normal.dot( direction );
- if ( denominator === 0 ) {
- // line is coplanar, return origin
- if ( this.distanceToPoint( line.start ) === 0 ) {
- return target.copy( line.start );
- }
- // Unsure if this is the correct method to handle this case.
- return null;
- }
- const t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
- if ( t < 0 || t > 1 ) {
- return null;
- }
- return target.copy( line.start ).addScaledVector( direction, t );
- }
- intersectsLine( line ) {
- // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
- const startSign = this.distanceToPoint( line.start );
- const endSign = this.distanceToPoint( line.end );
- return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
- }
- intersectsBox( box ) {
- return box.intersectsPlane( this );
- }
- intersectsSphere( sphere ) {
- return sphere.intersectsPlane( this );
- }
- coplanarPoint( target ) {
- return target.copy( this.normal ).multiplyScalar( - this.constant );
- }
- applyMatrix4( matrix, optionalNormalMatrix ) {
- const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix );
- const referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix );
- const normal = this.normal.applyMatrix3( normalMatrix ).normalize();
- this.constant = - referencePoint.dot( normal );
- return this;
- }
- translate( offset ) {
- this.constant -= offset.dot( this.normal );
- return this;
- }
- equals( plane ) {
- return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
- }
- clone() {
- return new this.constructor().copy( this );
- }
- }
- export { Plane };
|