1use super::{DynamicTree, ALLOCATED_NODE, ENLARGED_NODE, LEAF_NODE};
7use crate::aabb::{enlarge_aabb, perimeter};
8use crate::core::NULL_INDEX;
9use crate::math_functions::{
10 aabb_center, aabb_contains, aabb_union, is_valid_aabb, length_squared, min_float, sub, Aabb,
11};
12
13fn max_u16(a: u16, b: u16) -> u16 {
14 if a > b {
15 a
16 } else {
17 b
18 }
19}
20
21fn find_best_sibling(tree: &DynamicTree, box_d: Aabb) -> i32 {
41 let center_d = aabb_center(box_d);
42 let area_d = perimeter(box_d);
43
44 let nodes = &tree.nodes;
45 let root_index = tree.root;
46
47 let root_box = nodes[root_index as usize].aabb;
48
49 let mut area_base = perimeter(root_box);
51
52 let mut direct_cost = perimeter(aabb_union(root_box, box_d));
54 let mut inherited_cost = 0.0;
55
56 let mut best_sibling = root_index;
57 let mut best_cost = direct_cost;
58
59 let mut index = root_index;
61 while nodes[index as usize].height > 0 {
62 let child1 = nodes[index as usize].child1;
63 let child2 = nodes[index as usize].child2;
64
65 let cost = direct_cost + inherited_cost;
67
68 if cost < best_cost {
71 best_sibling = index;
72 best_cost = cost;
73 }
74
75 inherited_cost += direct_cost - area_base;
77
78 let leaf1 = nodes[child1 as usize].height == 0;
79 let leaf2 = nodes[child2 as usize].height == 0;
80
81 let mut lower_cost1 = f32::MAX;
83 let box1 = nodes[child1 as usize].aabb;
84 let direct_cost1 = perimeter(aabb_union(box1, box_d));
85 let mut area1 = 0.0;
86 if leaf1 {
87 let cost1 = direct_cost1 + inherited_cost;
90
91 if cost1 < best_cost {
93 best_sibling = child1;
94 best_cost = cost1;
95 }
96 } else {
97 area1 = perimeter(box1);
99
100 lower_cost1 = inherited_cost + direct_cost1 + min_float(area_d - area1, 0.0);
106 }
107
108 let mut lower_cost2 = f32::MAX;
110 let box2 = nodes[child2 as usize].aabb;
111 let direct_cost2 = perimeter(aabb_union(box2, box_d));
112 let mut area2 = 0.0;
113 if leaf2 {
114 let cost2 = direct_cost2 + inherited_cost;
115
116 if cost2 < best_cost {
117 best_sibling = child2;
118 best_cost = cost2;
119 }
120 } else {
121 area2 = perimeter(box2);
122 lower_cost2 = inherited_cost + direct_cost2 + min_float(area_d - area2, 0.0);
123 }
124
125 if leaf1 && leaf2 {
126 break;
127 }
128
129 if best_cost <= lower_cost1 && best_cost <= lower_cost2 {
131 break;
132 }
133
134 if lower_cost1 == lower_cost2 && !leaf1 {
135 debug_assert!(lower_cost1 < f32::MAX);
136 debug_assert!(lower_cost2 < f32::MAX);
137
138 let d1 = sub(aabb_center(box1), center_d);
142 let d2 = sub(aabb_center(box2), center_d);
143 lower_cost1 = length_squared(d1);
144 lower_cost2 = length_squared(d2);
145 }
146
147 if lower_cost1 < lower_cost2 && !leaf1 {
149 index = child1;
150 area_base = area1;
151 direct_cost = direct_cost1;
152 } else {
153 index = child2;
154 area_base = area2;
155 direct_cost = direct_cost2;
156 }
157
158 debug_assert!(nodes[index as usize].height > 0);
159 }
160
161 best_sibling
162}
163
164enum RotateType {
166 None,
167 Bf,
168 Bg,
169 Cd,
170 Ce,
171}
172
173impl DynamicTree {
174 fn rotate_nodes(&mut self, i_a: i32) {
177 debug_assert!(i_a != NULL_INDEX);
178
179 let nodes = &mut self.nodes;
180
181 if nodes[i_a as usize].height < 2 {
182 return;
183 }
184
185 let i_b = nodes[i_a as usize].child1;
186 let i_c = nodes[i_a as usize].child2;
187 debug_assert!(0 <= i_b && (i_b as usize) < nodes.len());
188 debug_assert!(0 <= i_c && (i_c as usize) < nodes.len());
189
190 let (ia, ib, ic) = (i_a as usize, i_b as usize, i_c as usize);
191
192 if nodes[ib].height == 0 {
193 debug_assert!(nodes[ic].height > 0);
195
196 let i_f = nodes[ic].child1;
197 let i_g = nodes[ic].child2;
198 let (if_, ig) = (i_f as usize, i_g as usize);
199 debug_assert!(0 <= i_f && (i_f as usize) < nodes.len());
200 debug_assert!(0 <= i_g && (i_g as usize) < nodes.len());
201
202 let cost_base = perimeter(nodes[ic].aabb);
204
205 let aabb_bg = aabb_union(nodes[ib].aabb, nodes[ig].aabb);
207 let cost_bf = perimeter(aabb_bg);
208
209 let aabb_bf = aabb_union(nodes[ib].aabb, nodes[if_].aabb);
211 let cost_bg = perimeter(aabb_bf);
212
213 if cost_base < cost_bf && cost_base < cost_bg {
214 return;
216 }
217
218 if cost_bf < cost_bg {
219 nodes[ia].child1 = i_f;
221 nodes[ic].child1 = i_b;
222
223 nodes[ib].parent = i_c;
224 nodes[if_].parent = i_a;
225
226 nodes[ic].aabb = aabb_bg;
227
228 nodes[ic].height = 1 + max_u16(nodes[ib].height, nodes[ig].height);
229 nodes[ia].height = 1 + max_u16(nodes[ic].height, nodes[if_].height);
230 nodes[ic].category_bits = nodes[ib].category_bits | nodes[ig].category_bits;
231 nodes[ia].category_bits = nodes[ic].category_bits | nodes[if_].category_bits;
232 nodes[ic].flags |= (nodes[ib].flags | nodes[ig].flags) & ENLARGED_NODE;
233 nodes[ia].flags |= (nodes[ic].flags | nodes[if_].flags) & ENLARGED_NODE;
234 } else {
235 nodes[ia].child1 = i_g;
237 nodes[ic].child2 = i_b;
238
239 nodes[ib].parent = i_c;
240 nodes[ig].parent = i_a;
241
242 nodes[ic].aabb = aabb_bf;
243
244 nodes[ic].height = 1 + max_u16(nodes[ib].height, nodes[if_].height);
245 nodes[ia].height = 1 + max_u16(nodes[ic].height, nodes[ig].height);
246 nodes[ic].category_bits = nodes[ib].category_bits | nodes[if_].category_bits;
247 nodes[ia].category_bits = nodes[ic].category_bits | nodes[ig].category_bits;
248 nodes[ic].flags |= (nodes[ib].flags | nodes[if_].flags) & ENLARGED_NODE;
249 nodes[ia].flags |= (nodes[ic].flags | nodes[ig].flags) & ENLARGED_NODE;
250 }
251 } else if nodes[ic].height == 0 {
252 debug_assert!(nodes[ib].height > 0);
254
255 let i_d = nodes[ib].child1;
256 let i_e = nodes[ib].child2;
257 let (id, ie) = (i_d as usize, i_e as usize);
258 debug_assert!(0 <= i_d && (i_d as usize) < nodes.len());
259 debug_assert!(0 <= i_e && (i_e as usize) < nodes.len());
260
261 let cost_base = perimeter(nodes[ib].aabb);
263
264 let aabb_ce = aabb_union(nodes[ic].aabb, nodes[ie].aabb);
266 let cost_cd = perimeter(aabb_ce);
267
268 let aabb_cd = aabb_union(nodes[ic].aabb, nodes[id].aabb);
270 let cost_ce = perimeter(aabb_cd);
271
272 if cost_base < cost_cd && cost_base < cost_ce {
273 return;
275 }
276
277 if cost_cd < cost_ce {
278 nodes[ia].child2 = i_d;
280 nodes[ib].child1 = i_c;
281
282 nodes[ic].parent = i_b;
283 nodes[id].parent = i_a;
284
285 nodes[ib].aabb = aabb_ce;
286
287 nodes[ib].height = 1 + max_u16(nodes[ic].height, nodes[ie].height);
288 nodes[ia].height = 1 + max_u16(nodes[ib].height, nodes[id].height);
289 nodes[ib].category_bits = nodes[ic].category_bits | nodes[ie].category_bits;
290 nodes[ia].category_bits = nodes[ib].category_bits | nodes[id].category_bits;
291 nodes[ib].flags |= (nodes[ic].flags | nodes[ie].flags) & ENLARGED_NODE;
292 nodes[ia].flags |= (nodes[ib].flags | nodes[id].flags) & ENLARGED_NODE;
293 } else {
294 nodes[ia].child2 = i_e;
296 nodes[ib].child2 = i_c;
297
298 nodes[ic].parent = i_b;
299 nodes[ie].parent = i_a;
300
301 nodes[ib].aabb = aabb_cd;
302 nodes[ib].height = 1 + max_u16(nodes[ic].height, nodes[id].height);
303 nodes[ia].height = 1 + max_u16(nodes[ib].height, nodes[ie].height);
304 nodes[ib].category_bits = nodes[ic].category_bits | nodes[id].category_bits;
305 nodes[ia].category_bits = nodes[ib].category_bits | nodes[ie].category_bits;
306 nodes[ib].flags |= (nodes[ic].flags | nodes[id].flags) & ENLARGED_NODE;
307 nodes[ia].flags |= (nodes[ib].flags | nodes[ie].flags) & ENLARGED_NODE;
308 }
309 } else {
310 let i_d = nodes[ib].child1;
311 let i_e = nodes[ib].child2;
312 let i_f = nodes[ic].child1;
313 let i_g = nodes[ic].child2;
314
315 let (id, ie, if_, ig) = (i_d as usize, i_e as usize, i_f as usize, i_g as usize);
316
317 debug_assert!(0 <= i_d && (i_d as usize) < nodes.len());
318 debug_assert!(0 <= i_e && (i_e as usize) < nodes.len());
319 debug_assert!(0 <= i_f && (i_f as usize) < nodes.len());
320 debug_assert!(0 <= i_g && (i_g as usize) < nodes.len());
321
322 let area_b = perimeter(nodes[ib].aabb);
324 let area_c = perimeter(nodes[ic].aabb);
325 let cost_base = area_b + area_c;
326 let mut best_rotation = RotateType::None;
327 let mut best_cost = cost_base;
328
329 let aabb_bg = aabb_union(nodes[ib].aabb, nodes[ig].aabb);
331 let cost_bf = area_b + perimeter(aabb_bg);
332 if cost_bf < best_cost {
333 best_rotation = RotateType::Bf;
334 best_cost = cost_bf;
335 }
336
337 let aabb_bf = aabb_union(nodes[ib].aabb, nodes[if_].aabb);
339 let cost_bg = area_b + perimeter(aabb_bf);
340 if cost_bg < best_cost {
341 best_rotation = RotateType::Bg;
342 best_cost = cost_bg;
343 }
344
345 let aabb_ce = aabb_union(nodes[ic].aabb, nodes[ie].aabb);
347 let cost_cd = area_c + perimeter(aabb_ce);
348 if cost_cd < best_cost {
349 best_rotation = RotateType::Cd;
350 best_cost = cost_cd;
351 }
352
353 let aabb_cd = aabb_union(nodes[ic].aabb, nodes[id].aabb);
355 let cost_ce = area_c + perimeter(aabb_cd);
356 if cost_ce < best_cost {
357 best_rotation = RotateType::Ce;
358 }
360
361 match best_rotation {
362 RotateType::None => {}
363
364 RotateType::Bf => {
365 nodes[ia].child1 = i_f;
366 nodes[ic].child1 = i_b;
367
368 nodes[ib].parent = i_c;
369 nodes[if_].parent = i_a;
370
371 nodes[ic].aabb = aabb_bg;
372 nodes[ic].height = 1 + max_u16(nodes[ib].height, nodes[ig].height);
373 nodes[ia].height = 1 + max_u16(nodes[ic].height, nodes[if_].height);
374 nodes[ic].category_bits = nodes[ib].category_bits | nodes[ig].category_bits;
375 nodes[ia].category_bits = nodes[ic].category_bits | nodes[if_].category_bits;
376 nodes[ic].flags |= (nodes[ib].flags | nodes[ig].flags) & ENLARGED_NODE;
377 nodes[ia].flags |= (nodes[ic].flags | nodes[if_].flags) & ENLARGED_NODE;
378 }
379
380 RotateType::Bg => {
381 nodes[ia].child1 = i_g;
382 nodes[ic].child2 = i_b;
383
384 nodes[ib].parent = i_c;
385 nodes[ig].parent = i_a;
386
387 nodes[ic].aabb = aabb_bf;
388 nodes[ic].height = 1 + max_u16(nodes[ib].height, nodes[if_].height);
389 nodes[ia].height = 1 + max_u16(nodes[ic].height, nodes[ig].height);
390 nodes[ic].category_bits = nodes[ib].category_bits | nodes[if_].category_bits;
391 nodes[ia].category_bits = nodes[ic].category_bits | nodes[ig].category_bits;
392 nodes[ic].flags |= (nodes[ib].flags | nodes[if_].flags) & ENLARGED_NODE;
393 nodes[ia].flags |= (nodes[ic].flags | nodes[ig].flags) & ENLARGED_NODE;
394 }
395
396 RotateType::Cd => {
397 nodes[ia].child2 = i_d;
398 nodes[ib].child1 = i_c;
399
400 nodes[ic].parent = i_b;
401 nodes[id].parent = i_a;
402
403 nodes[ib].aabb = aabb_ce;
404 nodes[ib].height = 1 + max_u16(nodes[ic].height, nodes[ie].height);
405 nodes[ia].height = 1 + max_u16(nodes[ib].height, nodes[id].height);
406 nodes[ib].category_bits = nodes[ic].category_bits | nodes[ie].category_bits;
407 nodes[ia].category_bits = nodes[ib].category_bits | nodes[id].category_bits;
408 nodes[ib].flags |= (nodes[ic].flags | nodes[ie].flags) & ENLARGED_NODE;
409 nodes[ia].flags |= (nodes[ib].flags | nodes[id].flags) & ENLARGED_NODE;
410 }
411
412 RotateType::Ce => {
413 nodes[ia].child2 = i_e;
414 nodes[ib].child2 = i_c;
415
416 nodes[ic].parent = i_b;
417 nodes[ie].parent = i_a;
418
419 nodes[ib].aabb = aabb_cd;
420 nodes[ib].height = 1 + max_u16(nodes[ic].height, nodes[id].height);
421 nodes[ia].height = 1 + max_u16(nodes[ib].height, nodes[ie].height);
422 nodes[ib].category_bits = nodes[ic].category_bits | nodes[id].category_bits;
423 nodes[ia].category_bits = nodes[ib].category_bits | nodes[ie].category_bits;
424 nodes[ib].flags |= (nodes[ic].flags | nodes[id].flags) & ENLARGED_NODE;
425 nodes[ia].flags |= (nodes[ib].flags | nodes[ie].flags) & ENLARGED_NODE;
426 }
427 }
428 }
429 }
430
431 fn insert_leaf(&mut self, leaf: i32, should_rotate: bool) {
433 if self.root == NULL_INDEX {
434 self.root = leaf;
435 self.nodes[self.root as usize].parent = NULL_INDEX;
436 return;
437 }
438
439 let leaf_aabb = self.nodes[leaf as usize].aabb;
441 let sibling = find_best_sibling(self, leaf_aabb);
442
443 let old_parent = self.nodes[sibling as usize].parent;
445 let new_parent = self.allocate_node();
446
447 let nodes = &mut self.nodes;
448 let np = new_parent as usize;
449 nodes[np].parent = old_parent;
450 nodes[np].user_data = u64::MAX;
451 nodes[np].aabb = aabb_union(leaf_aabb, nodes[sibling as usize].aabb);
452 nodes[np].category_bits =
453 nodes[leaf as usize].category_bits | nodes[sibling as usize].category_bits;
454 nodes[np].height = nodes[sibling as usize].height + 1;
455 nodes[np].child1 = sibling;
456 nodes[np].child2 = leaf;
457 nodes[sibling as usize].parent = new_parent;
458 nodes[leaf as usize].parent = new_parent;
459
460 if old_parent != NULL_INDEX {
462 if nodes[old_parent as usize].child1 == sibling {
464 nodes[old_parent as usize].child1 = new_parent;
465 } else {
466 debug_assert!(nodes[old_parent as usize].child2 == sibling);
467 nodes[old_parent as usize].child2 = new_parent;
468 }
469 } else {
470 self.root = new_parent;
472 }
473
474 let mut index = self.nodes[leaf as usize].parent;
476 while index != NULL_INDEX {
477 let child1 = self.nodes[index as usize].child1;
478 let child2 = self.nodes[index as usize].child2;
479
480 debug_assert!(child1 != NULL_INDEX);
481 debug_assert!(child2 != NULL_INDEX);
482
483 let (c1, c2) = (child1 as usize, child2 as usize);
484 self.nodes[index as usize].aabb = aabb_union(self.nodes[c1].aabb, self.nodes[c2].aabb);
485 self.nodes[index as usize].category_bits =
486 self.nodes[c1].category_bits | self.nodes[c2].category_bits;
487 self.nodes[index as usize].height =
488 1 + max_u16(self.nodes[c1].height, self.nodes[c2].height);
489 self.nodes[index as usize].flags |=
490 (self.nodes[c1].flags | self.nodes[c2].flags) & ENLARGED_NODE;
491
492 if should_rotate {
493 self.rotate_nodes(index);
494 }
495
496 index = self.nodes[index as usize].parent;
497 }
498 }
499
500 pub(crate) fn remove_leaf(&mut self, leaf: i32) {
502 if leaf == self.root {
503 self.root = NULL_INDEX;
504 return;
505 }
506
507 let parent = self.nodes[leaf as usize].parent;
508 let grand_parent = self.nodes[parent as usize].parent;
509 let sibling = if self.nodes[parent as usize].child1 == leaf {
510 self.nodes[parent as usize].child2
511 } else {
512 self.nodes[parent as usize].child1
513 };
514
515 if grand_parent != NULL_INDEX {
516 if self.nodes[grand_parent as usize].child1 == parent {
518 self.nodes[grand_parent as usize].child1 = sibling;
519 } else {
520 self.nodes[grand_parent as usize].child2 = sibling;
521 }
522 self.nodes[sibling as usize].parent = grand_parent;
523 self.free_node(parent);
524
525 let mut index = grand_parent;
527 while index != NULL_INDEX {
528 let child1 = self.nodes[index as usize].child1 as usize;
529 let child2 = self.nodes[index as usize].child2 as usize;
530
531 self.nodes[index as usize].aabb =
532 aabb_union(self.nodes[child1].aabb, self.nodes[child2].aabb);
533 self.nodes[index as usize].category_bits =
534 self.nodes[child1].category_bits | self.nodes[child2].category_bits;
535 self.nodes[index as usize].height =
536 1 + max_u16(self.nodes[child1].height, self.nodes[child2].height);
537
538 index = self.nodes[index as usize].parent;
539 }
540 } else {
541 self.root = sibling;
542 self.nodes[sibling as usize].parent = NULL_INDEX;
543 self.free_node(parent);
544 }
545 }
546
547 pub fn create_proxy(&mut self, aabb: Aabb, category_bits: u64, user_data: u64) -> i32 {
550 debug_assert!(is_valid_aabb(aabb));
551
552 let proxy_id = self.allocate_node();
553 let node = &mut self.nodes[proxy_id as usize];
554
555 node.aabb = aabb;
556 node.user_data = user_data;
557 node.category_bits = category_bits;
558 node.height = 0;
559 node.flags = ALLOCATED_NODE | LEAF_NODE;
560
561 let should_rotate = true;
562 self.insert_leaf(proxy_id, should_rotate);
563
564 self.proxy_count += 1;
565
566 proxy_id
567 }
568
569 pub fn destroy_proxy(&mut self, proxy_id: i32) {
572 debug_assert!(0 <= proxy_id && proxy_id < self.node_capacity());
573 debug_assert!(self.nodes[proxy_id as usize].is_leaf());
574
575 self.remove_leaf(proxy_id);
576 self.free_node(proxy_id);
577
578 debug_assert!(self.proxy_count > 0);
579 self.proxy_count -= 1;
580 }
581
582 pub fn move_proxy(&mut self, proxy_id: i32, aabb: Aabb) {
585 debug_assert!(is_valid_aabb(aabb));
586 debug_assert!(aabb.upper_bound.x - aabb.lower_bound.x < crate::constants::huge());
587 debug_assert!(aabb.upper_bound.y - aabb.lower_bound.y < crate::constants::huge());
588 debug_assert!(0 <= proxy_id && proxy_id < self.node_capacity());
589 debug_assert!(self.nodes[proxy_id as usize].is_leaf());
590
591 self.remove_leaf(proxy_id);
592
593 self.nodes[proxy_id as usize].aabb = aabb;
594
595 let should_rotate = false;
596 self.insert_leaf(proxy_id, should_rotate);
597 }
598
599 pub fn enlarge_proxy(&mut self, proxy_id: i32, aabb: Aabb) {
602 debug_assert!(is_valid_aabb(aabb));
603 debug_assert!(aabb.upper_bound.x - aabb.lower_bound.x < crate::constants::huge());
604 debug_assert!(aabb.upper_bound.y - aabb.lower_bound.y < crate::constants::huge());
605 debug_assert!(0 <= proxy_id && proxy_id < self.node_capacity());
606 debug_assert!(self.nodes[proxy_id as usize].is_leaf());
607
608 debug_assert!(!aabb_contains(self.nodes[proxy_id as usize].aabb, aabb));
610
611 self.nodes[proxy_id as usize].aabb = aabb;
612
613 let mut parent_index = self.nodes[proxy_id as usize].parent;
614 while parent_index != NULL_INDEX {
615 let changed = enlarge_aabb(&mut self.nodes[parent_index as usize].aabb, aabb);
616 self.nodes[parent_index as usize].flags |= ENLARGED_NODE;
617 parent_index = self.nodes[parent_index as usize].parent;
618
619 if !changed {
620 break;
621 }
622 }
623
624 while parent_index != NULL_INDEX {
625 if self.nodes[parent_index as usize].flags & ENLARGED_NODE != 0 {
626 break;
629 }
630
631 self.nodes[parent_index as usize].flags |= ENLARGED_NODE;
632 parent_index = self.nodes[parent_index as usize].parent;
633 }
634 }
635
636 pub fn set_category_bits(&mut self, proxy_id: i32, category_bits: u64) {
639 let p = proxy_id as usize;
640 debug_assert!(self.nodes[p].child1 == NULL_INDEX);
641 debug_assert!(self.nodes[p].child2 == NULL_INDEX);
642 debug_assert!(self.nodes[p].flags & LEAF_NODE == LEAF_NODE);
643
644 self.nodes[p].category_bits = category_bits;
645
646 let mut node_index = self.nodes[p].parent;
648 while node_index != NULL_INDEX {
649 let child1 = self.nodes[node_index as usize].child1;
650 debug_assert!(child1 != NULL_INDEX);
651 let child2 = self.nodes[node_index as usize].child2;
652 debug_assert!(child2 != NULL_INDEX);
653 self.nodes[node_index as usize].category_bits = self.nodes[child1 as usize]
654 .category_bits
655 | self.nodes[child2 as usize].category_bits;
656
657 node_index = self.nodes[node_index as usize].parent;
658 }
659 }
660}