|
@@ -64,7 +64,7 @@
|
|
|
|
|
|
intersectObject( object.getObjectForDistance( distance ), raycaster, intersects );
|
|
|
|
|
|
- } else if (object instanceof THREE.Mesh ) {
|
|
|
+ } else if ( object instanceof THREE.Mesh ) {
|
|
|
|
|
|
var geometry = object.geometry;
|
|
|
|
|
@@ -88,7 +88,7 @@
|
|
|
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;
|
|
@@ -104,6 +104,7 @@
|
|
|
|
|
|
var fl;
|
|
|
var indexed = false;
|
|
|
+
|
|
|
if ( geometry.attributes.index ) {
|
|
|
|
|
|
indexed = true;
|
|
@@ -112,6 +113,7 @@
|
|
|
} else {
|
|
|
|
|
|
fl = geometry.attributes.position.numItems / 9;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
var vA = new THREE.Vector3();
|
|
@@ -129,24 +131,34 @@
|
|
|
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 );
|
|
|
|
|
@@ -160,25 +172,43 @@
|
|
|
|
|
|
// 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 ) ) {
|
|
|
|
|
|
- if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) continue;
|
|
|
+ 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;
|
|
|
|
|
|
- if ( ! THREE.Triangle.containsPoint( intersectPoint, vA, vB, vC ) ) continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // passing in intersectPoint avoids a copy
|
|
|
+ intersectPoint = localRay.at( planeDistance, intersectPoint );
|
|
|
+
|
|
|
+ if ( THREE.Triangle.containsPoint( intersectPoint, vA, vB, vC ) === false ) {
|
|
|
+
|
|
|
+ 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
|
|
@@ -226,14 +256,20 @@
|
|
|
|
|
|
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 ) {
|
|
|
|
|
@@ -241,7 +277,11 @@
|
|
|
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 ) {
|
|
|
|
|
@@ -250,20 +290,27 @@
|
|
|
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,
|
|
@@ -275,12 +322,9 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
- } 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;
|
|
@@ -289,13 +333,16 @@
|
|
|
|
|
|
// 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;
|
|
@@ -304,16 +351,17 @@
|
|
|
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( {
|
|
|
|
|
@@ -324,9 +372,13 @@
|
|
|
object: object
|
|
|
|
|
|
} );
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
};
|
|
@@ -345,7 +397,7 @@
|
|
|
//
|
|
|
|
|
|
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 ) {
|
|
|
|
|
@@ -391,6 +443,7 @@
|
|
|
intersectDescendants( objects[ i ], this, intersects );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
intersects.sort( descSort );
|