three-mesh-bvh
Version:
A BVH implementation to speed up raycasting against three.js meshes.
100 lines (62 loc) • 2.7 kB
JavaScript
import { Vector3, Vector2, Triangle, DoubleSide, BackSide, Face3 } from 'three';
// Ripped and modified From THREE.js Mesh raycast
// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L115
var vA = new Vector3();
var vB = new Vector3();
var vC = new Vector3();
var uvA = new Vector2();
var uvB = new Vector2();
var uvC = new Vector2();
var intersectionPoint = new Vector3();
var intersectionPointWorld = new Vector3();
function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) {
var intersect;
if ( material.side === BackSide ) {
intersect = ray.intersectTriangle( pC, pB, pA, true, point );
} else {
intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
}
if ( intersect === null ) return null;
intersectionPointWorld.copy( point );
intersectionPointWorld.applyMatrix4( object.matrixWorld );
var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
if ( distance < raycaster.near || distance > raycaster.far ) return null;
return {
distance: distance,
point: intersectionPointWorld.clone(),
object: object
};
}
function checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {
vA.fromBufferAttribute( position, a );
vB.fromBufferAttribute( position, b );
vC.fromBufferAttribute( position, c );
var intersection = checkIntersection( object, object.material, raycaster, ray, vA, vB, vC, intersectionPoint );
if ( intersection ) {
if ( uv ) {
uvA.fromBufferAttribute( uv, a );
uvB.fromBufferAttribute( uv, b );
uvC.fromBufferAttribute( uv, c );
intersection.uv = Triangle.getUV( intersectionPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2( ) );
}
var normal = new Vector3();
intersection.face = new Face3( a, b, c, Triangle.getNormal( vA, vB, vC, normal ) );
intersection.faceIndex = a;
}
return intersection;
}
// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L258
function intersectTri( mesh, geo, raycaster, ray, tri, intersections ) {
const triOffset = tri * 3;
const a = geo.index.getX( triOffset );
const b = geo.index.getX( triOffset + 1 );
const c = geo.index.getX( triOffset + 2 );
const intersection = checkBufferGeometryIntersection( mesh, raycaster, ray, geo.attributes.position, geo.attributes.uv, a, b, c );
if ( intersection ) {
intersection.faceIndex = tri;
if ( intersections ) intersections.push( intersection );
return intersection;
}
return null;
};
export { intersectTri };