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}