424 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			424 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import {
							 | 
						||
| 
								 | 
							
									Box3,
							 | 
						||
| 
								 | 
							
									MathUtils,
							 | 
						||
| 
								 | 
							
									Matrix4,
							 | 
						||
| 
								 | 
							
									Matrix3,
							 | 
						||
| 
								 | 
							
									Ray,
							 | 
						||
| 
								 | 
							
									Vector3
							 | 
						||
| 
								 | 
							
								} from 'three';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// module scope helper variables
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const a = {
							 | 
						||
| 
								 | 
							
									c: null, // center
							 | 
						||
| 
								 | 
							
									u: [ new Vector3(), new Vector3(), new Vector3() ], // basis vectors
							 | 
						||
| 
								 | 
							
									e: [] // half width
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const b = {
							 | 
						||
| 
								 | 
							
									c: null, // center
							 | 
						||
| 
								 | 
							
									u: [ new Vector3(), new Vector3(), new Vector3() ], // basis vectors
							 | 
						||
| 
								 | 
							
									e: [] // half width
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const R = [[], [], []];
							 | 
						||
| 
								 | 
							
								const AbsR = [[], [], []];
							 | 
						||
| 
								 | 
							
								const t = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const xAxis = new Vector3();
							 | 
						||
| 
								 | 
							
								const yAxis = new Vector3();
							 | 
						||
| 
								 | 
							
								const zAxis = new Vector3();
							 | 
						||
| 
								 | 
							
								const v1 = new Vector3();
							 | 
						||
| 
								 | 
							
								const size = new Vector3();
							 | 
						||
| 
								 | 
							
								const closestPoint = new Vector3();
							 | 
						||
| 
								 | 
							
								const rotationMatrix = new Matrix3();
							 | 
						||
| 
								 | 
							
								const aabb = new Box3();
							 | 
						||
| 
								 | 
							
								const matrix = new Matrix4();
							 | 
						||
| 
								 | 
							
								const inverse = new Matrix4();
							 | 
						||
| 
								 | 
							
								const localRay = new Ray();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// OBB
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class OBB {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constructor( center = new Vector3(), halfSize = new Vector3(), rotation = new Matrix3() ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.center = center;
							 | 
						||
| 
								 | 
							
										this.halfSize = halfSize;
							 | 
						||
| 
								 | 
							
										this.rotation = rotation;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									set( center, halfSize, rotation ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.center = center;
							 | 
						||
| 
								 | 
							
										this.halfSize = halfSize;
							 | 
						||
| 
								 | 
							
										this.rotation = rotation;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									copy( obb ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.center.copy( obb.center );
							 | 
						||
| 
								 | 
							
										this.halfSize.copy( obb.halfSize );
							 | 
						||
| 
								 | 
							
										this.rotation.copy( obb.rotation );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									clone() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return new this.constructor().copy( this );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									getSize( result ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return result.copy( this.halfSize ).multiplyScalar( 2 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									* Reference: Closest Point on OBB to Point in Real-Time Collision Detection
							 | 
						||
| 
								 | 
							
									* by Christer Ericson (chapter 5.1.4)
							 | 
						||
| 
								 | 
							
									*/
							 | 
						||
| 
								 | 
							
									clampPoint( point, result ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const halfSize = this.halfSize;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										v1.subVectors( point, this.center );
							 | 
						||
| 
								 | 
							
										this.rotation.extractBasis( xAxis, yAxis, zAxis );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// start at the center position of the OBB
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										result.copy( this.center );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// project the target onto the OBB axes and walk towards that point
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const x = MathUtils.clamp( v1.dot( xAxis ), - halfSize.x, halfSize.x );
							 | 
						||
| 
								 | 
							
										result.add( xAxis.multiplyScalar( x ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const y = MathUtils.clamp( v1.dot( yAxis ), - halfSize.y, halfSize.y );
							 | 
						||
| 
								 | 
							
										result.add( yAxis.multiplyScalar( y ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const z = MathUtils.clamp( v1.dot( zAxis ), - halfSize.z, halfSize.z );
							 | 
						||
| 
								 | 
							
										result.add( zAxis.multiplyScalar( z ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return result;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									containsPoint( point ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										v1.subVectors( point, this.center );
							 | 
						||
| 
								 | 
							
										this.rotation.extractBasis( xAxis, yAxis, zAxis );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// project v1 onto each axis and check if these points lie inside the OBB
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return Math.abs( v1.dot( xAxis ) ) <= this.halfSize.x &&
							 | 
						||
| 
								 | 
							
												Math.abs( v1.dot( yAxis ) ) <= this.halfSize.y &&
							 | 
						||
| 
								 | 
							
												Math.abs( v1.dot( zAxis ) ) <= this.halfSize.z;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									intersectsBox3( box3 ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this.intersectsOBB( obb.fromBox3( box3 ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									intersectsSphere( sphere ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// find the point on the OBB closest to the sphere center
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.clampPoint( sphere.center, closestPoint );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// if that point is inside the sphere, the OBB and sphere intersect
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									* Reference: OBB-OBB Intersection in Real-Time Collision Detection
							 | 
						||
| 
								 | 
							
									* by Christer Ericson (chapter 4.4.1)
							 | 
						||
| 
								 | 
							
									*
							 | 
						||
| 
								 | 
							
									*/
							 | 
						||
| 
								 | 
							
									intersectsOBB( obb, epsilon = Number.EPSILON ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// prepare data structures (the code uses the same nomenclature like the reference)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										a.c = this.center;
							 | 
						||
| 
								 | 
							
										a.e[ 0 ] = this.halfSize.x;
							 | 
						||
| 
								 | 
							
										a.e[ 1 ] = this.halfSize.y;
							 | 
						||
| 
								 | 
							
										a.e[ 2 ] = this.halfSize.z;
							 | 
						||
| 
								 | 
							
										this.rotation.extractBasis( a.u[ 0 ], a.u[ 1 ], a.u[ 2 ] );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										b.c = obb.center;
							 | 
						||
| 
								 | 
							
										b.e[ 0 ] = obb.halfSize.x;
							 | 
						||
| 
								 | 
							
										b.e[ 1 ] = obb.halfSize.y;
							 | 
						||
| 
								 | 
							
										b.e[ 2 ] = obb.halfSize.z;
							 | 
						||
| 
								 | 
							
										obb.rotation.extractBasis( b.u[ 0 ], b.u[ 1 ], b.u[ 2 ] );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// compute rotation matrix expressing b in a's coordinate frame
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( let i = 0; i < 3; i ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for ( let j = 0; j < 3; j ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												R[ i ][ j ] = a.u[ i ].dot( b.u[ j ] );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// compute translation vector
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										v1.subVectors( b.c, a.c );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// bring translation into a's coordinate frame
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										t[ 0 ] = v1.dot( a.u[ 0 ] );
							 | 
						||
| 
								 | 
							
										t[ 1 ] = v1.dot( a.u[ 1 ] );
							 | 
						||
| 
								 | 
							
										t[ 2 ] = v1.dot( a.u[ 2 ] );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// compute common subexpressions. Add in an epsilon term to
							 | 
						||
| 
								 | 
							
										// counteract arithmetic errors when two edges are parallel and
							 | 
						||
| 
								 | 
							
										// their cross product is (near) null
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( let i = 0; i < 3; i ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for ( let j = 0; j < 3; j ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												AbsR[ i ][ j ] = Math.abs( R[ i ][ j ] ) + epsilon;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										let ra, rb;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axes L = A0, L = A1, L = A2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( let i = 0; i < 3; i ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											ra = a.e[ i ];
							 | 
						||
| 
								 | 
							
											rb = b.e[ 0 ] * AbsR[ i ][ 0 ] + b.e[ 1 ] * AbsR[ i ][ 1 ] + b.e[ 2 ] * AbsR[ i ][ 2 ];
							 | 
						||
| 
								 | 
							
											if ( Math.abs( t[ i ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axes L = B0, L = B1, L = B2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( let i = 0; i < 3; i ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											ra = a.e[ 0 ] * AbsR[ 0 ][ i ] + a.e[ 1 ] * AbsR[ 1 ][ i ] + a.e[ 2 ] * AbsR[ 2 ][ i ];
							 | 
						||
| 
								 | 
							
											rb = b.e[ i ];
							 | 
						||
| 
								 | 
							
											if ( Math.abs( t[ 0 ] * R[ 0 ][ i ] + t[ 1 ] * R[ 1 ][ i ] + t[ 2 ] * R[ 2 ][ i ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A0 x B0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 1 ] * AbsR[ 2 ][ 0 ] + a.e[ 2 ] * AbsR[ 1 ][ 0 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 1 ] * AbsR[ 0 ][ 2 ] + b.e[ 2 ] * AbsR[ 0 ][ 1 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 2 ] * R[ 1 ][ 0 ] - t[ 1 ] * R[ 2 ][ 0 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A0 x B1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 1 ] * AbsR[ 2 ][ 1 ] + a.e[ 2 ] * AbsR[ 1 ][ 1 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 0 ] * AbsR[ 0 ][ 2 ] + b.e[ 2 ] * AbsR[ 0 ][ 0 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 2 ] * R[ 1 ][ 1 ] - t[ 1 ] * R[ 2 ][ 1 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A0 x B2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 1 ] * AbsR[ 2 ][ 2 ] + a.e[ 2 ] * AbsR[ 1 ][ 2 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 0 ] * AbsR[ 0 ][ 1 ] + b.e[ 1 ] * AbsR[ 0 ][ 0 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 2 ] * R[ 1 ][ 2 ] - t[ 1 ] * R[ 2 ][ 2 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A1 x B0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 0 ] * AbsR[ 2 ][ 0 ] + a.e[ 2 ] * AbsR[ 0 ][ 0 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 1 ] * AbsR[ 1 ][ 2 ] + b.e[ 2 ] * AbsR[ 1 ][ 1 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 0 ] * R[ 2 ][ 0 ] - t[ 2 ] * R[ 0 ][ 0 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A1 x B1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 0 ] * AbsR[ 2 ][ 1 ] + a.e[ 2 ] * AbsR[ 0 ][ 1 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 0 ] * AbsR[ 1 ][ 2 ] + b.e[ 2 ] * AbsR[ 1 ][ 0 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 0 ] * R[ 2 ][ 1 ] - t[ 2 ] * R[ 0 ][ 1 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A1 x B2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 0 ] * AbsR[ 2 ][ 2 ] + a.e[ 2 ] * AbsR[ 0 ][ 2 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 0 ] * AbsR[ 1 ][ 1 ] + b.e[ 1 ] * AbsR[ 1 ][ 0 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 0 ] * R[ 2 ][ 2 ] - t[ 2 ] * R[ 0 ][ 2 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A2 x B0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 0 ] * AbsR[ 1 ][ 0 ] + a.e[ 1 ] * AbsR[ 0 ][ 0 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 1 ] * AbsR[ 2 ][ 2 ] + b.e[ 2 ] * AbsR[ 2 ][ 1 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 1 ] * R[ 0 ][ 0 ] - t[ 0 ] * R[ 1 ][ 0 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A2 x B1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 0 ] * AbsR[ 1 ][ 1 ] + a.e[ 1 ] * AbsR[ 0 ][ 1 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 0 ] * AbsR[ 2 ][ 2 ] + b.e[ 2 ] * AbsR[ 2 ][ 0 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 1 ] * R[ 0 ][ 1 ] - t[ 0 ] * R[ 1 ][ 1 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// test axis L = A2 x B2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ra = a.e[ 0 ] * AbsR[ 1 ][ 2 ] + a.e[ 1 ] * AbsR[ 0 ][ 2 ];
							 | 
						||
| 
								 | 
							
										rb = b.e[ 0 ] * AbsR[ 2 ][ 1 ] + b.e[ 1 ] * AbsR[ 2 ][ 0 ];
							 | 
						||
| 
								 | 
							
										if ( Math.abs( t[ 1 ] * R[ 0 ][ 2 ] - t[ 0 ] * R[ 1 ][ 2 ] ) > ra + rb ) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// since no separating axis is found, the OBBs must be intersecting
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									* Reference: Testing Box Against Plane in Real-Time Collision Detection
							 | 
						||
| 
								 | 
							
									* by Christer Ericson (chapter 5.2.3)
							 | 
						||
| 
								 | 
							
									*/
							 | 
						||
| 
								 | 
							
									intersectsPlane( plane ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.rotation.extractBasis( xAxis, yAxis, zAxis );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// compute the projection interval radius of this OBB onto L(t) = this->center + t * p.normal;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const r = this.halfSize.x * Math.abs( plane.normal.dot( xAxis ) ) +
							 | 
						||
| 
								 | 
							
												this.halfSize.y * Math.abs( plane.normal.dot( yAxis ) ) +
							 | 
						||
| 
								 | 
							
												this.halfSize.z * Math.abs( plane.normal.dot( zAxis ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// compute distance of the OBB's center from the plane
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const d = plane.normal.dot( this.center ) - plane.constant;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Intersection occurs when distance d falls within [-r,+r] interval
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return Math.abs( d ) <= r;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									* Performs a ray/OBB intersection test and stores the intersection point
							 | 
						||
| 
								 | 
							
									* to the given 3D vector. If no intersection is detected, *null* is returned.
							 | 
						||
| 
								 | 
							
									*/
							 | 
						||
| 
								 | 
							
									intersectRay( ray, result ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// the idea is to perform the intersection test in the local space
							 | 
						||
| 
								 | 
							
										// of the OBB.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.getSize( size );
							 | 
						||
| 
								 | 
							
										aabb.setFromCenterAndSize( v1.set( 0, 0, 0 ), size );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// create a 4x4 transformation matrix
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										matrix.setFromMatrix3( this.rotation );
							 | 
						||
| 
								 | 
							
										matrix.setPosition( this.center );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// transform ray to the local space of the OBB
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										inverse.copy( matrix ).invert();
							 | 
						||
| 
								 | 
							
										localRay.copy( ray ).applyMatrix4( inverse );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// perform ray <-> AABB intersection test
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( localRay.intersectBox( aabb, result ) ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// transform the intersection point back to world space
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return result.applyMatrix4( matrix );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									* Performs a ray/OBB intersection test. Returns either true or false if
							 | 
						||
| 
								 | 
							
									* there is a intersection or not.
							 | 
						||
| 
								 | 
							
									*/
							 | 
						||
| 
								 | 
							
									intersectsRay( ray ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this.intersectRay( ray, v1 ) !== null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									fromBox3( box3 ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										box3.getCenter( this.center );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										box3.getSize( this.halfSize ).multiplyScalar( 0.5 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.rotation.identity();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									equals( obb ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return obb.center.equals( this.center ) &&
							 | 
						||
| 
								 | 
							
											obb.halfSize.equals( this.halfSize ) &&
							 | 
						||
| 
								 | 
							
											obb.rotation.equals( this.rotation );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									applyMatrix4( matrix ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const e = matrix.elements;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										let sx = v1.set( e[ 0 ], e[ 1 ], e[ 2 ] ).length();
							 | 
						||
| 
								 | 
							
										const sy = v1.set( e[ 4 ], e[ 5 ], e[ 6 ] ).length();
							 | 
						||
| 
								 | 
							
										const sz = v1.set( e[ 8 ], e[ 9 ], e[ 10 ] ).length();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const det = matrix.determinant();
							 | 
						||
| 
								 | 
							
										if ( det < 0 ) sx = - sx;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										rotationMatrix.setFromMatrix4( matrix );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const invSX = 1 / sx;
							 | 
						||
| 
								 | 
							
										const invSY = 1 / sy;
							 | 
						||
| 
								 | 
							
										const invSZ = 1 / sz;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 0 ] *= invSX;
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 1 ] *= invSX;
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 2 ] *= invSX;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 3 ] *= invSY;
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 4 ] *= invSY;
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 5 ] *= invSY;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 6 ] *= invSZ;
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 7 ] *= invSZ;
							 | 
						||
| 
								 | 
							
										rotationMatrix.elements[ 8 ] *= invSZ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.rotation.multiply( rotationMatrix );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.halfSize.x *= sx;
							 | 
						||
| 
								 | 
							
										this.halfSize.y *= sy;
							 | 
						||
| 
								 | 
							
										this.halfSize.z *= sz;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										v1.setFromMatrixPosition( matrix );
							 | 
						||
| 
								 | 
							
										this.center.add( v1 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const obb = new OBB();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export { OBB };
							 |