|
@@ -282,6 +282,150 @@ THREE.Ray.prototype = {
|
|
|
|
|
|
},
|
|
|
|
|
|
+ isIntersectionBox: function () {
|
|
|
+
|
|
|
+ var v = new THREE.Vector3();
|
|
|
+
|
|
|
+ return function ( box ) {
|
|
|
+
|
|
|
+ return this.intersectBox( box, v ) !== null;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }(),
|
|
|
+
|
|
|
+ intersectBox: function ( box , optionalTarget ) {
|
|
|
+
|
|
|
+ // http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/
|
|
|
+
|
|
|
+ var tmin,tmax,tymin,tymax,tzmin,tzmax;
|
|
|
+
|
|
|
+ var invdirx = 1/this.direction.x,
|
|
|
+ invdiry = 1/this.direction.y,
|
|
|
+ invdirz = 1/this.direction.z;
|
|
|
+
|
|
|
+ var origin = this.origin;
|
|
|
+
|
|
|
+ if (invdirx >= 0) {
|
|
|
+
|
|
|
+ tmin = (box.min.x - origin.x) * invdirx;
|
|
|
+ tmax = (box.max.x - origin.x) * invdirx;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ tmin = (box.max.x - origin.x) * invdirx;
|
|
|
+ tmax = (box.min.x - origin.x) * invdirx;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (invdiry >= 0) {
|
|
|
+
|
|
|
+ tymin = (box.min.y - origin.y) * invdiry;
|
|
|
+ tymax = (box.max.y - origin.y) * invdiry;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ tymin = (box.max.y - origin.y) * invdiry;
|
|
|
+ tymax = (box.min.y - origin.y) * invdiry;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((tmin > tymax) || (tymin > tmax)) return null;
|
|
|
+
|
|
|
+ // These lines also handle the case where tmin or tmax is NaN
|
|
|
+ // (result of 0 * Infinity). x !== x returns true if x is NaN
|
|
|
+
|
|
|
+ if (tymin > tmin || tmin !== tmin ) tmin = tymin;
|
|
|
+
|
|
|
+ if (tymax < tmax || tmax !== tmax ) tmax = tymax;
|
|
|
+
|
|
|
+ if (invdirz >= 0) {
|
|
|
+
|
|
|
+ tzmin = (box.min.z - origin.z) * invdirz;
|
|
|
+ tzmax = (box.max.z - origin.z) * invdirz;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ tzmin = (box.max.z - origin.z) * invdirz;
|
|
|
+ tzmax = (box.min.z - origin.z) * invdirz;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((tmin > tzmax) || (tzmin > tmax)) return null;
|
|
|
+
|
|
|
+ if (tzmin > tmin || tmin !== tmin ) tmin = tzmin;
|
|
|
+
|
|
|
+ if (tzmax < tmax || tmax !== tmax ) tmax = tzmax;
|
|
|
+
|
|
|
+ //return point closest to the ray (positive side)
|
|
|
+
|
|
|
+ if ( tmax < 0 ) return null;
|
|
|
+
|
|
|
+ return this.at( tmin >= 0 ? tmin : tmax, optionalTarget );
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ intersectTriangle: function() {
|
|
|
+
|
|
|
+ // Compute the offset origin, edges, and normal.
|
|
|
+ var diff = new THREE.Vector3();
|
|
|
+ var edge1 = new THREE.Vector3();
|
|
|
+ var edge2 = new THREE.Vector3();
|
|
|
+ var normal = new THREE.Vector3();
|
|
|
+
|
|
|
+ return function ( a, b, c, backfaceCulling, optionalTarget ) {
|
|
|
+
|
|
|
+ //from http://www.geometrictools.com/LibMathematics/Intersection/Wm5IntrRay3Triangle3.cpp
|
|
|
+
|
|
|
+ edge1.subVectors( b, a );
|
|
|
+ edge2.subVectors( c, a );
|
|
|
+ normal.crossVectors( edge1, edge2 );
|
|
|
+
|
|
|
+ // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
|
|
|
+ // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
|
|
|
+ // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
|
|
|
+ // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
|
|
|
+ // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
|
|
|
+ var DdN = this.direction.dot(normal);
|
|
|
+ var sign;
|
|
|
+ if ( DdN > 0 ) {
|
|
|
+
|
|
|
+ if ( backfaceCulling ) return null;
|
|
|
+ sign = 1;
|
|
|
+
|
|
|
+ } else if ( DdN < 0 ) {
|
|
|
+
|
|
|
+ sign = - 1;
|
|
|
+ DdN = - DdN;
|
|
|
+
|
|
|
+ } else return null;
|
|
|
+
|
|
|
+ diff.subVectors( this.origin, a );
|
|
|
+ var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );
|
|
|
+
|
|
|
+ // b1 < 0, no intersection
|
|
|
+ if ( DdQxE2 < 0 )
|
|
|
+ return null;
|
|
|
+
|
|
|
+ var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );
|
|
|
+ // b2 < 0, no intersection
|
|
|
+ if ( DdE1xQ < 0 )
|
|
|
+ return null;
|
|
|
+
|
|
|
+ // b1+b2 > 1, no intersection
|
|
|
+ if ( DdQxE2 + DdE1xQ > DdN )
|
|
|
+ return null
|
|
|
+
|
|
|
+ // Line intersects triangle, check if ray does.
|
|
|
+ var QdN = - sign * diff.dot( normal );
|
|
|
+ // t < 0, no intersection
|
|
|
+ if ( QdN < 0 )
|
|
|
+ return null
|
|
|
+
|
|
|
+ // Ray intersects triangle.
|
|
|
+ return this.at( QdN / DdN, optionalTarget );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }(),
|
|
|
+
|
|
|
applyMatrix4: function ( matrix4 ) {
|
|
|
|
|
|
this.direction.add( this.origin ).applyMatrix4( matrix4 );
|