Skip to content

Commit

Permalink
Add bvh visitor thatt allows a context to be passed to the children o…
Browse files Browse the repository at this point in the history
…f a node
  • Loading branch information
Makogan (Makogan) committed Apr 24, 2024
1 parent 51b7cc1 commit e59b575
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 19 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## v0.13.7

### Unreleased

- Added new visitor logic to QBVH to allow parent nodes to pass a context to their children.

### Modified

- The `point_in_poly2d` now handles arbitrary (convex and non-convex) polygons. The previous implementation
Expand Down
16 changes: 8 additions & 8 deletions src/partitioning/qbvh/traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::bounding_volume::{Aabb, SimdAabb};
use crate::math::Real;
use crate::partitioning::visitor::{SimdSimultaneousVisitStatus, SimdVisitorContext};
use crate::partitioning::visitor::{SimdSimultaneousVisitStatus, SimdVisitorWithContext};
use crate::partitioning::{
GenericQbvh, QbvhStorage, SimdBestFirstVisitStatus, SimdBestFirstVisitor,
SimdSimultaneousVisitor, SimdVisitStatus, SimdVisitor,
Expand Down Expand Up @@ -115,12 +115,12 @@ impl<LeafData: IndexedData, Storage: QbvhStorage<LeafData>> GenericQbvh<LeafData
/// # Return
///
/// Returns `false` if the traversal exitted early, and `true` otherwise.
pub fn traverse_depth_first_context<Context: Clone>(
pub fn traverse_depth_first_with_context<Context: Clone>(
&self,
visitor: &mut impl SimdVisitorContext<LeafData, SimdAabb, Context>,
visitor: &mut impl SimdVisitorWithContext<LeafData, SimdAabb, Context>,
context: Context,
) -> bool {
self.traverse_depth_first_node_with_stack_context(visitor, &mut Vec::new(), 0, context)
self.traverse_depth_first_node_with_stack_and_context(visitor, &mut Vec::new(), 0, context)
}

/// Performs a depth-first traversal on the BVH and propagates a context down,
Expand All @@ -130,9 +130,9 @@ impl<LeafData: IndexedData, Storage: QbvhStorage<LeafData>> GenericQbvh<LeafData
/// # Return
///
/// Returns `false` if the traversal exited early, and `true` otherwise.
pub fn traverse_depth_first_node_with_stack_context<Context: Clone>(
pub fn traverse_depth_first_node_with_stack_and_context<Context: Clone>(
&self,
visitor: &mut impl SimdVisitorContext<LeafData, SimdAabb, Context>,
visitor: &mut impl SimdVisitorWithContext<LeafData, SimdAabb, Context>,
stack: &mut Vec<(u32, Context)>,
start_node: u32,
context: Context,
Expand All @@ -152,7 +152,7 @@ impl<LeafData: IndexedData, Storage: QbvhStorage<LeafData>> GenericQbvh<LeafData
None
};

let (visit_result, context) = visitor.visit(&node.simd_aabb, leaf_data, context);
let (visit_result, contexts) = visitor.visit(&node.simd_aabb, leaf_data, context);
match visit_result {
SimdVisitStatus::ExitEarly => {
return false;
Expand All @@ -166,7 +166,7 @@ impl<LeafData: IndexedData, Storage: QbvhStorage<LeafData>> GenericQbvh<LeafData
// Un fortunately, we have this check because invalid Aabbs
// return a hit as well.
if node.children[ii] as usize <= self.nodes.len() {
stack.push((node.children[ii], context.clone()));
stack.push((node.children[ii], contexts[ii].clone()));
}
}
}
Expand Down
18 changes: 8 additions & 10 deletions src/partitioning/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ where
}

/// Trait implemented by visitor called during the traversal of a spatial partitioning data structure.
pub trait SimdVisitorContext<LeafData, SimdBV, Context: Clone> {
pub trait SimdVisitorWithContext<LeafData, SimdBV, Context: Clone> {
/// Execute an operation on the content of a node of the spatial partitioning structure.
///
/// Returns whether the traversal should continue on the node's children, if it should not continue
Expand All @@ -91,26 +91,24 @@ pub trait SimdVisitorContext<LeafData, SimdBV, Context: Clone> {
bv: &SimdBV,
data: Option<[Option<&LeafData>; SIMD_WIDTH]>,
context: Context,
) -> (SimdVisitStatus, Context);
) -> (SimdVisitStatus, [Context; SIMD_WIDTH]);
}

impl<F, LeafData, SimdBV, Context: Clone> SimdVisitorContext<LeafData, SimdBV, Context> for F
impl<T, LeafData, SimdBV, Context: Clone> SimdVisitorWithContext<LeafData, SimdBV, Context> for T
where
F: FnMut(
&SimdBV,
Option<[Option<&LeafData>; SIMD_WIDTH]>,
Context,
) -> (SimdVisitStatus, Context),
T: SimdVisitor<LeafData, SimdBV>,
{
fn visit(
&mut self,
bv: &SimdBV,
data: Option<[Option<&LeafData>; SIMD_WIDTH]>,
context: Context,
) -> (SimdVisitStatus, Context) {
(self)(bv, data, context)
) -> (SimdVisitStatus, [Context; SIMD_WIDTH]) {
let contexts = std::array::from_fn(|_| context.clone());
(self.visit(bv, data), contexts)
}
}

/// Trait implemented by visitor called during a simultaneous spatial partitioning data structure tarversal.
pub trait SimdSimultaneousVisitor<T1, T2, SimdBV> {
/// Execute an operation on the content of two nodes, one from each structure.
Expand Down
2 changes: 1 addition & 1 deletion src/utils/weighted_value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::math::Real;
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use std::cmp::Ordering;

#[derive(Copy, Clone)]
pub struct WeightedValue<T> {
Expand Down

0 comments on commit e59b575

Please sign in to comment.