UNPKG

three-mesh-bvh

Version:

A BVH implementation to speed up raycasting against three.js meshes.

102 lines (64 loc) 2.49 kB
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 };