parry3d_f64/partitioning/
visitor.rs

1use crate::math::{Real, SimdBool, SimdReal, SIMD_WIDTH};
2
3#[cfg(all(feature = "alloc", feature = "parallel"))]
4use crate::partitioning::{qbvh::QbvhNode, SimdNodeIndex};
5
6/// The next action to be taken by a BVH traversal algorithm after having visited a node with some data.
7pub enum SimdBestFirstVisitStatus<Res> {
8    /// The traversal can continue.
9    MaybeContinue {
10        /// The weight associated to each child of the node being traversed.
11        weights: SimdReal,
12        /// Each lane indicates if the corresponding child of the node being traversed
13        /// should be traversed too.
14        mask: SimdBool,
15        /// Optional results associated to each child of the node being traversed.
16        results: [Option<Res>; SIMD_WIDTH],
17    },
18    /// The traversal aborts.
19    ///
20    /// If a data is provided, then it is returned as the result of the traversal.
21    /// If no result is provided, then the last best result found becomes the result of the traversal.
22    ExitEarly(Option<Res>),
23}
24
25/// Trait implemented by cost functions used by the best-first search on a `BVT`.
26pub trait SimdBestFirstVisitor<LeafData, SimdBV> {
27    /// The result of a best-first traversal.
28    type Result;
29
30    /// Compute the next action to be taken by the best-first-search after visiting a node containing the given bounding volume.
31    fn visit(
32        &mut self,
33        best_cost_so_far: Real,
34        bv: &SimdBV,
35        value: Option<[Option<&LeafData>; SIMD_WIDTH]>,
36    ) -> SimdBestFirstVisitStatus<Self::Result>;
37}
38
39/// The status of the spatial partitioning structure traversal.
40pub enum SimdVisitStatus {
41    /// The traversal should continue on the children of the currently visited nodes for which
42    /// the boolean lane is set to `1`.
43    MaybeContinue(SimdBool),
44    /// The traversal should exit immediately.
45    ExitEarly,
46}
47
48/// The status of the simultaneous traversal of two spatial partitioning structures.
49pub enum SimdSimultaneousVisitStatus {
50    /// The traversal should continue on the children of the currently visited nodes for which
51    /// the boolean lane is set to `1`.
52    MaybeContinue([SimdBool; SIMD_WIDTH]),
53    /// The traversal should exit immediately.
54    ExitEarly,
55}
56
57/// Trait implemented by visitor called during the traversal of a spatial partitioning data structure.
58pub trait SimdVisitor<LeafData, SimdBV> {
59    /// Execute an operation on the content of a node of the spatial partitioning structure.
60    ///
61    /// Returns whether the traversal should continue on the node's children, if it should not continue
62    /// on those children, or if the whole traversal should be exited early.
63    fn visit(
64        &mut self,
65        bv: &SimdBV,
66        data: Option<[Option<&LeafData>; SIMD_WIDTH]>,
67    ) -> SimdVisitStatus;
68}
69
70impl<F, LeafData, SimdBV> SimdVisitor<LeafData, SimdBV> for F
71where
72    F: FnMut(&SimdBV, Option<[Option<&LeafData>; SIMD_WIDTH]>) -> SimdVisitStatus,
73{
74    fn visit(
75        &mut self,
76        bv: &SimdBV,
77        data: Option<[Option<&LeafData>; SIMD_WIDTH]>,
78    ) -> SimdVisitStatus {
79        (self)(bv, data)
80    }
81}
82
83/// Trait implemented by visitor called during the traversal of a spatial partitioning data structure.
84pub trait SimdVisitorWithContext<LeafData, SimdBV, Context: Clone> {
85    /// Execute an operation on the content of a node of the spatial partitioning structure.
86    ///
87    /// Returns whether the traversal should continue on the node's children, if it should not continue
88    /// on those children, or if the whole traversal should be exited early. Also returns
89    /// a context, which may or may not be identical to the input context.
90    fn visit(
91        &mut self,
92        bv: &SimdBV,
93        data: Option<[Option<&LeafData>; SIMD_WIDTH]>,
94        context: Context,
95    ) -> (SimdVisitStatus, [Context; SIMD_WIDTH]);
96}
97
98/// Trait implemented by visitor called during a simultaneous spatial partitioning data structure tarversal.
99pub trait SimdSimultaneousVisitor<T1, T2, SimdBV> {
100    /// Execute an operation on the content of two nodes, one from each structure.
101    ///
102    /// Returns whether the traversal should continue on the nodes children, if it should not continue
103    /// on those children, or if the whole traversal should be exited early.
104    fn visit(
105        &mut self,
106        left_bv: &SimdBV,
107        left_data: Option<[Option<&T1>; SIMD_WIDTH]>,
108        right_bv: &SimdBV,
109        right_data: Option<[Option<&T2>; SIMD_WIDTH]>,
110    ) -> SimdSimultaneousVisitStatus;
111}
112
113/*
114 *
115 * Parallel visitors below.
116 *
117 */
118
119/// Trait implemented by visitor called during the parallel traversal of a spatial partitioning data structure.
120#[cfg(all(feature = "alloc", feature = "parallel"))]
121pub trait ParallelSimdVisitor<LeafData>: Sync {
122    /// Execute an operation on the content of a node of the spatial partitioning structure.
123    ///
124    /// Returns whether the traversal should continue on the node's children, if it should not continue
125    /// on those children, or if the whole traversal should be exited early.
126    fn visit(
127        &self,
128        node_id: SimdNodeIndex,
129        bv: &QbvhNode,
130        data: Option<[Option<&LeafData>; SIMD_WIDTH]>,
131    ) -> SimdVisitStatus;
132}
133
134#[cfg(all(feature = "alloc", feature = "parallel"))]
135impl<F, LeafData> ParallelSimdVisitor<LeafData> for F
136where
137    F: Sync + Fn(&QbvhNode, Option<[Option<&LeafData>; SIMD_WIDTH]>) -> SimdVisitStatus,
138{
139    fn visit(
140        &self,
141        _node_id: SimdNodeIndex,
142        node: &QbvhNode,
143        data: Option<[Option<&LeafData>; SIMD_WIDTH]>,
144    ) -> SimdVisitStatus {
145        (self)(node, data)
146    }
147}
148
149/// Trait implemented by visitor called during a parallel simultaneous spatial partitioning
150/// data structure traversal.
151#[cfg(all(feature = "alloc", feature = "parallel"))]
152pub trait ParallelSimdSimultaneousVisitor<LeafData1, LeafData2>: Sync {
153    /// Visitor state data that will be passed down the recursion.
154    type Data: Copy + Sync + Default;
155
156    /// Execute an operation on the content of two nodes, one from each structure.
157    ///
158    /// Returns whether the traversal should continue on the nodes children, if it should not continue
159    /// on those children, or if the whole traversal should be exited early.
160    fn visit(
161        &self,
162        left_node_id: SimdNodeIndex,
163        left_node: &QbvhNode,
164        left_data: Option<[Option<&LeafData1>; SIMD_WIDTH]>,
165        right_node_id: SimdNodeIndex,
166        right_node: &QbvhNode,
167        right_data: Option<[Option<&LeafData2>; SIMD_WIDTH]>,
168        visitor_data: Self::Data,
169    ) -> (SimdSimultaneousVisitStatus, Self::Data);
170}