1use super::*;
6
7#[must_use]
8pub struct NodeFinisher<'a, T: Aabb, S> {
9 axis: AxisDyn,
10 div: Option<T::Num>, mid: &'a mut [T],
12 sorter: S,
13 num_elem: usize,
14}
15impl<'a, T: Aabb, S: Sorter<T>> NodeFinisher<'a, T, S> {
16 pub fn get_num_elem(&self) -> usize {
17 self.num_elem
18 }
19 #[inline(always)]
20 #[must_use]
21 pub fn finish(self) -> Node<'a, T> {
22 fn create_cont<A: Axis, T: Aabb>(axis: A, middle: &[T]) -> axgeom::Range<T::Num> {
23 match middle.split_first() {
24 Some((first, rest)) => {
25 let mut min = first.get().get_range(axis).start;
26 let mut max = first.get().get_range(axis).end;
27
28 for a in rest.iter() {
29 let start = &a.get().get_range(axis).start;
30 let end = &a.get().get_range(axis).end;
31
32 if *start < min {
33 min = *start;
34 }
35
36 if *end > max {
37 max = *end;
38 }
39 }
40
41 axgeom::Range {
42 start: min,
43 end: max,
44 }
45 }
46 None => axgeom::Range {
47 start: Default::default(),
48 end: Default::default(),
49 },
50 }
51 }
52
53 let cont = match self.axis {
54 AxisDyn::X => {
55 self.sorter.sort(axgeom::XAXIS.next(), self.mid);
56 create_cont(axgeom::XAXIS, self.mid)
57 }
58 AxisDyn::Y => {
59 self.sorter.sort(axgeom::YAXIS.next(), self.mid);
60 create_cont(axgeom::YAXIS, self.mid)
61 }
62 };
63
64 Node {
65 num_elem: self.num_elem,
66 range: AabbPin::new(self.mid),
67 cont,
68 div: self.div,
69 }
70 }
71}
72
73pub struct TreeBuildVisitor<'a, T, S> {
77 bots: &'a mut [T],
78 current_height: usize,
79 sorter: S,
80 axis: AxisDyn,
81}
82
83pub struct NodeBuildResult<'a, T: Aabb, S> {
84 pub node: NodeFinisher<'a, T, S>,
85 pub rest: Option<[TreeBuildVisitor<'a, T, S>; 2]>,
86}
87
88impl<'a, T: Aabb, S: Sorter<T>> TreeBuildVisitor<'a, T, S> {
89 pub fn get_bots(&self) -> &[T] {
90 self.bots
91 }
92 #[must_use]
93 pub fn new(num_levels: usize, bots: &'a mut [T], sorter: S) -> TreeBuildVisitor<'a, T, S> {
94 assert!(num_levels >= 1);
95 TreeBuildVisitor {
96 bots,
97 current_height: num_levels - 1,
98 sorter,
99 axis: default_axis().to_dyn(),
100 }
101 }
102 #[must_use]
103 pub fn get_height(&self) -> usize {
104 self.current_height
105 }
106 #[must_use]
107 pub fn build_and_next(self) -> NodeBuildResult<'a, T, S> {
108 if self.current_height == 0 {
110 let node = NodeFinisher {
111 mid: self.bots,
112 div: None,
113 axis: self.axis,
114 sorter: self.sorter,
115 num_elem: 0,
116 };
117
118 NodeBuildResult { node, rest: None }
119 } else {
120 fn construct_non_leaf<T: Aabb>(
121 div_axis: impl Axis,
122 bots: &mut [T],
123 ) -> ConstructResult<T> {
124 if bots.is_empty() {
125 return ConstructResult {
126 mid: &mut [],
127 div: None,
128 left: &mut [],
129 right: &mut [],
130 };
131 }
132
133 let med_index = bots.len() / 2;
134 let (_, med, _) = bots.select_nth_unstable_by(med_index, move |a, b| {
135 crate::util::compare_bots(div_axis, a, b)
136 });
137
138 let med_val = med.get().get_range(div_axis).start;
139
140 let binned = oned::bin_middle_left_right(div_axis, &med_val, bots);
147
148 ConstructResult {
149 mid: binned.middle,
150 div: Some(med_val),
151 left: binned.left,
152 right: binned.right,
153 }
154 }
155
156 let rr = match self.axis {
157 AxisDyn::X => construct_non_leaf(axgeom::XAXIS, self.bots),
158 AxisDyn::Y => construct_non_leaf(axgeom::YAXIS, self.bots),
159 };
160
161 let finish_node = NodeFinisher {
162 mid: rr.mid,
163 div: rr.div,
164 axis: self.axis,
165 sorter: self.sorter,
166 num_elem: rr.left.len().min(rr.right.len()),
167 };
168
169 let left = rr.left;
170 let right = rr.right;
171
172 NodeBuildResult {
173 node: finish_node,
174 rest: Some([
175 TreeBuildVisitor {
176 bots: left,
177 current_height: self.current_height.saturating_sub(1),
178 sorter: self.sorter,
179 axis: self.axis.next(),
180 },
181 TreeBuildVisitor {
182 bots: right,
183 current_height: self.current_height.saturating_sub(1),
184 sorter: self.sorter,
185 axis: self.axis.next(),
186 },
187 ]),
188 }
189 }
190 }
191
192 pub fn recurse_seq(self, res: &mut Vec<Node<'a, T>>) {
193 let NodeBuildResult { node, rest } = self.build_and_next();
194 res.push(node.finish());
195 if let Some([left, right]) = rest {
196 left.recurse_seq(res);
197 right.recurse_seq(res);
198 }
199 }
200}
201
202struct ConstructResult<'a, T: Aabb> {
203 div: Option<T::Num>,
204 mid: &'a mut [T],
205 right: &'a mut [T],
206 left: &'a mut [T],
207}
208
209#[derive(Copy, Clone, Default)]
210pub struct DefaultSorter;
211
212impl<T: Aabb> Sorter<T> for DefaultSorter {
213 fn sort(&self, axis: impl Axis, bots: &mut [T]) {
214 crate::util::sweeper_update(axis, bots);
215 }
216}
217
218#[derive(Copy, Clone, Default)]
219pub struct NoSorter;
220
221impl<T: Aabb> Sorter<T> for NoSorter {
222 fn sort(&self, _axis: impl Axis, _bots: &mut [T]) {}
223}