pub struct DynamicBvh { /* private fields */ }Expand description
Dynamic AABB Tree (DBVT) for broadphase collision detection.
Supports incremental insert, remove, and update operations.
Uses the surface-area heuristic (SAH) to choose the best sibling when
inserting a new leaf.
Implementations§
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn insert(&mut self, aabb: BvhAabb, data: u32) -> usize
pub fn insert(&mut self, aabb: BvhAabb, data: u32) -> usize
Insert a leaf AABB with associated data. Returns the leaf node index.
The leaf is stored with a fat AABB (expanded by FAT_MARGIN) to
reduce the frequency of re-insertions when the object moves slightly.
Sourcepub fn update(&mut self, leaf: usize, new_aabb: BvhAabb) -> bool
pub fn update(&mut self, leaf: usize, new_aabb: BvhAabb) -> bool
Update an existing leaf’s AABB.
If new_aabb still fits within the leaf’s current fat AABB, the tree
is unchanged and false is returned. Otherwise the leaf is removed and
reinserted with a fresh fat AABB, and true is returned.
Sourcepub fn query_overlapping_pairs(&self) -> Vec<(u32, u32)>
pub fn query_overlapping_pairs(&self) -> Vec<(u32, u32)>
Return all leaf-data pairs (a, b) where a < b and the leaves
overlap. Uses a stack-based traversal.
Sourcepub fn query_aabb(&self, aabb: &BvhAabb) -> Vec<u32>
pub fn query_aabb(&self, aabb: &BvhAabb) -> Vec<u32>
Return the data of all leaves whose fat AABB overlaps aabb.
Sourcepub fn query_point(&self, point: Vec3) -> Vec<u32>
pub fn query_point(&self, point: Vec3) -> Vec<u32>
Return the data of all leaves whose fat AABB contains point.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn refit_all(&mut self)
pub fn refit_all(&mut self)
Refit all internal-node AABBs from leaves upward (full refit pass).
Useful after bulk updates.
Sourcepub fn ray_cast(
&self,
origin: Vec3,
dir: Vec3,
t_min: f64,
t_max: f64,
) -> Vec<(u32, f64)>
pub fn ray_cast( &self, origin: Vec3, dir: Vec3, t_min: f64, t_max: f64, ) -> Vec<(u32, f64)>
Ray cast against all leaves; returns data of all leaves hit.
origin + dir * t for t ∈ [t_min, t_max].
Sourcepub fn query_aabb_filtered(
&self,
aabb: &BvhAabb,
filter: impl Fn(u32) -> bool,
) -> Vec<u32>
pub fn query_aabb_filtered( &self, aabb: &BvhAabb, filter: impl Fn(u32) -> bool, ) -> Vec<u32>
Overlap query: return data of all leaves that overlap query_aabb and
whose data value satisfies filter.
This is an enhanced version of query_aabb that supports a predicate.
Sourcepub fn insert_bulk(&mut self, items: &[(BvhAabb, u32)]) -> Vec<usize>
pub fn insert_bulk(&mut self, items: &[(BvhAabb, u32)]) -> Vec<usize>
Bulk insert many (aabb, data) pairs and return their leaf indices.
Sourcepub fn all_leaf_data(&self) -> Vec<u32>
pub fn all_leaf_data(&self) -> Vec<u32>
Collect all leaf data values in the tree (arbitrary order).
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn quality_metrics(&self) -> Option<BvhQuality>
pub fn quality_metrics(&self) -> Option<BvhQuality>
Compute BVH quality metrics via a single DFS traversal.
Returns None if the tree is empty.
Sourcepub fn quality_degraded(&self, threshold: f64) -> bool
pub fn quality_degraded(&self, threshold: f64) -> bool
Return true if the SAH cost is above threshold (tree quality degraded).
Useful as a trigger to rebuild the tree from scratch.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn frustum_query(&self, frustum: &BvhFrustum) -> Vec<u32>
pub fn frustum_query(&self, frustum: &BvhFrustum) -> Vec<u32>
Return the data of all leaves potentially visible inside frustum.
Uses a stack-based traversal that prunes subtrees whose AABB is fully outside any frustum plane.
Source§impl DynamicBvh
impl DynamicBvh
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn serialize(&self) -> Vec<f64>
pub fn serialize(&self) -> Vec<f64>
Serialize the entire tree into a flat Vecf64`.
Format per node (14 values):
\[min_x, min_y, min_z, max_x, max_y, max_z, parent_or_neg1, left_or_neg1, right_or_neg1, data_or_neg1, height, is_leaf, is_on_free_list, PADDING]
The first element of the buffer is the total number of nodes (as f64).
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn move_proxy(
&mut self,
leaf: usize,
new_aabb: BvhAabb,
velocity: Vec3,
dt: f64,
) -> bool
pub fn move_proxy( &mut self, leaf: usize, new_aabb: BvhAabb, velocity: Vec3, dt: f64, ) -> bool
Update leaf leaf using a new tight AABB expanded in the direction of
velocity * dt (speculative / predicted motion).
The resulting fat AABB covers both the current and predicted positions.
Returns true if the tree was modified (re-insertion occurred).
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn try_rotate(&mut self, idx: usize) -> bool
pub fn try_rotate(&mut self, idx: usize) -> bool
Attempt one SAH-improving rotation at node idx.
Tries swapping each grandchild with its uncle; keeps the swap only if it strictly reduces the total surface area of the two affected internal nodes.
Returns true if a rotation was performed.
Sourcepub fn optimize_rotations(&mut self)
pub fn optimize_rotations(&mut self)
Perform one bottom-up pass of SAH-improving rotations across the tree.
Visits every non-leaf node from leaves upward and attempts try_rotate.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn refit_leaf_ancestors(&mut self, leaf: usize)
pub fn refit_leaf_ancestors(&mut self, leaf: usize)
Refit only the ancestors of a specific leaf node.
More efficient than refit_all when only one leaf changed.
Sourcepub fn update_leaf_inplace(&mut self, leaf: usize, new_aabb: BvhAabb)
pub fn update_leaf_inplace(&mut self, leaf: usize, new_aabb: BvhAabb)
Update a leaf’s AABB in place without re-inserting it, then refit its ancestor chain.
Only use this when new_aabb is contained within the current fat AABB;
otherwise the tree’s AABBs may become incorrect. For unconstrained moves
use DynamicBvh::update or DynamicBvh::move_proxy.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn compute_sah_cost(&self) -> f64
pub fn compute_sah_cost(&self) -> f64
Compute the Surface Area Heuristic (SAH) cost of the entire tree.
This is an alias for DynamicBvh::sah_cost provided under the name
requested by the algorithm expansion spec so that callers can use either
name without changing existing code.
Returns 0.0 for an empty or degenerate tree.
Sourcepub fn balance_rotation(&mut self) -> usize
pub fn balance_rotation(&mut self) -> usize
Apply one round of balance-improving rotations to the entire tree.
Walks every internal node in bottom-up order and attempts a single
SAH-improving swap (see try_rotate). Nodes are visited from
shallowest to deepest so that parent improvements propagate before
children are processed.
Returns the number of rotations that were accepted.
Sourcepub fn traverse_frustum(&self, frustum: &BvhFrustum) -> Vec<u32>
pub fn traverse_frustum(&self, frustum: &BvhFrustum) -> Vec<u32>
Frustum-culling traversal: return data of all leaves whose fat AABB is
potentially inside frustum.
This is a named alias for frustum_query following the algorithm
expansion spec. Uses a stack-based traversal that prunes fully-outside
subtrees for O(k + log n) complexity where k is the number of hits.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn node_depth(&self, idx: usize) -> Option<usize>
pub fn node_depth(&self, idx: usize) -> Option<usize>
Return the depth of a given node in the tree (root = 0).
Returns None if idx is on the free list.
Sourcepub fn find_leaf(&self, target: u32) -> Option<usize>
pub fn find_leaf(&self, target: u32) -> Option<usize>
Return the leaf node index whose data matches target, or None.
Sourcepub fn leaf_data_preorder(&self) -> Vec<u32>
pub fn leaf_data_preorder(&self) -> Vec<u32>
Collect all leaf data in DFS pre-order (left-first).
Sourcepub fn root_aabb(&self) -> Option<BvhAabb>
pub fn root_aabb(&self) -> Option<BvhAabb>
Return the AABB of the root node, or None if the tree is empty.
Sourcepub fn n_internal(&self) -> usize
pub fn n_internal(&self) -> usize
Return the number of internal nodes (non-leaf, non-free).
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn query_sphere(&self, center: Vec3, radius: f64) -> Vec<u32>
pub fn query_sphere(&self, center: Vec3, radius: f64) -> Vec<u32>
Return data of all leaves whose fat AABB overlaps a sphere defined by
center and radius.
Uses the AABB-vs-sphere test: the sphere overlaps an AABB iff the
squared distance from center to the nearest point on the AABB is ≤ radius².
Sourcepub fn any_in_sphere(&self, center: Vec3, radius: f64) -> bool
pub fn any_in_sphere(&self, center: Vec3, radius: f64) -> bool
Return true if any leaf’s fat AABB overlaps the given sphere.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn query_capsule(&self, capsule: BvhCapsule) -> Vec<u32>
pub fn query_capsule(&self, capsule: BvhCapsule) -> Vec<u32>
Return data of all leaves whose fat AABB is hit by a capsule query.
Implemented as AABB-vs-segment-distance test: an AABB intersects the
capsule iff the minimum distance from the AABB to the line segment is
≤ capsule.radius.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn rebuild(&mut self)
pub fn rebuild(&mut self)
Rebuild the tree from scratch using the current fat AABBs of all leaves.
Removes all nodes, collects leaf data and AABBs, then re-inserts them. This is a full O(n log n) rebuild; use only when the tree is severely degraded (e.g. after many updates without rotations).
Sourcepub fn leaf_snapshot(&self) -> Vec<(u32, BvhAabb)>
pub fn leaf_snapshot(&self) -> Vec<(u32, BvhAabb)>
Return a snapshot of all leaf (data, fat_aabb) pairs without
modifying the tree.
Sourcepub fn leaf_aabb(&self, idx: usize) -> Option<BvhAabb>
pub fn leaf_aabb(&self, idx: usize) -> Option<BvhAabb>
Return the fat AABB for a given leaf idx, or None if it is not
a valid leaf.
Sourcepub fn remove_where(&mut self, pred: impl Fn(u32) -> bool) -> usize
pub fn remove_where(&mut self, pred: impl Fn(u32) -> bool) -> usize
Remove all leaves whose data value satisfies pred.
Returns the number of leaves removed.
Sourcepub fn relabel_leaf(&mut self, leaf: usize, new_data: u32) -> bool
pub fn relabel_leaf(&mut self, leaf: usize, new_data: u32) -> bool
Replace the data value of a leaf without changing its AABB.
Returns true if the leaf was found and updated.
Source§impl DynamicBvh
impl DynamicBvh
Sourcepub fn subtree_leaf_count(&self, idx: usize) -> usize
pub fn subtree_leaf_count(&self, idx: usize) -> usize
Return the number of leaves in the subtree rooted at idx.
Sourcepub fn validate_heights(&self) -> bool
pub fn validate_heights(&self) -> bool
Return true if the heights stored in nodes are consistent with the
actual tree structure.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for DynamicBvh
impl RefUnwindSafe for DynamicBvh
impl Send for DynamicBvh
impl Sync for DynamicBvh
impl Unpin for DynamicBvh
impl UnsafeUnpin for DynamicBvh
impl UnwindSafe for DynamicBvh
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.