three-mesh-bvh
Version:
A BVH implementation to speed up raycasting against three.js meshes.
102 lines (64 loc) • 2.49 kB
JavaScript
import { Vector3, Vector2, Triangle, DoubleSide, BackSide } from 'three';
// Ripped and modified From THREE.js Mesh raycast
// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L115
const vA = /* @__PURE__ */ new Vector3();
const vB = /* @__PURE__ */ new Vector3();
const vC = /* @__PURE__ */ new Vector3();
const uvA = /* @__PURE__ */ new Vector2();
const uvB = /* @__PURE__ */ new Vector2();
const uvC = /* @__PURE__ */ new Vector2();
const intersectionPoint = /* @__PURE__ */ new Vector3();
function checkIntersection( ray, pA, pB, pC, point, side ) {
let intersect;
if ( side === BackSide ) {
intersect = ray.intersectTriangle( pC, pB, pA, true, point );
} else {
intersect = ray.intersectTriangle( pA, pB, pC, side !== DoubleSide, point );
}
if ( intersect === null ) return null;
const distance = ray.origin.distanceTo( point );
return {
distance: distance,
point: point.clone(),
};
}
function checkBufferGeometryIntersection( ray, position, uv, a, b, c, side ) {
vA.fromBufferAttribute( position, a );
vB.fromBufferAttribute( position, b );
vC.fromBufferAttribute( position, c );
const intersection = checkIntersection( ray, vA, vB, vC, intersectionPoint, side );
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( ) );
}
const face = {
a: a,
b: b,
c: c,
normal: new Vector3(),
materialIndex: 0
};
Triangle.getNormal( vA, vB, vC, face.normal );
intersection.face = face;
intersection.faceIndex = a;
}
return intersection;
}
// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L258
function intersectTri( geo, side, 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( ray, geo.attributes.position, geo.attributes.uv, a, b, c, side );
if ( intersection ) {
intersection.faceIndex = tri;
if ( intersections ) intersections.push( intersection );
return intersection;
}
return null;
}
export { intersectTri };