pub struct Bvh { /* private fields */ }
Expand description
A Bounding Volume Hierarchy designed for spatial queries and physics engine broad-phases.
Implementations§
Source§impl Bvh
impl Bvh
Sourcepub fn rebuild(
&mut self,
workspace: &mut BvhWorkspace,
strategy: BvhBuildStrategy,
)
pub fn rebuild( &mut self, workspace: &mut BvhWorkspace, strategy: BvhBuildStrategy, )
Fully rebuilds this BVH using the given strategy.
This rebuilds a BVH with the same leaves, but different intermediate nodes and depth using the specified building strategy.
Source§impl Bvh
impl Bvh
Sourcepub fn insert(&mut self, aabb: Aabb, leaf_index: u32)
pub fn insert(&mut self, aabb: Aabb, leaf_index: u32)
Inserts a leaf into this BVH, or updates it if already exists.
Sourcepub fn insert_with_change_detection(
&mut self,
aabb: Aabb,
leaf_index: u32,
change_detection_margin: f32,
)
pub fn insert_with_change_detection( &mut self, aabb: Aabb, leaf_index: u32, change_detection_margin: f32, )
Inserts a leaf into this BVH, or updates it if already exists.
If the aabb
is already contained by the existing leaf node AABB, nothing is modified.
Otherwise, the aabb being effectively inserted is equal to aabb
enlarged by the
change_detection_margin
.
Sourcepub fn insert_or_update_partially(
&mut self,
aabb: Aabb,
leaf_index: u32,
change_detection_margin: f32,
)
pub fn insert_or_update_partially( &mut self, aabb: Aabb, leaf_index: u32, change_detection_margin: f32, )
Either inserts a node on this tree, or, if it already exists, updates its associated bounding but doesn’t update its ascendant nodes.
This method is primarily designed to be called for inserting new nodes or updating existing
ones, and then running a Bvh::refit
. Until Bvh::refit
or Bvh::refit_without_opt
is called, the BVH will effectively be left in an invalid state where some internal nodes
might no longer enclose their children.
For an alternative that inserts a node while also making sure all its ascendants are
up to date, see Bvh::insert
.
Source§impl Bvh
impl Bvh
Sourcepub fn optimize_incremental(&mut self, workspace: &mut BvhWorkspace)
pub fn optimize_incremental(&mut self, workspace: &mut BvhWorkspace)
Performs one step of incremental optimization of the tree.
Incremental optimization of the tree ensures that after modification of the tree’s geometry (after changes of its leaves AABBs) doesn’t lead to a poorly shaped tree, or tree with poor spatial culling capabilities.
This optimization is incremental because it only optimizes a subset of the tree in order to reduce its computational cost. It is indented to be called multiple times across multiple frames.
For example, if the BVH is used for a physics engine’s broad-phase, this method would typically be called once by simulation step.
Source§impl Bvh
impl Bvh
Sourcepub fn intersect_aabb<'a>(
&'a self,
aabb: &'a Aabb,
) -> impl Iterator<Item = u32> + 'a
pub fn intersect_aabb<'a>( &'a self, aabb: &'a Aabb, ) -> impl Iterator<Item = u32> + 'a
Iterates through all the leaves with an AABB intersecting the given aabb
.
Sourcepub fn project_point(
&self,
point: &Point<f32>,
max_distance: f32,
primitive_check: impl Fn(u32, f32) -> Option<PointProjection>,
) -> Option<(u32, (f32, PointProjection))>
pub fn project_point( &self, point: &Point<f32>, max_distance: f32, primitive_check: impl Fn(u32, f32) -> Option<PointProjection>, ) -> Option<(u32, (f32, PointProjection))>
Projects a point on this BVH using the provided leaf projection function.
The primitive_check
delegates the point-projection task to an external function that
is assumed to map a leaf index to an actual geometry to project on. The Real
argument
given to that closure is the distance to the closest point found so far (or is equal to
max_distance
if no projection was found so far).
Sourcepub fn cast_ray(
&self,
ray: &Ray,
max_time_of_impact: f32,
primitive_check: impl Fn(u32, f32) -> Option<f32>,
) -> Option<(u32, f32)>
pub fn cast_ray( &self, ray: &Ray, max_time_of_impact: f32, primitive_check: impl Fn(u32, f32) -> Option<f32>, ) -> Option<(u32, f32)>
Casts a ray on this BVH using the provided leaf ray-cast function.
The primitive_check
delegates the ray-casting task to an external function that
is assumed to map a leaf index to an actual geometry to cast a ray on. The Real
argument
given to that closure is the distance to the closest ray hit found so far (or is equal to
max_time_of_impact
if no projection was found so far).
Source§impl Bvh
impl Bvh
Sourcepub fn refit(&mut self, workspace: &mut BvhWorkspace)
pub fn refit(&mut self, workspace: &mut BvhWorkspace)
Performs a tree refitting with internal storage cache optimizations.
Refitting is the action of ensuring that every node’s AABB encloses the AABBs of its children. In addition, this method will:
- Ensure that nodes are stored internally in depth-first order for better cache locality on depth-first searches.
- Ensure that the leaf count on each node is correct.
- Propagate the
BvhNode::is_changed
flag changes detected bySelf::insert_or_update_partially
(ifchange_detection_margin
was nonzero) from leaves to its ascendants.
Sourcepub fn refit_without_opt(&mut self)
pub fn refit_without_opt(&mut self)
Similar to Self::refit
but without any optimization of the internal node storage layout.
This can be faster than Self::refit
but doesn’t reorder node to be more cache-efficient
on tree traversals.
Source§impl Bvh
impl Bvh
Sourcepub fn leaves<F: Fn(&BvhNode) -> bool>(&self, check_node: F) -> Leaves<'_, F>
pub fn leaves<F: Fn(&BvhNode) -> bool>(&self, check_node: F) -> Leaves<'_, F>
Iterates through the leaves, in depth-first order.
The check_node
closure is called on every traversed node. If it returns false
then the
node and all its descendants won’t be iterated on. This is useful for pruning whole
sub-trees based on a geometric predicate on the node’s AABB.
See also the Bvh::traverse
function which is slightly less convenient since it doesn’t
rely on the iterator system, but takes a closure that implements FnMut
instead of Fn
.
Source§impl Bvh
impl Bvh
Sourcepub fn traverse(&self, check_node: impl FnMut(&BvhNode) -> TraversalAction)
pub fn traverse(&self, check_node: impl FnMut(&BvhNode) -> TraversalAction)
Traverse the tree in depth-first order.
The check_node
closure is called on every traversed node. The returned TraversalAction
controls whether a given node (and all its subtree) needs to be traversed, skipped, or if
the traversal needs to exit immediately (for example if you were looking for only one
particular node).
See also the Bvh::leaves
iterator which is a more convenient way of traversing the tree,
but is slightly limited in terms of node checking. In particular the closure
given to Bvh::traverse
is mutable can hold any state so its check can depend on previous
execution of itself during the traversal.
Source§impl Bvh
impl Bvh
Sourcepub fn traverse_bvtt_single_tree<const CHANGE_DETECTION: bool>(
&self,
workspace: &mut BvhWorkspace,
f: &mut impl FnMut(u32, u32),
)
pub fn traverse_bvtt_single_tree<const CHANGE_DETECTION: bool>( &self, workspace: &mut BvhWorkspace, f: &mut impl FnMut(u32, u32), )
Traverses the Bounding Volume Test Tree of a tree against itself.
The closure f
will be called on each pair of leaf that passed the AABB intersection checks.
If CHANGE_DETECTION
is true
, then only pairs of leaves where at least one was detected
as changed during Self::insert_or_update_partially
will be traversed.
Sourcepub fn leaf_pairs<'a, F: Fn(&BvhNode, &BvhNode) -> bool>(
&'a self,
other: &'a Self,
check: F,
) -> LeafPairs<'a, F>
pub fn leaf_pairs<'a, F: Fn(&BvhNode, &BvhNode) -> bool>( &'a self, other: &'a Self, check: F, ) -> LeafPairs<'a, F>
Performs a simultaneous traversal of the BVHs self
and other
, and yields the pairs
of leaves it reached.
Any node pairs failing the given check
will be excluded from the traversal.
Source§impl Bvh
impl Bvh
Sourcepub fn from_leaves(strategy: BvhBuildStrategy, leaves: &[Aabb]) -> Self
pub fn from_leaves(strategy: BvhBuildStrategy, leaves: &[Aabb]) -> Self
Creates a new BVH with a slice of AABBs.
Each leaf will be associated an index equal to its position into the slice. For example,
the AABB leaves[42]
is associated to the leaf with index 42.
Sourcepub fn from_iter<It>(strategy: BvhBuildStrategy, leaves: It) -> Self
pub fn from_iter<It>(strategy: BvhBuildStrategy, leaves: It) -> Self
Creates a new BVH with leaves given by an iterator.
The iterator yields leaf index and aabbs. The leaf indices will then be read back by various methods like tree traversals or leaf iterations.
Note that the indices are stored internally as u32
. The iterator expects usize
for convenience (so that iterators built with .enumerate()
can be used directly
without an additional cast of the usize
index to u32
).
Sourcepub fn scale(&mut self, scale: &Vector<f32>)
pub fn scale(&mut self, scale: &Vector<f32>)
Scales this tree’s geometry by the given factor.
This is only valid if all elements of scale
are positive.
Sourcepub fn leaf_node(&self, leaf_key: u32) -> Option<&BvhNode>
pub fn leaf_node(&self, leaf_key: u32) -> Option<&BvhNode>
Reference to the leaf associated to the given index at construction time.
Sourcepub fn total_memory_size(&self) -> usize
pub fn total_memory_size(&self) -> usize
An approximation of the memory usage (in bytes) for this struct plus the memory it allocates dynamically.
Sourcepub fn heap_memory_size(&self) -> usize
pub fn heap_memory_size(&self) -> usize
An approximation of the memory dynamically-allocated by this struct.
Sourcepub fn subtree_depth(&self, node_id: u32) -> u32
pub fn subtree_depth(&self, node_id: u32) -> u32
The depth of the sub-tree rooted at the node with index node_id
.
Set node_id
to 0 to get the depth of the whole tree.
Sourcepub fn leaf_count(&self) -> u32
pub fn leaf_count(&self) -> u32
The number of leaves of this tree.
Source§impl Bvh
impl Bvh
Sourcepub fn reachable_leaf_count(&self, id: u32) -> u32
pub fn reachable_leaf_count(&self, id: u32) -> u32
Counts the number of leaves that can be reached from the node at index id
.
This is mostly a utility for debugging.
Sourcepub fn changed_leaf_count(&self, id: u32) -> u32
pub fn changed_leaf_count(&self, id: u32) -> u32
Counts the number of leaves of self
, starting with the subtree indexed at
id
, that are marked as changed.
This mostly a utility for debugging.
Sourcepub fn assert_well_formed(&self)
pub fn assert_well_formed(&self)
Panics if the tree isn’t well-formed.
The tree is well-formed if it is topologically correct (internal indices are all valid) and geometrically correct (node metadata of a parent bound the ones of the children).
Returns the calculated leaf count.
Sourcepub fn assert_well_formed_topology_only(&self)
pub fn assert_well_formed_topology_only(&self)
Similar to Self::assert_well_formed
but doesn’t check the geometry (i.e. it won’t
check that parent AABBs enclose child AABBs).
This can be useful for checking intermediate states of the tree after topological changes but before refitting.
Sourcepub fn assert_is_depth_first(&self)
pub fn assert_is_depth_first(&self)
Panics if the nodes of self
are not stored in depth-first order on its internal storage.
Depth-first ordering of self
’s internals are guaranteed by Self::refit
.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Bvh
impl RefUnwindSafe for Bvh
impl Send for Bvh
impl Sync for Bvh
impl Unpin for Bvh
impl UnwindSafe for Bvh
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
, which can then be
downcast
into Box<dyn ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
, which can then be further
downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
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<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.