Mr.doob 12 anni fa
parent
commit
8d55e8114e
2 ha cambiato i file con 188 aggiunte e 66 eliminazioni
  1. 181 60
      build/three.js
  2. 7 6
      build/three.min.js

+ 181 - 60
build/three.js

@@ -5011,7 +5011,7 @@ THREE.Ray.prototype = {
 
 	},
 
-	at: function( t, optionalTarget ) {
+	at: function ( t, optionalTarget ) {
 
 		var result = optionalTarget || new THREE.Vector3();
 
@@ -5019,7 +5019,7 @@ THREE.Ray.prototype = {
 
 	},
 
-	recast: function() {
+	recast: function () {
 
 		var v1 = new THREE.Vector3();
 
@@ -5043,7 +5043,7 @@ THREE.Ray.prototype = {
 
 	},
 
-	distanceToPoint: function() {
+	distanceToPoint: function () {
 
 		var v1 = new THREE.Vector3();
 
@@ -5058,13 +5058,15 @@ THREE.Ray.prototype = {
 
 	}(),
 
-	distanceSqAndPointToSegment: function( v0, v1, optionalPointOnLine, optionalPointOnSegment ) {
+	distanceSqAndPointToSegment: function ( v0, v1, optionalPointOnLine, optionalPointOnSegment ) {
+
 		// from http://www.geometrictools.com/LibMathematics/Distance/Wm5DistLine3Segment3.cpp
 		// It returns the min distance between the ray (actually... the line) and the segment
 		// defined by v0 and v1
 		// It can also set two optional targets :
 		// - The closest point on the ray (...line)
 		// - The closest point on the segment
+
 		var segCenter = v0.clone().add( v1 ).multiplyScalar( 0.5 );
 		var segDir = v1.clone().sub( v0 ).normalize();
 		var segExtent = v0.distanceTo( v1 ) *0.5;
@@ -5074,53 +5076,79 @@ THREE.Ray.prototype = {
 		var c = diff.lengthSq();
 		var det = Math.abs( 1 - a01 * a01 );
 		var b1, s0, s1, sqrDist, extDet;
-		if( det >= 0 ) {
+
+		if ( det >= 0 ) {
+
 			// The line and segment are not parallel.
+
 			b1 = -diff.dot( segDir );
 			s1 = a01 * b0 - b1;
 			extDet = segExtent * det;
-			if( s1 >= -extDet ) {
-				if( s1 <= extDet ) {
+
+			if ( s1 >= -extDet ) {
+
+				if ( s1 <= extDet ) {
+
 					// Two interior points are closest, one on the line and one
 					// on the segment.
+
 					var invDet = 1 / det;
 					s0 = ( a01 * b1 - b0 ) * invDet;
 					s1 *= invDet;
 					sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
-				}
-				else {
+
+				} else {
+
 					// The endpoint e1 of the segment and an interior point of
 					// the line are closest.
+
 					s1 = segExtent;
 					s0 = - ( a01 * s1 + b0 );
 					sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
+
 				}
-			}
-			else {
+
+			} else {
+
 				// The end point e0 of the segment and an interior point of the
 				// line are closest.
+
 				s1 = - segExtent;
 				s0 = - ( a01 * s1 + b0 );
 				sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
+
 			}
-		}
-		else {
+
+		} else {
+
 			// The line and segment are parallel.  Choose the closest pair so that
 			// one point is at segment center.
+
 			s1 = 0;
 			s0 = - b0;
 			sqrDist = b0 * s0 + c;
+
 		}
-		if(optionalPointOnLine)
+
+		if ( optionalPointOnLine ) {
+
 			optionalPointOnLine.copy( this.direction.clone().multiplyScalar( s0 ).add( this.origin ) );
-		if(optionalPointOnSegment)
+
+		}
+
+		if ( optionalPointOnSegment ) {
+
 			optionalPointOnSegment.copy( segDir.clone().multiplyScalar( s1 ).add( segCenter ) );
+
+		}
+
 		return sqrDist;
+
 	},
 
-	isIntersectionSphere: function( sphere ) {
+	isIntersectionSphere: function ( sphere ) {
 
-		return ( this.distanceToPoint( sphere.center ) <= sphere.radius );
+		return this.distanceToPoint( sphere.center ) <= sphere.radius;
 
 	},
 
@@ -5128,7 +5156,9 @@ THREE.Ray.prototype = {
 
 		// check if the line and plane are non-perpendicular, if they
 		// eventually they will intersect.
+
 		var denominator = plane.normal.dot( this.direction );
+
 		if ( denominator != 0 ) {
 
 			return true;
@@ -5475,6 +5505,44 @@ THREE.Frustum.prototype = {
 
 	},
 
+	intersectsBox : function() {
+
+		var p1 = new THREE.Vector3(),
+			p2 = new THREE.Vector3();
+
+		return function( box ) {
+
+			var planes = this.planes;
+			
+			for ( var i = 0; i < 6 ; i ++ ) {
+			
+				var plane = planes[i];
+				
+				p1.x = plane.normal.x > 0 ? box.min.x : box.max.x;
+				p2.x = plane.normal.x > 0 ? box.max.x : box.min.x;
+				p1.y = plane.normal.y > 0 ? box.min.y : box.max.y;
+				p2.y = plane.normal.y > 0 ? box.max.y : box.min.y;
+				p1.z = plane.normal.z > 0 ? box.min.z : box.max.z;
+				p2.z = plane.normal.z > 0 ? box.max.z : box.min.z;
+
+				var d1 = plane.distanceToPoint( p1 );
+				var d2 = plane.distanceToPoint( p2 );
+				
+				// if both outside plane, no intersection
+
+				if ( d1 < 0 && d2 < 0 ) {
+					
+					return false;
+		
+				}
+			}
+
+			return true;
+		};
+
+	}(),
+
+
 	containsPoint: function ( point ) {
 
 		var planes = this.planes;
@@ -6495,7 +6563,7 @@ THREE.EventDispatcher.prototype = {
 
 			intersectObject( object.getObjectForDistance( distance ), raycaster, intersects );
 
-		} else if (object instanceof THREE.Mesh ) {
+		} else if ( object instanceof THREE.Mesh ) {
 
 			var geometry = object.geometry;
 
@@ -6519,7 +6587,7 @@ THREE.EventDispatcher.prototype = {
 				var material = object.material;
 
 				if ( material === undefined ) return intersects;
-				if ( ! geometry.dynamic ) return intersects;
+				if ( geometry.dynamic === false ) return intersects;
 
 				var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 				var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
@@ -6535,6 +6603,7 @@ THREE.EventDispatcher.prototype = {
 
 				var fl;
 				var indexed = false;
+
 				if ( geometry.attributes.index ) {
 
 					indexed = true;
@@ -6543,6 +6612,7 @@ THREE.EventDispatcher.prototype = {
 				} else {
 
 					fl = geometry.attributes.position.numItems / 9;
+
 				}
 
 				var vA = new THREE.Vector3();
@@ -6560,24 +6630,34 @@ THREE.EventDispatcher.prototype = {
 					for ( var i = start, il = start + count; i < il; i += 3 ) {
 
 						if ( indexed ) {
+
 							a = index + geometry.attributes.index.array[ i ];
 							b = index + geometry.attributes.index.array[ i + 1 ];
 							c = index + geometry.attributes.index.array[ i + 2 ];
+
 						} else {
+
 							a = index;
 							b = index + 1;
 							c = index + 2;
+
 						}
 
-						vA.set( geometry.attributes.position.array[ a * 3 ],
-								geometry.attributes.position.array[ a * 3 + 1 ],
-								geometry.attributes.position.array[ a * 3 + 2] );
-						vB.set( geometry.attributes.position.array[ b * 3 ],
-								geometry.attributes.position.array[ b * 3 + 1 ],
-								geometry.attributes.position.array[ b * 3 + 2] );
-						vC.set( geometry.attributes.position.array[ c * 3 ],
-								geometry.attributes.position.array[ c * 3 + 1 ],
-								geometry.attributes.position.array[ c * 3 + 2 ] );
+						vA.set(
+							geometry.attributes.position.array[ a * 3 ],
+							geometry.attributes.position.array[ a * 3 + 1 ],
+							geometry.attributes.position.array[ a * 3 + 2 ]
+						);
+						vB.set(
+							geometry.attributes.position.array[ b * 3 ],
+							geometry.attributes.position.array[ b * 3 + 1 ],
+							geometry.attributes.position.array[ b * 3 + 2 ]
+						);
+						vC.set(
+							geometry.attributes.position.array[ c * 3 ],
+							geometry.attributes.position.array[ c * 3 + 1 ],
+							geometry.attributes.position.array[ c * 3 + 2 ]
+						);
 
 						facePlane.setFromCoplanarPoints( vA, vB, vC );
 
@@ -6591,25 +6671,43 @@ THREE.EventDispatcher.prototype = {
 
 						// check if we hit the wrong side of a single sided face
 						side = material.side;
+
 						if ( side !== THREE.DoubleSide ) {
 
 							var planeSign = localRay.direction.dot( facePlane.normal );
+							
 
-							if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) continue;
+							if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) {
+
+								continue;
+
+							}
 
 						}
 
-						// this can be done using the planeDistance from localRay because localRay wasn't normalized, but ray was
-						if ( planeDistance < raycaster.near || planeDistance > raycaster.far ) continue;
+						// this can be done using the planeDistance from localRay because
+						// localRay wasn't normalized, but ray was
+						if ( planeDistance < raycaster.near || planeDistance > raycaster.far ) {
 
-						intersectPoint = localRay.at( planeDistance, intersectPoint ); // passing in intersectPoint avoids a copy
+							continue;
+
+						}
+
+						// passing in intersectPoint avoids a copy
+						intersectPoint = localRay.at( planeDistance, intersectPoint );
+
+						if ( THREE.Triangle.containsPoint( intersectPoint, vA, vB, vC ) === false ) {
+
+							continue;
 
-						if ( ! THREE.Triangle.containsPoint( intersectPoint, vA, vB, vC ) ) continue;
+						}
 
 						intersects.push( {
 
-							distance: planeDistance, // this works because the original ray was normalized, and the transformed localRay wasn't
-							point: raycaster.ray.at(planeDistance),
+							// this works because the original ray was normalized,
+							// and the transformed localRay wasn't
+							distance: planeDistance,
+							point: raycaster.ray.at( planeDistance ),
 							face: null,
 							faceIndex: null,
 							object: object
@@ -6657,14 +6755,20 @@ THREE.EventDispatcher.prototype = {
 
 						var planeSign = localRay.direction.dot( facePlane.normal );
 
-						if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) continue;
+						if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) {
+
+							continue;
+
+						}
 
 					}
 
-					// this can be done using the planeDistance from localRay because localRay wasn't normalized, but ray was
+					// this can be done using the planeDistance from localRay because localRay
+					// wasn't normalized, but ray was
 					if ( planeDistance < raycaster.near || planeDistance > raycaster.far ) continue;
 
-					intersectPoint = localRay.at( planeDistance, intersectPoint ); // passing in intersectPoint avoids a copy
+					// passing in intersectPoint avoids a copy
+					intersectPoint = localRay.at( planeDistance, intersectPoint );
 
 					if ( face instanceof THREE.Face3 ) {
 
@@ -6672,7 +6776,11 @@ THREE.EventDispatcher.prototype = {
 						b = vertices[ face.b ];
 						c = vertices[ face.c ];
 
-						if ( ! THREE.Triangle.containsPoint( intersectPoint, a, b, c ) ) continue;
+						if ( THREE.Triangle.containsPoint( intersectPoint, a, b, c ) === false ) {
+
+							continue;
+
+						}
 
 					} else if ( face instanceof THREE.Face4 ) {
 
@@ -6681,20 +6789,27 @@ THREE.EventDispatcher.prototype = {
 						c = vertices[ face.c ];
 						d = vertices[ face.d ];
 
-						if ( ( ! THREE.Triangle.containsPoint( intersectPoint, a, b, d ) ) &&
-							 ( ! THREE.Triangle.containsPoint( intersectPoint, b, c, d ) ) ) continue;
+						if ( THREE.Triangle.containsPoint( intersectPoint, a, b, d ) === false &&
+						     THREE.Triangle.containsPoint( intersectPoint, b, c, d ) === false ) {
+
+							continue;
+
+						}
 
 					} else {
 
-						// This is added because if we call out of this if/else group when none of the cases
-						//    match it will add a point to the intersection list erroneously.
+						// This is added because if we call out of this if/else group when
+						// none of the cases match it will add a point to the intersection
+						// list erroneously.
 						throw Error( "face type not supported" );
 
 					}
 
 					intersects.push( {
 
-						distance: planeDistance,    // this works because the original ray was normalized, and the transformed localRay wasn't
+						// this works because the original ray was normalized,
+						// and the transformed localRay wasn't
+						distance: planeDistance,
 						point: raycaster.ray.at( planeDistance ),
 						face: face,
 						faceIndex: f,
@@ -6706,12 +6821,9 @@ THREE.EventDispatcher.prototype = {
 
 			}
 
-		} else if (object instanceof THREE.Line) {
+		} else if ( object instanceof THREE.Line ) {
 
 			var precision = raycaster.linePrecision;
-			if(precision < 0)
-				return intersects;
-
 			var precisionSq = precision * precision;
 
 			var geometry = object.geometry;
@@ -6720,13 +6832,16 @@ THREE.EventDispatcher.prototype = {
 
 			// Checking boundingSphere distance to ray
 			matrixPosition.getPositionFromMatrix(object.matrixWorld);
-			sphere.set(matrixPosition, geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis());
+			sphere.set( matrixPosition, geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis() );
 			
-			if(!raycaster.ray.isIntersectionSphere(sphere))
+			if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
+
 				return intersects;
+
+			}
 			
-			inverseMatrix.getInverse(object.matrixWorld);
-			localRay.copy(raycaster.ray).applyMatrix4(inverseMatrix);
+			inverseMatrix.getInverse( object.matrixWorld );
+			localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
 			localRay.direction.normalize(); // for scale matrix
 
 			var vertices = geometry.vertices;
@@ -6735,16 +6850,17 @@ THREE.EventDispatcher.prototype = {
 			var interLine = new THREE.Vector3();
 			var step = object.type === THREE.LineStrip ? 1 : 2;
 
-			for(var i = 0; i < nbVertices - 1; i=i+step) {
+			for ( var i = 0; i < nbVertices - 1; i = i + step ) {
 
-				localRay.distanceSqAndPointToSegment(vertices[i], vertices[i + 1], interLine, interSegment);
-				interSegment.applyMatrix4(object.matrixWorld);
-				interLine.applyMatrix4(object.matrixWorld);
-				if(interLine.distanceToSquared(interSegment) <= precisionSq) {
+				localRay.distanceSqAndPointToSegment( vertices[ i ], vertices[ i + 1 ], interLine, interSegment );
+				interSegment.applyMatrix4( object.matrixWorld );
+				interLine.applyMatrix4( object.matrixWorld );
 
-					var distance = raycaster.ray.origin.distanceTo(interLine);
+				if ( interLine.distanceToSquared( interSegment ) <= precisionSq ) {
 
-					if(raycaster.near <= distance && distance <= raycaster.far) {
+					var distance = raycaster.ray.origin.distanceTo( interLine );
+
+					if ( raycaster.near <= distance && distance <= raycaster.far ) {
 
 						intersects.push( {
 
@@ -6755,9 +6871,13 @@ THREE.EventDispatcher.prototype = {
 							object: object
 
 						} );
+
 					}
+
 				}
+
 			}
+
 		}
 
 	};
@@ -6776,7 +6896,7 @@ THREE.EventDispatcher.prototype = {
 	//
 
 	THREE.Raycaster.prototype.precision = 0.0001;
-	THREE.Raycaster.prototype.linePrecision = -1; // if negative, we don't pick lines 
+	THREE.Raycaster.prototype.linePrecision = 1;
 
 	THREE.Raycaster.prototype.set = function ( origin, direction ) {
 
@@ -6822,6 +6942,7 @@ THREE.EventDispatcher.prototype = {
 				intersectDescendants( objects[ i ], this, intersects );
 
 			}
+
 		}
 
 		intersects.sort( descSort );

+ 7 - 6
build/three.min.js

@@ -115,7 +115,8 @@ this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.ce
 this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}};THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]};
 THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var h=this.planes;h[0].copy(a);h[1].copy(b);h[2].copy(c);h[3].copy(d);h[4].copy(e);h[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements,a=c[0],d=c[1],e=c[2],f=c[3],h=c[4],g=c[5],i=c[6],j=c[7],l=c[8],m=c[9],n=c[10],p=c[11],t=c[12],q=c[13],r=c[14],c=c[15];b[0].setComponents(f-a,j-h,p-l,c-t).normalize();b[1].setComponents(f+
 a,j+h,p+l,c+t).normalize();b[2].setComponents(f+d,j+g,p+m,c+q).normalize();b[3].setComponents(f-d,j-g,p-m,c-q).normalize();b[4].setComponents(f-e,j-i,p-n,c-r).normalize();b[5].setComponents(f+e,j+i,p+n,c+r).normalize();return this},intersectsObject:function(){var a=new THREE.Vector3;return function(b){var c=b.geometry,b=b.matrixWorld;null===c.boundingSphere&&c.computeBoundingSphere();c=-c.boundingSphere.radius*b.getMaxScaleOnAxis();a.getPositionFromMatrix(b);for(var b=this.planes,d=0;6>d;d++)if(b[d].distanceToPoint(a)<
-c)return!1;return!0}}(),intersectsSphere:function(a){for(var b=this.planes,c=a.center,a=-a.radius,d=0;6>d;d++)if(b[d].distanceToPoint(c)<a)return!1;return!0},containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0};
+c)return!1;return!0}}(),intersectsSphere:function(a){for(var b=this.planes,c=a.center,a=-a.radius,d=0;6>d;d++)if(b[d].distanceToPoint(c)<a)return!1;return!0},intersectsBox:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c){for(var d=this.planes,e=0;6>e;e++){var f=d[e];a.x=0<f.normal.x?c.min.x:c.max.x;b.x=0<f.normal.x?c.max.x:c.min.x;a.y=0<f.normal.y?c.min.y:c.max.y;b.y=0<f.normal.y?c.max.y:c.min.y;a.z=0<f.normal.z?c.min.z:c.max.z;b.z=0<f.normal.z?c.max.z:c.min.z;var h=f.distanceToPoint(a),
+f=f.distanceToPoint(b);if(0>h&&0>f)return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0};
 THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d,
 c);return this}}(),copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){return this.orthoPoint(a,b).sub(a).negate()},orthoPoint:function(a,
 b){var c=this.distanceToPoint(a);return(b||new THREE.Vector3).copy(this.normal).multiplyScalar(c)},isIntersectionLine:function(a){var b=this.distanceToPoint(a.start),a=this.distanceToPoint(a.end);return 0>b&&0<a||0>a&&0<b},intersectLine:function(){var a=new THREE.Vector3;return function(b,c){var d=c||new THREE.Vector3,e=b.delta(a),f=this.normal.dot(e);if(0==f){if(0==this.distanceToPoint(b.start))return d.copy(b.start)}else return f=-(b.start.dot(this.normal)+this.constant)/f,0>f||1<f?void 0:d.copy(e).multiplyScalar(f).add(b.start)}}(),
@@ -135,13 +136,13 @@ THREE.Clock.prototype={constructor:THREE.Clock,start:function(){this.oldTime=thi
 a=0.001*(b-this.oldTime);this.oldTime=b;this.elapsedTime+=a}return a}};THREE.EventDispatcher=function(){};
 THREE.EventDispatcher.prototype={constructor:THREE.EventDispatcher,addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&&c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},removeEventListener:function(a,b){if(void 0!==this._listeners){var c=this._listeners,d=c[a].indexOf(b);-1!==d&&c[a].splice(d,1)}},dispatchEvent:function(a){if(void 0!==
 this._listeners){var b=this._listeners[a.type];if(void 0!==b){a.target=this;for(var c=0,d=b.length;c<d;c++)b[c].call(this,a)}}}};(function(a){a.Raycaster=function(b,c,d,e){this.ray=new a.Ray(b,c);0<this.ray.direction.lengthSq()&&this.ray.direction.normalize();this.near=d||0;this.far=e||Infinity};var b=new a.Sphere,c=new a.Ray,d=new a.Plane,e=new a.Vector3,f=new a.Vector3,h=new a.Matrix4,g=function(a,b){return a.distance-b.distance},i=function(g,j,n){if(g instanceof a.Particle){f.getPositionFromMatrix(g.matrixWorld);var p=j.ray.distanceToPoint(f);if(p>g.scale.x)return n;n.push({distance:p,point:g.position,face:null,object:g})}else if(g instanceof
-a.LOD)f.getPositionFromMatrix(g.matrixWorld),p=j.ray.origin.distanceTo(f),i(g.getObjectForDistance(p),j,n);else if(g instanceof a.Mesh){p=g.geometry;f.getPositionFromMatrix(g.matrixWorld);null===p.boundingSphere&&p.computeBoundingSphere();b.set(f,p.boundingSphere.radius*g.matrixWorld.getMaxScaleOnAxis());if(!1===j.ray.isIntersectionSphere(b))return n;var t=p.vertices;if(p instanceof a.BufferGeometry){var q=g.material;if(void 0===q||!p.dynamic)return n;var r=g.material instanceof a.MeshFaceMaterial,
+a.LOD)f.getPositionFromMatrix(g.matrixWorld),p=j.ray.origin.distanceTo(f),i(g.getObjectForDistance(p),j,n);else if(g instanceof a.Mesh){p=g.geometry;f.getPositionFromMatrix(g.matrixWorld);null===p.boundingSphere&&p.computeBoundingSphere();b.set(f,p.boundingSphere.radius*g.matrixWorld.getMaxScaleOnAxis());if(!1===j.ray.isIntersectionSphere(b))return n;var t=p.vertices;if(p instanceof a.BufferGeometry){var q=g.material;if(void 0===q||!1===p.dynamic)return n;var r=g.material instanceof a.MeshFaceMaterial,
 s=!0===r?g.material.materials:null,v=g.material.side,z,C,F=j.precision;h.getInverse(g.matrixWorld);c.copy(j.ray).applyMatrix4(h);var H,t=!1;p.attributes.index&&(t=!0);s=new a.Vector3;H=new a.Vector3;var I=new a.Vector3;new a.Vector3;new a.Vector3;for(var G=0;G<p.offsets.length;++G)for(var A=p.offsets[G].start,K=p.offsets[G].index,r=A,B=A+p.offsets[G].count;r<B;r+=3)if(t?(v=K+p.attributes.index.array[r],z=K+p.attributes.index.array[r+1],C=K+p.attributes.index.array[r+2]):(v=K,z=K+1,C=K+2),s.set(p.attributes.position.array[3*
 v],p.attributes.position.array[3*v+1],p.attributes.position.array[3*v+2]),H.set(p.attributes.position.array[3*z],p.attributes.position.array[3*z+1],p.attributes.position.array[3*z+2]),I.set(p.attributes.position.array[3*C],p.attributes.position.array[3*C+1],p.attributes.position.array[3*C+2]),d.setFromCoplanarPoints(s,H,I),A=c.distanceToPlane(d),!(Math.abs(A)<F)&&!(0>A)){v=q.side;if(v!==a.DoubleSide&&(z=c.direction.dot(d.normal),!(v===a.FrontSide?0>z:0<z)))continue;A<j.near||A>j.far||(e=c.at(A,e),
-a.Triangle.containsPoint(e,s,H,I)&&n.push({distance:A,point:j.ray.at(A),face:null,faceIndex:null,object:g}))}}else if(p instanceof a.Geometry){r=g.material instanceof a.MeshFaceMaterial;s=!0===r?g.material.materials:null;F=j.precision;h.getInverse(g.matrixWorld);c.copy(j.ray).applyMatrix4(h);I=0;for(H=p.faces.length;I<H;I++)if(G=p.faces[I],q=!0===r?s[G.materialIndex]:g.material,void 0!==q&&(d.setFromNormalAndCoplanarPoint(G.normal,t[G.a]),A=c.distanceToPlane(d),!(Math.abs(A)<F)&&!(0>A))){v=q.side;
-if(v!==a.DoubleSide&&(z=c.direction.dot(d.normal),!(v===a.FrontSide?0>z:0<z)))continue;if(!(A<j.near||A>j.far)){e=c.at(A,e);if(G instanceof a.Face3){if(v=t[G.a],z=t[G.b],C=t[G.c],!a.Triangle.containsPoint(e,v,z,C))continue}else if(G instanceof a.Face4){if(v=t[G.a],z=t[G.b],C=t[G.c],q=t[G.d],!a.Triangle.containsPoint(e,v,z,q)&&!a.Triangle.containsPoint(e,z,C,q))continue}else throw Error("face type not supported");n.push({distance:A,point:j.ray.at(A),face:G,faceIndex:I,object:g})}}}}else if(g instanceof
-a.Line){F=j.linePrecision;if(0>F)return n;F*=F;p=g.geometry;null===p.boundingSphere&&p.computeBoundingSphere();f.getPositionFromMatrix(g.matrixWorld);b.set(f,p.boundingSphere.radius*g.matrixWorld.getMaxScaleOnAxis());if(!j.ray.isIntersectionSphere(b))return n;h.getInverse(g.matrixWorld);c.copy(j.ray).applyMatrix4(h);c.direction.normalize();t=p.vertices;q=t.length;A=new a.Vector3;v=new a.Vector3;z=g.type===a.LineStrip?1:2;for(r=0;r<q-1;r+=z)c.distanceSqAndPointToSegment(t[r],t[r+1],v,A),A.applyMatrix4(g.matrixWorld),
-v.applyMatrix4(g.matrixWorld),v.distanceToSquared(A)<=F&&(p=j.ray.origin.distanceTo(v),j.near<=p&&p<=j.far&&n.push({distance:p,point:A.clone(),face:null,faceIndex:null,object:g}))}},j=function(a,b,c){for(var a=a.getDescendants(),d=0,e=a.length;d<e;d++)i(a[d],b,c)};a.Raycaster.prototype.precision=1E-4;a.Raycaster.prototype.linePrecision=-1;a.Raycaster.prototype.set=function(a,b){this.ray.set(a,b);0<this.ray.direction.length()&&this.ray.direction.normalize()};a.Raycaster.prototype.intersectObject=function(a,
+!1!==a.Triangle.containsPoint(e,s,H,I)&&n.push({distance:A,point:j.ray.at(A),face:null,faceIndex:null,object:g}))}}else if(p instanceof a.Geometry){r=g.material instanceof a.MeshFaceMaterial;s=!0===r?g.material.materials:null;F=j.precision;h.getInverse(g.matrixWorld);c.copy(j.ray).applyMatrix4(h);I=0;for(H=p.faces.length;I<H;I++)if(G=p.faces[I],q=!0===r?s[G.materialIndex]:g.material,void 0!==q&&(d.setFromNormalAndCoplanarPoint(G.normal,t[G.a]),A=c.distanceToPlane(d),!(Math.abs(A)<F)&&!(0>A))){v=q.side;
+if(v!==a.DoubleSide&&(z=c.direction.dot(d.normal),!(v===a.FrontSide?0>z:0<z)))continue;if(!(A<j.near||A>j.far)){e=c.at(A,e);if(G instanceof a.Face3){if(v=t[G.a],z=t[G.b],C=t[G.c],!1===a.Triangle.containsPoint(e,v,z,C))continue}else if(G instanceof a.Face4){if(v=t[G.a],z=t[G.b],C=t[G.c],q=t[G.d],!1===a.Triangle.containsPoint(e,v,z,q)&&!1===a.Triangle.containsPoint(e,z,C,q))continue}else throw Error("face type not supported");n.push({distance:A,point:j.ray.at(A),face:G,faceIndex:I,object:g})}}}}else if(g instanceof
+a.Line){F=j.linePrecision;F*=F;p=g.geometry;null===p.boundingSphere&&p.computeBoundingSphere();f.getPositionFromMatrix(g.matrixWorld);b.set(f,p.boundingSphere.radius*g.matrixWorld.getMaxScaleOnAxis());if(!1===j.ray.isIntersectionSphere(b))return n;h.getInverse(g.matrixWorld);c.copy(j.ray).applyMatrix4(h);c.direction.normalize();t=p.vertices;q=t.length;A=new a.Vector3;v=new a.Vector3;z=g.type===a.LineStrip?1:2;for(r=0;r<q-1;r+=z)c.distanceSqAndPointToSegment(t[r],t[r+1],v,A),A.applyMatrix4(g.matrixWorld),
+v.applyMatrix4(g.matrixWorld),v.distanceToSquared(A)<=F&&(p=j.ray.origin.distanceTo(v),j.near<=p&&p<=j.far&&n.push({distance:p,point:A.clone(),face:null,faceIndex:null,object:g}))}},j=function(a,b,c){for(var a=a.getDescendants(),d=0,e=a.length;d<e;d++)i(a[d],b,c)};a.Raycaster.prototype.precision=1E-4;a.Raycaster.prototype.linePrecision=1;a.Raycaster.prototype.set=function(a,b){this.ray.set(a,b);0<this.ray.direction.length()&&this.ray.direction.normalize()};a.Raycaster.prototype.intersectObject=function(a,
 b){var c=[];!0===b&&j(a,this,c);i(a,this,c);c.sort(g);return c};a.Raycaster.prototype.intersectObjects=function(a,b){for(var c=[],d=0,e=a.length;d<e;d++)i(a[d],this,c),!0===b&&j(a[d],this,c);c.sort(g);return c}})(THREE);THREE.Object3D=function(){this.id=THREE.Object3DIdCount++;this.uuid=THREE.Math.generateUUID();this.name="";this.parent=void 0;this.children=[];this.up=new THREE.Vector3(0,1,0);this.position=new THREE.Vector3;this.rotation=new THREE.Euler;this.quaternion=new THREE.Quaternion;this.scale=new THREE.Vector3(1,1,1);this.rotation._quaternion=this.quaternion;this.quaternion._euler=this.rotation;this.renderDepth=null;this.rotationAutoUpdate=!0;this.matrix=new THREE.Matrix4;this.matrixWorld=new THREE.Matrix4;
 this.visible=this.matrixWorldNeedsUpdate=this.matrixAutoUpdate=!0;this.receiveShadow=this.castShadow=!1;this.frustumCulled=!0;this.userData={}};
 THREE.Object3D.prototype={constructor:THREE.Object3D,addEventListener:THREE.EventDispatcher.prototype.addEventListener,hasEventListener:THREE.EventDispatcher.prototype.hasEventListener,removeEventListener:THREE.EventDispatcher.prototype.removeEventListener,dispatchEvent:THREE.EventDispatcher.prototype.dispatchEvent,get eulerOrder(){console.warn("DEPRECATED: Object3D's .eulerOrder has been moved to Object3D's .rotation.order.");return this.rotation.order},set eulerOrder(a){console.warn("DEPRECATED: Object3D's .eulerOrder has been moved to Object3D's .rotation.order.");