box3d_rust/dynamic_tree/
rebuild.rs1use super::{DynamicTree, ENLARGED_NODE, TREE_STACK_SIZE};
8use crate::core::NULL_INDEX;
9use crate::math_functions::{aabb_center, aabb_union, add, max, min, mul_sv, sub, Vec3};
10
11fn max_u16(a: u16, b: u16) -> u16 {
12 if a > b {
13 a
14 } else {
15 b
16 }
17}
18
19fn partition_mid(indices: &mut [i32], centers: &mut [Vec3]) -> i32 {
21 let count = indices.len();
22
23 if count <= 2 {
25 return (count / 2) as i32;
26 }
27
28 let mut lower_bound = centers[0];
29 let mut upper_bound = centers[0];
30
31 for center in centers.iter().skip(1) {
32 lower_bound = min(lower_bound, *center);
33 upper_bound = max(upper_bound, *center);
34 }
35
36 let d = sub(upper_bound, lower_bound);
37 let c = mul_sv(0.5, add(lower_bound, upper_bound));
38
39 let (mut i1, mut i2) = (0usize, count);
43 if d.x >= d.y && d.x >= d.z {
44 let pivot = c.x;
45
46 while i1 < i2 {
47 while i1 < i2 && centers[i1].x < pivot {
48 i1 += 1;
49 }
50
51 while i1 < i2 && centers[i2 - 1].x >= pivot {
52 i2 -= 1;
53 }
54
55 if i1 < i2 {
56 indices.swap(i1, i2 - 1);
57 centers.swap(i1, i2 - 1);
58
59 i1 += 1;
60 i2 -= 1;
61 }
62 }
63 } else if d.y >= d.z {
64 let pivot = c.y;
65
66 while i1 < i2 {
67 while i1 < i2 && centers[i1].y < pivot {
68 i1 += 1;
69 }
70
71 while i1 < i2 && centers[i2 - 1].y >= pivot {
72 i2 -= 1;
73 }
74
75 if i1 < i2 {
76 indices.swap(i1, i2 - 1);
77 centers.swap(i1, i2 - 1);
78
79 i1 += 1;
80 i2 -= 1;
81 }
82 }
83 } else {
84 let pivot = c.z;
85
86 while i1 < i2 {
87 while i1 < i2 && centers[i1].z < pivot {
88 i1 += 1;
89 }
90
91 while i1 < i2 && centers[i2 - 1].z >= pivot {
92 i2 -= 1;
93 }
94
95 if i1 < i2 {
96 indices.swap(i1, i2 - 1);
97 centers.swap(i1, i2 - 1);
98
99 i1 += 1;
100 i2 -= 1;
101 }
102 }
103 }
104 debug_assert!(i1 == i2);
105
106 if i1 > 0 && i1 < count {
107 i1 as i32
108 } else {
109 (count / 2) as i32
110 }
111}
112
113#[derive(Clone, Copy, Default)]
116struct RebuildItem {
117 node_index: i32,
118 child_count: i32,
119 start_index: i32,
121 split_index: i32,
122 end_index: i32,
123}
124
125impl DynamicTree {
126 fn build_tree(&mut self, leaf_count: i32) -> i32 {
128 if leaf_count == 1 {
129 let leaf = self.leaf_indices[0];
130 self.nodes[leaf as usize].parent = NULL_INDEX;
131 return leaf;
132 }
133
134 let mut stack = vec![RebuildItem::default(); TREE_STACK_SIZE];
135 let mut top = 0usize;
136
137 stack[0].node_index = self.allocate_node();
138 stack[0].child_count = -1;
139 stack[0].start_index = 0;
140 stack[0].end_index = leaf_count;
141 stack[0].split_index = {
142 let (indices, centers) = (&mut self.leaf_indices, &mut self.leaf_centers);
144 partition_mid(
145 &mut indices[..leaf_count as usize],
146 &mut centers[..leaf_count as usize],
147 )
148 };
149
150 loop {
151 stack[top].child_count += 1;
152 let item = stack[top];
153
154 if item.child_count == 2 {
155 if top == 0 {
158 break;
160 }
161
162 let parent_item = stack[top - 1];
163
164 if parent_item.child_count == 0 {
165 debug_assert!(self.nodes[parent_item.node_index as usize].child1 == NULL_INDEX);
166 self.nodes[parent_item.node_index as usize].child1 = item.node_index;
167 } else {
168 debug_assert!(parent_item.child_count == 1);
169 debug_assert!(self.nodes[parent_item.node_index as usize].child2 == NULL_INDEX);
170 self.nodes[parent_item.node_index as usize].child2 = item.node_index;
171 }
172
173 let node_index = item.node_index as usize;
174 debug_assert!(self.nodes[node_index].parent == NULL_INDEX);
175 self.nodes[node_index].parent = parent_item.node_index;
176
177 debug_assert!(self.nodes[node_index].child1 != NULL_INDEX);
178 debug_assert!(self.nodes[node_index].child2 != NULL_INDEX);
179 let c1 = self.nodes[node_index].child1 as usize;
180 let c2 = self.nodes[node_index].child2 as usize;
181
182 self.nodes[node_index].aabb = aabb_union(self.nodes[c1].aabb, self.nodes[c2].aabb);
183 self.nodes[node_index].height =
184 1 + max_u16(self.nodes[c1].height, self.nodes[c2].height);
185 self.nodes[node_index].category_bits =
186 self.nodes[c1].category_bits | self.nodes[c2].category_bits;
187
188 top -= 1;
190 } else {
191 let (start_index, end_index) = if item.child_count == 0 {
192 (item.start_index, item.split_index)
193 } else {
194 debug_assert!(item.child_count == 1);
195 (item.split_index, item.end_index)
196 };
197
198 let count = end_index - start_index;
199
200 if count == 1 {
201 let child_index = self.leaf_indices[start_index as usize];
202 let node_index = item.node_index as usize;
203
204 if item.child_count == 0 {
205 debug_assert!(self.nodes[node_index].child1 == NULL_INDEX);
206 self.nodes[node_index].child1 = child_index;
207 } else {
208 debug_assert!(item.child_count == 1);
209 debug_assert!(self.nodes[node_index].child2 == NULL_INDEX);
210 self.nodes[node_index].child2 = child_index;
211 }
212
213 debug_assert!(self.nodes[child_index as usize].parent == NULL_INDEX);
214 self.nodes[child_index as usize].parent = item.node_index;
215 } else {
216 debug_assert!(count > 0);
217 debug_assert!(top < TREE_STACK_SIZE);
218
219 top += 1;
220 let node_index = self.allocate_node();
221 let split_index = {
222 let (s, e) = (start_index as usize, end_index as usize);
223 let (indices, centers) = (&mut self.leaf_indices, &mut self.leaf_centers);
224 partition_mid(&mut indices[s..e], &mut centers[s..e])
225 };
226 let new_item = &mut stack[top];
227 new_item.node_index = node_index;
228 new_item.child_count = -1;
229 new_item.start_index = start_index;
230 new_item.end_index = end_index;
231 new_item.split_index = split_index + start_index;
232 }
233 }
234 }
235
236 let root_index = stack[0].node_index as usize;
237 debug_assert!(self.nodes[root_index].parent == NULL_INDEX);
238 debug_assert!(self.nodes[root_index].child1 != NULL_INDEX);
239 debug_assert!(self.nodes[root_index].child2 != NULL_INDEX);
240
241 let c1 = self.nodes[root_index].child1 as usize;
242 let c2 = self.nodes[root_index].child2 as usize;
243
244 self.nodes[root_index].aabb = aabb_union(self.nodes[c1].aabb, self.nodes[c2].aabb);
245 self.nodes[root_index].height = 1 + max_u16(self.nodes[c1].height, self.nodes[c2].height);
246 self.nodes[root_index].category_bits =
247 self.nodes[c1].category_bits | self.nodes[c2].category_bits;
248
249 stack[0].node_index
250 }
251
252 pub fn rebuild(&mut self, full_build: bool) -> i32 {
255 let proxy_count = self.proxy_count;
256 if proxy_count == 0 {
257 return 0;
258 }
259
260 if proxy_count > self.rebuild_capacity {
262 let new_capacity = proxy_count + proxy_count / 2;
263
264 self.leaf_indices = vec![0; new_capacity as usize];
265 self.leaf_centers = vec![Vec3::default(); new_capacity as usize];
266 self.rebuild_capacity = new_capacity;
267 }
268
269 let mut leaf_count = 0usize;
270 let mut stack = [0i32; TREE_STACK_SIZE];
271 let mut stack_count = 0usize;
272
273 let mut node_index = self.root;
274
275 loop {
279 let node = self.nodes[node_index as usize];
280 if node.is_leaf() || (node.flags & ENLARGED_NODE == 0 && !full_build) {
281 self.leaf_indices[leaf_count] = node_index;
282 self.leaf_centers[leaf_count] = aabb_center(node.aabb);
283 leaf_count += 1;
284
285 self.nodes[node_index as usize].parent = NULL_INDEX;
287 } else {
288 let doomed_node_index = node_index;
289
290 node_index = node.child1;
292
293 debug_assert!(stack_count < TREE_STACK_SIZE);
294 if stack_count < TREE_STACK_SIZE {
295 stack[stack_count] = node.child2;
296 stack_count += 1;
297 }
298
299 self.free_node(doomed_node_index);
301
302 continue;
303 }
304
305 if stack_count == 0 {
306 break;
307 }
308
309 stack_count -= 1;
310 node_index = stack[stack_count];
311 }
312
313 debug_assert!(leaf_count <= proxy_count as usize);
314
315 self.root = self.build_tree(leaf_count as i32);
316
317 self.validate();
318
319 leaf_count as i32
320 }
321}