box2d_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, max, min, sub, Vec2};
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 [Vec2]) -> 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 = Vec2 {
38 x: 0.5 * (lower_bound.x + upper_bound.x),
39 y: 0.5 * (lower_bound.y + upper_bound.y),
40 };
41
42 let (mut i1, mut i2) = (0usize, count);
46 if d.x > d.y {
47 let pivot = c.x;
48
49 while i1 < i2 {
50 while i1 < i2 && centers[i1].x < pivot {
51 i1 += 1;
52 }
53
54 while i1 < i2 && centers[i2 - 1].x >= pivot {
55 i2 -= 1;
56 }
57
58 if i1 < i2 {
59 indices.swap(i1, i2 - 1);
60 centers.swap(i1, i2 - 1);
61
62 i1 += 1;
63 i2 -= 1;
64 }
65 }
66 } else {
67 let pivot = c.y;
68
69 while i1 < i2 {
70 while i1 < i2 && centers[i1].y < pivot {
71 i1 += 1;
72 }
73
74 while i1 < i2 && centers[i2 - 1].y >= pivot {
75 i2 -= 1;
76 }
77
78 if i1 < i2 {
79 indices.swap(i1, i2 - 1);
80 centers.swap(i1, i2 - 1);
81
82 i1 += 1;
83 i2 -= 1;
84 }
85 }
86 }
87 debug_assert!(i1 == i2);
88
89 if i1 > 0 && i1 < count {
90 i1 as i32
91 } else {
92 (count / 2) as i32
93 }
94}
95
96#[derive(Clone, Copy, Default)]
99struct RebuildItem {
100 node_index: i32,
101 child_count: i32,
102 start_index: i32,
104 split_index: i32,
105 end_index: i32,
106}
107
108impl DynamicTree {
109 fn build_tree(&mut self, leaf_count: i32) -> i32 {
111 if leaf_count == 1 {
112 let leaf = self.leaf_indices[0];
113 self.nodes[leaf as usize].parent = NULL_INDEX;
114 return leaf;
115 }
116
117 let mut stack = vec![RebuildItem::default(); TREE_STACK_SIZE];
118 let mut top = 0usize;
119
120 stack[0].node_index = self.allocate_node();
121 stack[0].child_count = -1;
122 stack[0].start_index = 0;
123 stack[0].end_index = leaf_count;
124 stack[0].split_index = {
125 let (indices, centers) = (&mut self.leaf_indices, &mut self.leaf_centers);
127 partition_mid(
128 &mut indices[..leaf_count as usize],
129 &mut centers[..leaf_count as usize],
130 )
131 };
132
133 loop {
134 stack[top].child_count += 1;
135 let item = stack[top];
136
137 if item.child_count == 2 {
138 if top == 0 {
141 break;
143 }
144
145 let parent_item = stack[top - 1];
146
147 if parent_item.child_count == 0 {
148 debug_assert!(self.nodes[parent_item.node_index as usize].child1 == NULL_INDEX);
149 self.nodes[parent_item.node_index as usize].child1 = item.node_index;
150 } else {
151 debug_assert!(parent_item.child_count == 1);
152 debug_assert!(self.nodes[parent_item.node_index as usize].child2 == NULL_INDEX);
153 self.nodes[parent_item.node_index as usize].child2 = item.node_index;
154 }
155
156 let node_index = item.node_index as usize;
157 debug_assert!(self.nodes[node_index].parent == NULL_INDEX);
158 self.nodes[node_index].parent = parent_item.node_index;
159
160 debug_assert!(self.nodes[node_index].child1 != NULL_INDEX);
161 debug_assert!(self.nodes[node_index].child2 != NULL_INDEX);
162 let c1 = self.nodes[node_index].child1 as usize;
163 let c2 = self.nodes[node_index].child2 as usize;
164
165 self.nodes[node_index].aabb = aabb_union(self.nodes[c1].aabb, self.nodes[c2].aabb);
166 self.nodes[node_index].height =
167 1 + max_u16(self.nodes[c1].height, self.nodes[c2].height);
168 self.nodes[node_index].category_bits =
169 self.nodes[c1].category_bits | self.nodes[c2].category_bits;
170
171 top -= 1;
173 } else {
174 let (start_index, end_index) = if item.child_count == 0 {
175 (item.start_index, item.split_index)
176 } else {
177 debug_assert!(item.child_count == 1);
178 (item.split_index, item.end_index)
179 };
180
181 let count = end_index - start_index;
182
183 if count == 1 {
184 let child_index = self.leaf_indices[start_index as usize];
185 let node_index = item.node_index as usize;
186
187 if item.child_count == 0 {
188 debug_assert!(self.nodes[node_index].child1 == NULL_INDEX);
189 self.nodes[node_index].child1 = child_index;
190 } else {
191 debug_assert!(item.child_count == 1);
192 debug_assert!(self.nodes[node_index].child2 == NULL_INDEX);
193 self.nodes[node_index].child2 = child_index;
194 }
195
196 debug_assert!(self.nodes[child_index as usize].parent == NULL_INDEX);
197 self.nodes[child_index as usize].parent = item.node_index;
198 } else {
199 debug_assert!(count > 0);
200 debug_assert!(top < TREE_STACK_SIZE);
201
202 top += 1;
203 let node_index = self.allocate_node();
204 let split_index = {
205 let (s, e) = (start_index as usize, end_index as usize);
206 let (indices, centers) = (&mut self.leaf_indices, &mut self.leaf_centers);
207 partition_mid(&mut indices[s..e], &mut centers[s..e])
208 };
209 let new_item = &mut stack[top];
210 new_item.node_index = node_index;
211 new_item.child_count = -1;
212 new_item.start_index = start_index;
213 new_item.end_index = end_index;
214 new_item.split_index = split_index + start_index;
215 }
216 }
217 }
218
219 let root_index = stack[0].node_index as usize;
220 debug_assert!(self.nodes[root_index].parent == NULL_INDEX);
221 debug_assert!(self.nodes[root_index].child1 != NULL_INDEX);
222 debug_assert!(self.nodes[root_index].child2 != NULL_INDEX);
223
224 let c1 = self.nodes[root_index].child1 as usize;
225 let c2 = self.nodes[root_index].child2 as usize;
226
227 self.nodes[root_index].aabb = aabb_union(self.nodes[c1].aabb, self.nodes[c2].aabb);
228 self.nodes[root_index].height = 1 + max_u16(self.nodes[c1].height, self.nodes[c2].height);
229 self.nodes[root_index].category_bits =
230 self.nodes[c1].category_bits | self.nodes[c2].category_bits;
231
232 stack[0].node_index
233 }
234
235 pub fn rebuild(&mut self, full_build: bool) -> i32 {
238 let proxy_count = self.proxy_count;
239 if proxy_count == 0 {
240 return 0;
241 }
242
243 if proxy_count > self.rebuild_capacity {
245 let new_capacity = proxy_count + proxy_count / 2;
246
247 self.leaf_indices = vec![0; new_capacity as usize];
248 self.leaf_centers = vec![Vec2::default(); new_capacity as usize];
249 self.rebuild_capacity = new_capacity;
250 }
251
252 let mut leaf_count = 0usize;
253 let mut stack = [0i32; TREE_STACK_SIZE];
254 let mut stack_count = 0usize;
255
256 let mut node_index = self.root;
257
258 loop {
262 let node = self.nodes[node_index as usize];
263 if node.height == 0 || (node.flags & ENLARGED_NODE == 0 && !full_build) {
264 self.leaf_indices[leaf_count] = node_index;
265 self.leaf_centers[leaf_count] = aabb_center(node.aabb);
266 leaf_count += 1;
267
268 self.nodes[node_index as usize].parent = NULL_INDEX;
270 } else {
271 let doomed_node_index = node_index;
272
273 node_index = node.child1;
275
276 if stack_count < TREE_STACK_SIZE {
277 stack[stack_count] = node.child2;
278 stack_count += 1;
279 } else {
280 debug_assert!(stack_count < TREE_STACK_SIZE);
281 }
282
283 self.free_node(doomed_node_index);
285
286 continue;
287 }
288
289 if stack_count == 0 {
290 break;
291 }
292
293 stack_count -= 1;
294 node_index = stack[stack_count];
295 }
296
297 debug_assert!(leaf_count <= proxy_count as usize);
298
299 self.root = self.build_tree(leaf_count as i32);
300
301 self.validate();
302
303 leaf_count as i32
304 }
305}