ReadonlylayoutThe tree in the GPU layout. Its buffers are this object's own storage: refit writes them in place.
The deepest box's depth, as traverse reports it (three-mesh-bvh's depth: the root's children are at 1).
StaticbuildBuilds a tree with tinybvh (createTinyBvhBuilder()), on this thread. Keeps input as its source.
three-mesh-bvh's bvhcast (0.9.18): walks this tree and other
together, other placed by matrixToLocal (its space to this one's),
and hands over every pair of leaves whose boxes overlap
(intersectsRanges) and every pair of their triangles
(intersectsTriangles, the other's moved into this space). The walk is
three-mesh-bvh's, step for step: descend the other tree while both its
children overlap, switch trees when one doesn't or a leaf is reached.
Offsets and indices are tree positions (indirect mode). Returns true
when a callback stopped the cast. Casts may nest.
three-mesh-bvh's closestPointToGeometry (0.9.18), step for step: the
closest points between this tree's triangles and other's, other
placed by geometryToBvh (its space to this tree's; default identity).
A shapecast of this tree ordered by the distance from other's
box (as an OrientedBox) to each box; for each leaf, a shapecast
of other's tree ordered by the distance from that leaf's box (moved
into other's space) to its boxes, or, when other is a mesh
({ positions, indices }), every triangle of it. Pairs are measured with
ExtendedTriangle.distanceToTriangle, and the cast stops at a pair
nearer than minThreshold; boxes no nearer than the best so far or than
maxThreshold are skipped.
target1 gets the point on this tree, the distance and this tree's
triangle; target2 (pass null to skip it) the point on other, in
other's space, the distance measured there, and other's triangle.
Both triangle indices are original indices (three-mesh-bvh 0.9.18's
indirect mode returns tree positions here instead). Returns target1, or
null with the targets untouched when nothing is nearer than
maxThreshold. The box scores are taken in each tree's own space, as in
three-mesh-bvh, so a geometryToBvh with scale skews the culling (not
the distances).
OptionalgeometryToBvh: BvhMatrix4Like | nullthree-mesh-bvh's closestPointToPoint (0.9.18), step for step: a
shapecast visiting the nearer box first (boundsTraverseOrder:
squared distance from the point to the box), entering only boxes nearer
than the best so far and than maxThreshold, and testing each triangle
with three's Triangle.closestPointToPoint. Stops at the first
triangle nearer than minThreshold (set both thresholds equal to ask
"is anything within this distance?"). Returns target with point,
distance and faceIndex (the original triangle), or null, leaving
target alone, when no box is nearer than maxThreshold.
As in three-mesh-bvh, maxThreshold culls boxes, not triangles: a
triangle in a box nearer than it may still be returned past it.
One departure: on a sliver (the squared sine of its angle at a at
most 1e-7) the nearer of three's point and the nearest point of its
three edges is kept, as the GPU's bvhClosestPointToTriangle does,
because three's regions cancel there (see closestOnTriangle).
StaticcreateStaticdeserializeReads bytes from serialize (or serializeLayout).
Bytes this object holds: the layout (nodes; triangles, 48-byte records or with corners: 'positions' 16 bytes;
parents), the one-instance top level and lookups made so far. Not the source geometry.
Box around every triangle, current after refit: into target
as [minX, minY, minZ, maxX, maxY, maxZ], or into its min and max
(a three Box3). Default a new Float32Array(6).
Optionaltarget: TThe corners of the triangle at a tree position, as the tree stores them: 9 numbers into target.
Where point lies on an original triangle: barycentrics, the corners,
the face normal, and any vertex attributes given, interpolated. The
vertex indices come from options.indices, else the source's index
buffer, else (a source without one) 3 * triangle + corner. A tree
without a source (deserialized, or made from a layout) has vertices
null unless options.indices is given, and then can't interpolate
attributes.
The inside test's votes for point: of the three rays
(INSIDE_TEST_DIRECTIONS), how many see it inside by parity (an
odd crossing count) and how many by winding (a non-zero signed sum).
The CPU twin of the GPU's bvhInsideVotes. Three full ray walks.
The walk under raycast: every hit (or the closest only) with t
in [tMin, tMax], in units of direction as given. side culls
natively in the walk (BVH_FRONT_SIDE front faces only,
BVH_BACK_SIDE back faces only; default BVH_DOUBLE_SIDE,
the WGSL walk's behaviour; CPU only). accept decides which of the rest
count (by original triangle and side), the others are passed through.
All hits come in walk order, not sorted. A closest-hit query without
accept runs the walk with no triangle filter at all.
Whether any triangle touches the box box placed by boxToMesh (into
this tree's space; default identity), three-mesh-bvh's intersectsBox:
an OrientedBox shapecast. A three Box3 and Matrix4 pass.
OptionalboxToMesh: BvhMatrix4Like | nullWhether any triangle touches a triangle of other placed by
geometryToBvh (into this tree's space; default identity),
three-mesh-bvh's intersectsGeometry. other is a tree or a mesh
({ positions, indices }). Against a tree it is a bvhcast
testing each pair as three-mesh-bvh does (the other's triangle, moved,
against this one's), so the answer is the same; three-mesh-bvh 0.9.18
shapecasts the other tree from each leaf instead, which measured 1.5x
slower here. Against a mesh, every triangle of it is tested against
the leaves its bounding box reaches, as three-mesh-bvh does.
OptionalgeometryToBvh: BvhMatrix4Like | nullWhether any triangle touches the sphere (three-mesh-bvh's intersectsSphere). A three Sphere passes.
Whether point is inside the mesh: at least two of three rays vote it
inside (insideVotes). rule is 'parity' (the default; odd
crossings, any winding) or 'winding' (non-zero signed crossings;
overlapping closed parts stay inside, triangles must be wound
consistently). Exact for a closed mesh away from its surface; on an open
mesh, rays through a hole disagree and the vote decides (docs/tracing/sdf.mdx).
The CPU twin of the GPU's bvhIsInside.
Every hit on the faces side selects, sorted by distance. The second
argument is the side (three's FrontSide/BackSide/DoubleSide
values), a BvhRaycastOptions, or anything with side (a three
material); near and far may follow, as in three-mesh-bvh.
OptionalsideOrOptions: number | BvhRaycastOptionsOptionalnear: numberOptionalfar: numberThe closest hit, or null. Arguments as raycast.
OptionalsideOrOptions: number | BvhRaycastOptionsOptionalnear: numberOptionalfar: numberEvery triangle the ray from origin along direction crosses at
t >= 0, both faces: how many, and their signed sum (+1 for each
triangle the ray leaves through its front side, -1 for each it enters
through it). The CPU twin of the GPU's bvhRayCrossings: the same
watertight walk, in doubles. A ray exactly on a shared edge counts both
triangles, as the walk does.
Loads the corners at a tree position into a triangle (as the tree stores them) and sets its needsUpdate.
Refits the boxes to moved vertices, keeping the tree's shape (as the GPU
refit does, refitOnCpu): the triangle records get the new corners,
then every box is recomputed bottom up. input replaces the source
(default: reread the source's positions, which may have been edited in
place). The triangle count and the index buffer's meaning must not have
changed. A tree refitted after large moves stays correct but gets slower
to walk; rebuild it then.
With corners: 'positions' there are no records to write: the leaf
boxes are recomputed from the positions through the tree's own vertex
indices (input's index buffer only has to have the same triangle
count), and input, when given, becomes the source the queries read
corners from. The boxes are the records path's bit for bit.
Optionalinput: MeshInputThe original triangle index at a tree position (as traverse reports them).
The tree as bytes (serializeLayout's format). The source geometry isn't included.
three-mesh-bvh's shapecast (0.9.18): traverse, with each
leaf's triangles handed to intersectsTriangle as an
ExtendedTriangle (a scratch object, reloaded per triangle, with
needsUpdate set) and the original triangle index. Boxes come as
BvhBox3. Returns true when a callback stopped the cast.
Walks the tree, asking callbacks which boxes to enter and handing over
triangle ranges, with three-mesh-bvh's shapecast contract
(BvhTraverseCallbacks): depth first, the root's box never asked
about, each child scored once by boundsTraverseOrder and the lower
score visited first, a falsy intersectsBounds skipping the box, a
contained box reported as one range, and a truthy intersectsRange
stopping the walk. Returns true when it was stopped.
three-mesh-bvh's node walk (BVH.traverse(callback), 0.9.18), for the
debug utilities and the helper: every node in depth-first order, left
before right, starting with the root at depth 0 (its box the tree's
bounds; a one-leaf tree's root is that leaf). box is a new
Float32Array(6), [minX, minY, minZ, maxX, maxY, maxZ], per node. A
leaf gets its first tree position and triangle count; an inner node
gets its split axis (0, 1, 2), which our layout doesn't store: it is
taken as the axis along which the children's centres lie furthest
apart. A truthy return skips the node's children.
The tree position of an original triangle.
three-mesh-bvh's writePrimitiveRangeBounds: the box around the
triangles at tree positions offset to offset + count - 1, into
target at targetOffset as [minX, minY, minZ, maxX, maxY, maxZ].
Read from the source geometry when the tree has one (so edits made
since the build or the last refit show, as three-mesh-bvh reads
the geometry), else from the corners the tree stores.
One mesh's tree, for CPU queries. See the file comment.
Hitis what raycast returns: BvhRaycastHit here; an engine adapter (@pmndrs/bvh/three'sBvhBoundsTree) overrides createHit to return its engine's type.