v0.9.18
three-mesh-bvh
A long-standing & still growing spatial query system for three.js trusted for fast and accurate spatial queries. Used for accelerating raycasting, collision detection, and spatial queries with BVH-based acceleration structures.
performancegame devphysics
import { AmbientLight, BufferAttribute, DirectionalLight, Mesh, MeshStandardMaterial, Raycaster, Sphere, TorusKnotGeometry, Vector2 } from 'three';
import { MeshBVH, acceleratedRaycast, INTERSECTED, NOT_INTERSECTED } from 'three-mesh-bvh';
// scene, camera and renderer are initialized here
const light = new DirectionalLight( 0xffffff, 1.5 );
light.position.set( 1, 1, 1 );
scene.add( light, new AmbientLight( 0xffffff, 1.2 ) );
// a torus knot of over half a million triangles, every vertex white to start
const geometry = new TorusKnotGeometry( 1, 0.4, 800, 400 ).toNonIndexed();
const colors = new BufferAttribute( new Float32Array( geometry.attributes.position.count * 3 ).fill( 1 ), 3 );
geometry.setAttribute( 'color', colors );
geometry.boundsTree = new MeshBVH( geometry );
const mesh = new Mesh( geometry, new MeshStandardMaterial( { vertexColors: true, roughness: 0.3 } ) );
mesh.raycast = acceleratedRaycast;
scene.add( mesh );
// hovering paints every triangle within a sphere around the point under the pointer
const raycaster = new Raycaster();
raycaster.firstHitOnly = true;
const pointer = new Vector2();
const hits = [];
const brush = new Sphere( undefined, 0.2 );
const paint = {
intersectsBounds: box => brush.intersectsBox( box ) ? INTERSECTED : NOT_INTERSECTED,
intersectsTriangle: ( triangle, index ) => {
if ( ! triangle.intersectsSphere( brush ) ) return;
for ( let i = 3 * index; i < 3 * index + 3; i ++ ) {
colors.setXYZ( geometry.index.getX( i ), 0.93, 0.25, 0.48 );
}
},
};
window.addEventListener( 'pointermove', e => {
pointer.set( e.clientX / window.innerWidth * 2 - 1, - e.clientY / window.innerHeight * 2 + 1 );
raycaster.setFromCamera( pointer, camera );
hits.length = 0;
raycaster.intersectObject( mesh, false, hits );
if ( ! hits.length ) return;
brush.center.copy( hits[ 0 ].point );
geometry.boundsTree.shapecast( paint );
colors.needsUpdate = true;
} );Install
npm install three-mesh-bvhChangelog
0.9.18
Added
- BVHComputeData: "raycastAnyHit" function that ends traversal at the first hit, for shadow and occlusion rays.
- BVHComputeData: "getShapecastFn" range callbacks can return "STOP_TRAVERSAL" to end the traversal early.
Fixed
- BVHComputeData: "raycastFirstHit" no longer misses bounds for axis-parallel rays that lie on a bounds face.
- BVHHelper: No longer generates infinite positions for a BVH with empty bounds, such as one built from an empty geometry.
0.9.17
Added
- BVHComputeData: "updateAsync" so a "getBVH" override can build BVHs asynchronously.
Changed
- SAH builds are faster: 8 bins per axis and an exact sweep for small nodes.
- BVH builds write nodes directly into the packed buffer instead of an intermediate node tree, using a fraction of the memory.
Fixed
- MeshBVH: Raycasts no longer test triangles when the ray misses a root that is a leaf.
- OrientedBox: Fixed "distanceToBox" using the wrong axis for one set of box edges.
- ExtendedTriangle: Fixed "closestPointToSegment" returning a positive distance for segments that pass through the triangle.
0.9.16
Fixed
- BVHHelper: Fixed helper not rendering with three.js r186 correctly.