|
@@ -90,11 +90,6 @@
|
|
|
if ( material === undefined ) return intersects;
|
|
|
if ( geometry.dynamic === false ) return intersects;
|
|
|
|
|
|
- var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
|
|
|
- var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
|
|
|
-
|
|
|
- var side = object.material.side;
|
|
|
-
|
|
|
var a, b, c;
|
|
|
var precision = raycaster.precision;
|
|
|
|
|
@@ -119,22 +114,25 @@
|
|
|
var vA = new THREE.Vector3();
|
|
|
var vB = new THREE.Vector3();
|
|
|
var vC = new THREE.Vector3();
|
|
|
- var vCB = new THREE.Vector3();
|
|
|
- var vAB = new THREE.Vector3();
|
|
|
|
|
|
- for ( var oi = 0; oi < geometry.offsets.length; ++oi ) {
|
|
|
+ var offsets = geometry.offsets;
|
|
|
+ var indices = geometry.attributes.index.array;
|
|
|
+ var positions = geometry.attributes.position.array;
|
|
|
+ var offLength = geometry.offsets.length;
|
|
|
+
|
|
|
+ for ( var oi = 0; oi < offLength; ++oi ) {
|
|
|
|
|
|
- var start = geometry.offsets[ oi ].start;
|
|
|
- var count = geometry.offsets[ oi ].count;
|
|
|
- var index = geometry.offsets[ oi ].index;
|
|
|
+ var start = offsets[ oi ].start;
|
|
|
+ var count = offsets[ oi ].count;
|
|
|
+ var index = offsets[ oi ].index;
|
|
|
|
|
|
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 ];
|
|
|
+ a = index + indices[ i ];
|
|
|
+ b = index + indices[ i + 1 ];
|
|
|
+ c = index + indices[ i + 2 ];
|
|
|
|
|
|
} else {
|
|
|
|
|
@@ -145,70 +143,39 @@
|
|
|
}
|
|
|
|
|
|
vA.set(
|
|
|
- geometry.attributes.position.array[ a * 3 ],
|
|
|
- geometry.attributes.position.array[ a * 3 + 1 ],
|
|
|
- geometry.attributes.position.array[ a * 3 + 2 ]
|
|
|
+ positions[ a * 3 ],
|
|
|
+ positions[ a * 3 + 1 ],
|
|
|
+ positions[ 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 ]
|
|
|
+ positions[ b * 3 ],
|
|
|
+ positions[ b * 3 + 1 ],
|
|
|
+ positions[ 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 ]
|
|
|
+ positions[ c * 3 ],
|
|
|
+ positions[ c * 3 + 1 ],
|
|
|
+ positions[ c * 3 + 2 ]
|
|
|
);
|
|
|
|
|
|
- facePlane.setFromCoplanarPoints( vA, vB, vC );
|
|
|
-
|
|
|
- var planeDistance = localRay.distanceToPlane( facePlane );
|
|
|
-
|
|
|
- // bail if the ray is too close to the plane
|
|
|
- if ( planeDistance < precision ) continue;
|
|
|
-
|
|
|
- // bail if the ray is behind the plane
|
|
|
- if ( planeDistance === null ) continue;
|
|
|
-
|
|
|
- // 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 );
|
|
|
-
|
|
|
+ var interPoint = THREE.Triangle.intersectionRayTriangle( localRay, vA, vB, vC, material.side !== THREE.DoubleSide );
|
|
|
|
|
|
- if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) {
|
|
|
+ if ( !interPoint ) continue;
|
|
|
|
|
|
- continue;
|
|
|
+ interPoint.applyMatrix4( object.matrixWorld );
|
|
|
+ var distance = raycaster.ray.origin.distanceTo( interPoint );
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // 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;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // passing in intersectPoint avoids a copy
|
|
|
- intersectPoint = localRay.at( planeDistance, intersectPoint );
|
|
|
-
|
|
|
- if ( THREE.Triangle.containsPoint( intersectPoint, vA, vB, vC ) === false ) {
|
|
|
-
|
|
|
- continue;
|
|
|
+ // bail if the ray is too close to the plane
|
|
|
+ if ( distance < precision ) continue;
|
|
|
|
|
|
- }
|
|
|
+ if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
|
|
|
intersects.push( {
|
|
|
|
|
|
// this works because the original ray was normalized,
|
|
|
// and the transformed localRay wasn't
|
|
|
- distance: planeDistance,
|
|
|
- point: raycaster.ray.at( planeDistance ),
|
|
|
+ distance: distance,
|
|
|
+ point: interPoint,
|
|
|
face: null,
|
|
|
faceIndex: null,
|
|
|
object: object
|
|
@@ -223,8 +190,6 @@
|
|
|
var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
|
|
|
var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
|
|
|
|
|
|
- var side = object.material.side;
|
|
|
-
|
|
|
var a, b, c, d;
|
|
|
var precision = raycaster.precision;
|
|
|
|
|
@@ -240,44 +205,16 @@
|
|
|
|
|
|
if ( material === undefined ) continue;
|
|
|
|
|
|
- facePlane.setFromNormalAndCoplanarPoint( face.normal, vertices[face.a] );
|
|
|
-
|
|
|
- var planeDistance = localRay.distanceToPlane( facePlane );
|
|
|
-
|
|
|
- // bail if the ray is too close to the plane
|
|
|
- if ( planeDistance < precision ) continue;
|
|
|
-
|
|
|
- // bail if the ray is behind the plane
|
|
|
- if ( planeDistance === null ) continue;
|
|
|
-
|
|
|
- // 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;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // 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;
|
|
|
-
|
|
|
- // passing in intersectPoint avoids a copy
|
|
|
- intersectPoint = localRay.at( planeDistance, intersectPoint );
|
|
|
+ var interPoint;
|
|
|
|
|
|
if ( face instanceof THREE.Face3 ) {
|
|
|
|
|
|
a = vertices[ face.a ];
|
|
|
b = vertices[ face.b ];
|
|
|
c = vertices[ face.c ];
|
|
|
+ interPoint = THREE.Triangle.intersectionRayTriangle( localRay, a, b, c, material.side !== THREE.DoubleSide );
|
|
|
|
|
|
- if ( THREE.Triangle.containsPoint( intersectPoint, a, b, c ) === false ) {
|
|
|
+ if ( !interPoint ) {
|
|
|
|
|
|
continue;
|
|
|
|
|
@@ -289,11 +226,13 @@
|
|
|
b = vertices[ face.b ];
|
|
|
c = vertices[ face.c ];
|
|
|
d = vertices[ face.d ];
|
|
|
+ interPoint = THREE.Triangle.intersectionRayTriangle( localRay, a, b, d, material.side !== THREE.DoubleSide );
|
|
|
|
|
|
- if ( THREE.Triangle.containsPoint( intersectPoint, a, b, d ) === false &&
|
|
|
- THREE.Triangle.containsPoint( intersectPoint, b, c, d ) === false ) {
|
|
|
+ if( !interPoint ) {
|
|
|
|
|
|
- continue;
|
|
|
+ interPoint = THREE.Triangle.intersectionRayTriangle( localRay, b, c, d, material.side !== THREE.DoubleSide );
|
|
|
+
|
|
|
+ if( !interPoint ) continue;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -306,12 +245,18 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
+ interPoint.applyMatrix4( object.matrixWorld );
|
|
|
+ var distance = raycaster.ray.origin.distanceTo( interPoint );
|
|
|
+
|
|
|
+ // bail if the ray is too close to the plane
|
|
|
+ if ( distance < precision ) continue;
|
|
|
+
|
|
|
+ if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
+
|
|
|
intersects.push( {
|
|
|
|
|
|
- // this works because the original ray was normalized,
|
|
|
- // and the transformed localRay wasn't
|
|
|
- distance: planeDistance,
|
|
|
- point: raycaster.ray.at( planeDistance ),
|
|
|
+ distance: distance,
|
|
|
+ point: interPoint,
|
|
|
face: face,
|
|
|
faceIndex: f,
|
|
|
object: object
|