Skip to main content

Function: applyBVH()

applyBVH(root, __namedParameters): Promise<void>

Defined in: src/utils/BVHRaycast.ts:126

Walk the given object3D (recursively) and build a bounds tree on every standard THREE.Mesh whose geometry doesn't already have one. Subsequent raycaster.intersectObject(root, true) calls then go through the BVH-accelerated path.

Use on dense, static environmental meshes only (loaded immersive scenes, photogrammetry scans, baked levels). The tree has a one-time build + memory cost and assumes static vertices, so it's a net loss for low-poly / UI / dynamic meshes. Don't apply globally to xb.core.scene.

Skips THREE.SkinnedMesh: skinned meshes deform vertices on the GPU each frame, so a bounds tree built on the bind-pose geometry is wrong the moment the mesh animates. Three's SkinnedMesh.raycast() also overrides the patched Mesh.prototype.raycast and does its own CPU skinning, so the BVH would never be consulted anyway.

Skips THREE.BatchedMesh: three-mesh-bvh ships a dedicated computeBatchedBoundsTree / disposeBatchedBoundsTree pair that builds per-draw-range BVHs on this.boundsTrees (plural), and acceleratedRaycast has a separate isBatchedMesh branch that consults those. The standard computeBoundsTree would index the combined batched buffer and produce wrong hits. Conservative skip until the batched helpers are wired up.

THREE.InstancedMesh is NOT skipped: its .raycast() calls a shared internal Mesh per instance, which does route through the patched Mesh.prototype.raycast, so a BVH on the shared geometry accelerates every per-instance test.

Async because it awaits the dynamic import of three-mesh-bvh. If the module isn't available, this is a no-op. Idempotent across calls.

Parameters

root

Object3D

__namedParameters

recursive?

boolean = true

Returns

Promise<void>