Struct Bvh

Source
pub struct Bvh { /* private fields */ }
Expand description

A Bounding Volume Hierarchy designed for spatial queries and physics engine broad-phases.

Implementations§

Source§

impl Bvh

Source

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

Source

pub fn insert(&mut self, aabb: Aabb, leaf_index: u32)

Inserts a leaf into this BVH, or updates it if already exists.

Source

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.

Source

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

Source

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

Source

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.

Source

pub fn project_point( &self, point: &OPoint<f32, Const<3>>, 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).

Source

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

Source

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 by Self::insert_or_update_partially (if change_detection_margin was nonzero) from leaves to its ascendants.
Source

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

Source

pub fn leaves<F>(&self, check_node: F) -> Leaves<'_, F>
where F: Fn(&BvhNode) -> bool,

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

Source

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

pub fn find_best<L>( &self, max_cost: f32, aabb_cost: impl Fn(&BvhNode, f32) -> f32, leaf_cost: impl Fn(u32, f32) -> Option<L>, ) -> Option<(u32, L)>
where L: BvhLeafCost,

Find the leaf that minimizes their associated cost.

Source§

impl Bvh

Source

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.

Source

pub fn leaf_pairs<'a, F>(&'a self, other: &'a Bvh, check: F) -> LeafPairs<'a, F>
where F: Fn(&BvhNode, &BvhNode) -> bool,

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

Source

pub fn new() -> Bvh

An empty BVH.

Source

pub fn from_leaves(strategy: BvhBuildStrategy, leaves: &[Aabb]) -> Bvh

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.

Source

pub fn from_iter<It>(strategy: BvhBuildStrategy, leaves: It) -> Bvh
where It: IntoIterator<Item = (usize, Aabb)>,

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).

Source

pub fn root_aabb(&self) -> Aabb

The AABB bounding everything contained by this BVH.

Source

pub fn scale( &mut self, scale: &Matrix<f32, Const<3>, Const<1>, ArrayStorage<f32, 3, 1>>, )

Scales this tree’s geometry by the given factor.

This is only valid if all elements of scale are positive.

Source

pub fn is_empty(&self) -> bool

Does this tree not contain any leaf?

Source

pub fn leaf_node(&self, leaf_key: u32) -> Option<&BvhNode>

Reference to the leaf associated to the given index at construction time.

Source

pub fn total_memory_size(&self) -> usize

An approximation of the memory usage (in bytes) for this struct plus the memory it allocates dynamically.

Source

pub fn heap_memory_size(&self) -> usize

An approximation of the memory dynamically-allocated by this struct.

Source

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.

Source

pub fn leaf_count(&self) -> u32

The number of leaves of this tree.

Source

pub fn remove(&mut self, leaf_index: u32)

Deletes the leaf at the given index.

The operation is O(h) where h is the tree height (which, if optimized should be close to n log(n) where n is the leaf count). It will update the leaf counts and AABBs of all ancestors of the removed leaf.

Source§

impl Bvh

Source

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.

Source

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.

Source

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.

Source

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.

Source

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§

Source§

impl Clone for Bvh

Source§

fn clone(&self) -> Bvh

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Bvh

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for Bvh

Source§

fn default() -> Bvh

Returns the “default value” for a type. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts 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>

Converts 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)

Converts &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)

Converts &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
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Sync + Send>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V