# three-mesh-bvh: Functions

## Debug Functions

### BVHExtremes

typedef in `three-mesh-bvh`

## Properties

- `nodeCount`, `number`: Total number of nodes in the tree including leaf nodes.
- `leafNodeCount`, `number`: Total number of leaf nodes in the tree.
- `surfaceAreaScore`, `number`: Total tree score based on the surface area heuristic.
Lower is better. Useful for comparing tree quality and performance, and for detecting
degradation after `MeshBVH.refit` calls.
- `depth`, `Object`: Min and max depth of leaf nodes.
- `tris`, `Object`: Min and max triangle count in leaf nodes.
- `splits`, `Array<number>`: Number of splits on each axis as a three-element array `[X, Y, Z]`.

### getBVHExtremes

```js
getBVHExtremes( bvh: MeshBVH ): Array<BVHExtremes>
```

Measures the min and max extremes of the BVH tree structure, including node
depth, leaf primitive count, split axis distribution, and a surface-area
heuristic score. Returns one entry per root group in the BVH.

- `bvh`, `MeshBVH`

### estimateMemoryInBytes

```js
estimateMemoryInBytes( bvh: BVH ): number
```

Roughly estimates the amount of memory in bytes used by a BVH by walking
its object graph and summing typed-array byte lengths and primitive sizes.

- `bvh`, `BVH`

### validateBounds

```js
validateBounds( bvh: MeshBVH ): boolean
```

Validates that every node's bounding box fully contains its children and,
for leaf nodes, fully contains all of its primitives. Uses `console.assert`
to log failures and returns `false` if any check fails.

- `bvh`, `MeshBVH`

### getJSONStructure

```js
getJSONStructure( bvh: BVH ): Object
```

Returns a plain-object tree that mirrors the BVH hierarchy, useful for
inspecting or serialising the structure for debugging. Each node has a
`bounds` (`Box3`) and either `{ count, offset }` (leaf) or `{ left, right }`
(internal) fields.

- `bvh`, `BVH`

## Extension Utilities

### acceleratedRaycast

```js
acceleratedRaycast( raycaster: Raycaster, intersects: Array<Intersection> ): void
```

An accelerated raycast function with the same signature as `THREE.Mesh.raycast`. Uses the BVH
for raycasting if it's available otherwise it falls back to the built-in approach. The results
of the function are designed to be identical to the results of the conventional
`THREE.Mesh.raycast` results.

If the raycaster object being used has a property `firstHitOnly` set to `true`, then the
raycasting will terminate as soon as it finds the closest intersection to the ray's origin and
return only that intersection. This is typically several times faster than searching for all
intersections.

- `raycaster`, `Raycaster`
- `intersects`, `Array<Intersection>`

Example: Casting a thousand rays at a mesh every frame

```js
import { BufferAttribute, BufferGeometry, HemisphereLight, LineBasicMaterial, LineSegments, Mesh, Points, PointsMaterial, Raycaster, Vector3 } from 'three';
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
import { computeBoundsTree, acceleratedRaycast } from 'three-mesh-bvh';

// scene, camera and renderer are initialized here

const URL = 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/models/fbx/stanford-bunny.fbx';
const RAYS = 1000;

BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
Mesh.prototype.raycast = acceleratedRaycast;

scene.add( new HemisphereLight( 0xffffff, 0x999999, 3 ) );
camera.position.set( 5, 3, 8 );

const { children: [ bunny ] } = await new FBXLoader().loadAsync( URL );
bunny.geometry.computeBoundsTree();
bunny.scale.setScalar( 0.0075 );
bunny.position.y = 0.5;
scene.add( bunny );

const origins = new Array( RAYS ).fill().map( () => new Vector3().randomDirection().multiplyScalar( 3.75 ) );
const rays = new BufferGeometry();
rays.setAttribute( 'position', new BufferAttribute( new Float32Array( RAYS * 6 ), 3 ) );
scene.add(
	new LineSegments( rays, new LineBasicMaterial( { color: 0xe91e63, transparent: true, opacity: 0.25 } ) ),
	new Points( rays, new PointsMaterial( { color: 0xe91e63, size: 0.04 } ) ),
);

const raycaster = new Raycaster();
raycaster.firstHitOnly = true;
const { ray } = raycaster;
const hits = [];
renderer.setAnimationLoop( time => {

	bunny.rotation.y = time * 0.0001;
	bunny.updateMatrixWorld();

	const position = rays.attributes.position;
	for ( let i = 0; i < RAYS; i ++ ) {

		ray.origin.copy( origins[ i ] );
		ray.direction.copy( ray.origin ).negate().normalize();
		hits.length = 0;
		raycaster.intersectObject( bunny, false, hits );
		const end = hits.length ? hits[ 0 ].point : ray.origin;
		position.setXYZ( 2 * i, ray.origin.x, ray.origin.y, ray.origin.z );
		position.setXYZ( 2 * i + 1, end.x, end.y, end.z );

	}

	position.needsUpdate = true;
	renderer.render( scene, camera );

} );
```

### computeBoundsTree

```js
computeBoundsTree( options?: Object ): GeometryBVH
```

A pre-made BufferGeometry extension function that builds a new BVH, assigns it to `boundsTree`
for BufferGeometry, and applies the new index buffer to the geometry. Comparable to
`computeBoundingBox` and `computeBoundingSphere`.

```js
THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
```

- `options`, `Object`, optional

### disposeBoundsTree

```js
disposeBoundsTree(  ): void
```

A BufferGeometry extension function that disposes of the BVH.

```js
THREE.BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree;
```

### computeBatchedBoundsTree

```js
computeBatchedBoundsTree( index?: number, options?: Object ): GeometryBVH | Array<GeometryBVH> | null
```

Equivalent of `computeBoundsTree` for `BatchedMesh`. Creates the
`BatchedMesh.boundsTrees` array if it does not exist. If `index` is `-1`
BVHs for all available geometries are generated and the full array is
returned; otherwise only the BVH at that geometry index is generated and
returned.

```js
THREE.BatchedMesh.prototype.computeBoundsTree = computeBatchedBoundsTree;
```

- `index`, `number`, optional, default `-1`
- `options`, `Object`, optional

### disposeBatchedBoundsTree

```js
disposeBatchedBoundsTree( index?: number ): void
```

Equivalent of `disposeBoundsTree` for `BatchedMesh`. Sets entries in
`BatchedMesh.boundsTrees` to `null`. If `index` is `-1` all BVHs are
disposed; otherwise only the BVH at that geometry index is disposed.

```js
THREE.BatchedMesh.prototype.disposeBoundsTree = disposeBatchedBoundsTree;
```

- `index`, `number`, optional, default `-1`

## Functions

### getTriangleHitPointInfo

```js
getTriangleHitPointInfo( point: Vector3, geometry: BufferGeometry, triangleIndex: number, target?: HitTriangleInfo ): HitTriangleInfo
```

Computes hit-point information for a point on a triangle within a `BufferGeometry`. Returns
the face vertex indices, face normal, material index, UV coordinates, and barycentric coordinates.
Useful for retrieving detailed hit data after a call to `MeshBVH.closestPointToPoint` or
`MeshBVH.closestPointToGeometry`.

- `point`, `Vector3`: The point on the triangle surface (in the geometry's local space).
- `geometry`, `BufferGeometry`: The geometry containing the triangle.
- `triangleIndex`, `number`: The index of the triangle within the geometry.
- `target`, `HitTriangleInfo`, optional: Optional object to write results into. Reuses existing
  `face`, `uv`, and `barycoord` sub-objects if present.
