1use crate::intersections::IntersectsWith;
2use crate::quadtree::aabb::AABB;
3use crate::quadtree::centered_aabb::CenteredAABB;
4use crate::quadtree::error::InsertError;
5use crate::quadtree::free_list::{self, FreeList, IndexType};
6use crate::quadtree::node::Node;
7use crate::quadtree::node_data::{NodeData, NodeIndexType};
8use crate::quadtree::node_info::NodeInfo;
9use crate::quadtree::node_list::NodeList;
10use crate::quadtree::quad_rect::QuadRect;
11use crate::quadtree::quadrants::Quadrants;
12use crate::quadtree::quadtree_element::QuadTreeElementNode;
13pub use crate::quadtree::quadtree_element::{ElementIdType, QuadTreeElement};
14use smallvec::SmallVec;
15
16#[derive(Debug, Eq, PartialEq, Copy, Clone)]
19enum FindLeafHint {
20 Query,
23 Mutate,
26}
27
28pub struct QuadTree<ElementId = u32>
33where
34 ElementId: ElementIdType,
35{
36 element_ids: FreeList<ElementId>,
39 element_rects: FreeList<AABB>,
42 element_nodes: FreeList<QuadTreeElementNode>,
46 nodes: Vec<Node>,
49 root_rect: QuadRect,
51 free_node: free_list::IndexType,
56 max_num_elements: u32,
58 smallest_cell_size: u32,
60 max_depth: u8,
62}
63
64impl<ElementId> QuadTree<ElementId>
65where
66 ElementId: ElementIdType,
67{
68 pub fn default() -> Self {
69 Self::new(QuadRect::default(), 8, 16, 1)
70 }
71
72 pub fn new(
73 root_rect: QuadRect,
74 max_depth: u8,
75 max_num_elements: u32,
76 smallest_cell_size: u32,
77 ) -> Self {
78 assert!(max_num_elements > 0);
79 assert!(smallest_cell_size > 0);
80 Self {
81 element_ids: FreeList::default(),
82 element_rects: FreeList::default(),
83 element_nodes: FreeList::default(),
84 nodes: vec![Node::default()],
85 root_rect,
86 free_node: free_list::SENTINEL,
87 max_depth,
88 max_num_elements,
89 smallest_cell_size,
90 }
91 }
92
93 pub fn insert(&mut self, element: QuadTreeElement<ElementId>) -> Result<(), InsertError> {
94 let element_coords = &element.rect;
95 if !self.root_rect.contains(element_coords) {
96 return Err(InsertError::OutOfBounds);
97 }
98
99 let max_num_elements = self.max_num_elements;
100
101 let element_idx = self.element_ids.insert(element.id);
103 let element_rect_idx = self.element_rects.insert(element.rect);
104 debug_assert_eq!(element_idx, element_rect_idx);
105
106 let mut to_process: SmallVec<[NodeData; 128]> =
107 smallvec::smallvec![self.get_root_node_data()];
108
109 while !to_process.is_empty() {
110 let node_data = to_process.pop().unwrap();
111
112 let mut leaves = NodeList::default(); self.find_leaves_aabb_fn(
115 node_data,
116 element_coords,
117 FindLeafHint::Mutate,
118 |_rect, nd| {
119 leaves.push_back(nd);
120 },
121 );
122
123 while !leaves.is_empty() {
125 let leaf = leaves.pop_back();
126
127 let (element_count, first_child_or_element) = {
128 let node = &self.nodes[leaf.index as usize];
129 debug_assert!(node.is_leaf());
130 (node.element_count, node.first_child_or_element)
131 };
132
133 let can_split = leaf.can_split_further(self.smallest_cell_size, self.max_depth);
134 let node_is_full = element_count >= max_num_elements;
135
136 let must_store_element = !node_is_full || !can_split;
137 if must_store_element {
138 let element_node_idx = self.element_nodes.insert(QuadTreeElementNode {
140 element_idx,
141 next: first_child_or_element,
142 });
143 let node = &mut self.nodes[leaf.index as usize];
144 node.first_child_or_element = element_node_idx;
145 node.element_count += 1;
146 } else {
147 self.distribute_elements_to_child_nodes(&leaf);
151 to_process.push(leaf);
152 }
153 }
154 }
155
156 Ok(())
157 }
158
159 fn distribute_elements_to_child_nodes(&mut self, parent: &NodeData) {
162 let first_child_index = self.ensure_child_nodes_exist();
163
164 let node = &mut self.nodes[parent.index as usize];
165 let mut element_node_index = node.get_first_element_node_index();
166 node.make_branch(first_child_index);
167
168 let mx = parent.crect.center_x;
169 let my = parent.crect.center_y;
170
171 while element_node_index != free_list::SENTINEL {
173 let element_node = unsafe { *self.element_nodes.at(element_node_index) };
174 let element = unsafe { *self.element_rects.at(element_node.element_idx) };
175
176 self.assign_element_to_child_nodes(
177 mx,
178 my,
179 first_child_index,
180 element_node.element_idx,
181 &element,
182 );
183
184 self.element_nodes.erase(element_node_index);
187
188 element_node_index = element_node.next;
189 }
190 }
191
192 fn ensure_child_nodes_exist(&mut self) -> u32 {
195 if self.free_node != free_list::SENTINEL {
196 let node_index = self.free_node;
197 let next_free_node = self.nodes[node_index as usize].first_child_or_element;
198 self.nodes[node_index as usize] = Node::default();
199 self.free_node = next_free_node;
200 node_index
201 } else {
202 let node_index = self.nodes.len() as IndexType;
203 self.nodes.push(Node::default());
205 for _ in 0..4 {
207 self.nodes.push(Node::default());
208 }
209 node_index
210 }
211 }
212
213 fn assign_element_to_child_nodes(
222 &mut self,
223 mx: i32,
224 my: i32,
225 first_child_index: free_list::IndexType,
226 element_index: free_list::IndexType,
227 element_rect: &AABB,
228 ) {
229 let insert_left = element_rect.tl.x <= mx;
230 let insert_right = element_rect.br.x > mx;
231 let insert_top = element_rect.tl.y <= my;
232 let insert_bottom = element_rect.br.y > my;
233
234 let covers_many = (insert_top & insert_bottom) | (insert_left & insert_right);
236 if covers_many {
237 self.insert_element_in_child_node(first_child_index + 0, element_index);
238 return;
239 }
240
241 debug_assert!(
243 (insert_top & insert_left)
244 || (insert_top & insert_right)
245 || (insert_bottom & insert_left)
246 || (insert_bottom && insert_right)
247 );
248 if insert_top & insert_left {
249 self.insert_element_in_child_node(first_child_index + 1, element_index);
250 } else if insert_top & insert_right {
251 self.insert_element_in_child_node(first_child_index + 2, element_index);
252 } else if insert_bottom & insert_left {
253 self.insert_element_in_child_node(first_child_index + 3, element_index);
254 } else if insert_bottom & insert_right {
255 self.insert_element_in_child_node(first_child_index + 4, element_index);
256 }
257 }
258
259 fn insert_element_in_child_node(&mut self, child_index: u32, element: free_list::IndexType) {
260 let node = &mut self.nodes[child_index as usize];
261 let element_node_index = self.element_nodes.insert(QuadTreeElementNode {
262 element_idx: element,
263 next: node.first_child_or_element,
264 });
265 node.first_child_or_element = element_node_index;
266 node.element_count += 1;
267 }
268
269 pub fn remove(&mut self, element: &QuadTreeElement<ElementId>) -> bool {
279 let element_coords = &element.rect;
281 let root = self.get_root_node_data();
282
283 let mut found_element_idx = free_list::SENTINEL;
285
286 let mut leaves = NodeList::default(); self.find_leaves_aabb_fn(root, element_coords, FindLeafHint::Mutate, |_rect, nd| {
288 leaves.push_back(nd);
289 });
290
291 while !leaves.is_empty() {
293 let leaf = leaves.pop_back();
294 let leaf_node_data = self.nodes[leaf.index as usize];
295
296 if leaf_node_data.element_count == 0 {
298 continue;
299 }
300
301 let mut element_found = false;
303
304 let mut element_node_idx = leaf_node_data.first_child_or_element;
306 let mut prev_element_node_idx = element_node_idx;
307 let mut new_first_child_or_element = element_node_idx;
308
309 while element_node_idx != free_list::SENTINEL {
310 let elem_node = *unsafe { self.element_nodes.at(element_node_idx) };
311 let elem_id = unsafe { self.element_ids.at(elem_node.element_idx) };
312
313 if *elem_id == element.id {
314 debug_assert!(!element_found);
315 element_found = true;
316
317 if leaf_node_data.first_child_or_element == element_node_idx {
320 new_first_child_or_element = elem_node.next;
321 }
322
323 if element_node_idx != prev_element_node_idx {
325 unsafe { self.element_nodes.at_mut(prev_element_node_idx) }.next =
326 elem_node.next;
327 }
328
329 self.element_nodes.erase(element_node_idx);
332 debug_assert!(
333 found_element_idx == free_list::SENTINEL
334 || found_element_idx == elem_node.element_idx
335 );
336 found_element_idx = elem_node.element_idx;
337 }
338
339 prev_element_node_idx = element_node_idx;
340 element_node_idx = elem_node.next;
341
342 #[cfg(not(debug_assertions))]
349 if element_found {
350 break;
351 }
352 }
353
354 let node = &mut self.nodes[leaf.index as usize];
356 node.first_child_or_element = new_first_child_or_element;
357
358 if element_found {
360 debug_assert!(node.element_count > 0);
361 node.element_count -= 1;
362 }
363 }
364
365 if found_element_idx != free_list::SENTINEL {
366 self.element_ids.erase(found_element_idx);
367 self.element_rects.erase(found_element_idx);
368 true
369 } else {
370 false
371 }
372 }
373
374 fn find_leaves_aabb_fn<F>(
376 &self,
377 root: NodeData,
378 rect: &AABB,
379 hint: FindLeafHint,
380 mut callback: F,
381 ) where
382 F: FnMut(&AABB, NodeData),
383 {
384 let mut to_process = NodeList::default();
385 to_process.push_back(root);
386
387 while to_process.len() > 0 {
388 let nd = to_process.pop_back();
389
390 if self.nodes[nd.index as usize].is_leaf() {
392 callback(rect, nd);
393 continue;
394 }
395
396 let fc = self.nodes[nd.index as usize].get_first_child_node_index();
397
398 let quadrants = nd.crect.explore_quadrants_aabb(rect);
400 Self::collect_relevant_quadrants(&mut to_process, &nd, fc, quadrants, hint)
401 }
402 }
403
404 fn find_leaves_generic_fn<T, F>(&self, root: NodeData, element: &T, mut callback: F)
406 where
407 T: IntersectsWith<AABB>,
408 F: FnMut(NodeData),
409 {
410 let mut to_process = NodeList::default();
411 to_process.push_back(root);
412
413 while to_process.len() > 0 {
414 let nd = to_process.pop_back();
415
416 if self.nodes[nd.index as usize].is_leaf() {
418 callback(nd);
419 continue;
420 }
421
422 let fc = self.nodes[nd.index as usize].get_first_child_node_index();
423
424 let quadrants = nd.crect.explore_quadrants_generic(element);
426 Self::collect_relevant_quadrants(
427 &mut to_process,
428 &nd,
429 fc,
430 quadrants,
431 FindLeafHint::Query,
432 )
433 }
434 }
435
436 pub fn visit_leaves<F>(&self, mut visit: F)
438 where
439 F: FnMut(NodeInfo),
440 {
441 let mut to_process = NodeList::default();
442 to_process.push_back(self.get_root_node_data());
443
444 while to_process.len() > 0 {
445 let nd = to_process.pop_back();
446
447 let is_this_node = nd.index > 0 && ((nd.index - 1) % 5) == 0;
452 if is_this_node {
453 debug_assert!(self.nodes[nd.index as usize].is_leaf());
454 continue;
455 }
456
457 let node = &self.nodes[nd.index as usize];
458 if node.is_leaf() {
459 visit(NodeInfo::from(nd, node.element_count));
460 continue;
461 }
462
463 let fc = self.nodes[nd.index as usize].get_first_child_node_index();
464 Self::collect_relevant_quadrants(
465 &mut to_process,
466 &nd,
467 fc,
468 Quadrants::all(),
469 FindLeafHint::Query,
470 )
471 }
472 }
473
474 #[inline]
476 fn collect_relevant_quadrants(
477 to_process: &mut NodeList,
478 nd: &NodeData,
479 first_child_id: u32,
480 quadrants: Quadrants,
481 hint: FindLeafHint,
482 ) {
483 let split_quadrants = nd.crect.split_quadrants();
486
487 match hint {
488 FindLeafHint::Query => Self::collect_relevant_quadrants_for_query(
489 to_process,
490 nd.depth,
491 first_child_id,
492 quadrants,
493 &split_quadrants,
494 ),
495 FindLeafHint::Mutate => Self::collect_relevant_quadrants_for_mutation(
496 to_process,
497 nd.depth,
498 first_child_id,
499 quadrants,
500 &split_quadrants,
501 ),
502 }
503 }
504
505 fn collect_relevant_quadrants_for_mutation(
507 to_process: &mut NodeList,
508 depth: u8,
509 first_child_id: u32,
510 quadrants: Quadrants,
511 split_quadrants: &[CenteredAABB; 5],
512 ) {
513 let offset = quadrants.mutation_index();
514 debug_assert!(offset <= 4);
515
516 let can_split = offset > 0;
518
519 let child_depth = depth + (1 - quadrants.this() as u8);
521
522 to_process.push_back(NodeData::new(
523 split_quadrants[offset as usize],
524 first_child_id + offset,
525 child_depth,
526 can_split,
527 ));
528 }
529
530 fn collect_relevant_quadrants_for_query(
532 to_process: &mut NodeList,
533 depth: u8,
534 first_child_id: u32,
535 quadrants: Quadrants,
536 split_quadrants: &[CenteredAABB; 5],
537 ) {
538 let child_depth = depth + 1;
539
540 for offset in (1..=4).rev() {
541 if quadrants.at(offset) {
542 to_process.push_back(NodeData::new(
543 split_quadrants[offset as usize],
544 first_child_id + offset as u32,
545 child_depth,
546 true,
547 ));
548 }
549 }
550
551 to_process.push_back(NodeData::new(
553 split_quadrants[0],
554 first_child_id + 0,
555 depth,
557 false,
558 ));
559 }
560
561 pub fn cleanup(&mut self) -> bool {
567 if self.nodes[0].is_leaf() {
569 return false;
570 }
571
572 let mut tree_compacted = false;
573
574 let mut to_process: SmallVec<[NodeIndexType; 128]> = smallvec::smallvec![0];
577
578 while !to_process.is_empty() {
579 let node_index = to_process.pop().unwrap();
580 let first_child_index = self.nodes[node_index as usize].get_first_child_node_index();
581
582 let mut num_empty_leaves = 0usize;
584 for j in 0..5 {
585 let child_index = first_child_index + j;
586 let child = &self.nodes[child_index as usize];
587
588 if child.is_empty() {
594 num_empty_leaves += 1;
595 } else if child.is_branch() {
596 to_process.push(child_index);
597 }
598 }
599
600 if num_empty_leaves == 5 {
603 self.nodes[first_child_index as usize].first_child_or_element = self.free_node;
607 self.free_node = first_child_index;
608
609 self.nodes[node_index as usize].make_empty_leaf();
611
612 tree_compacted = true;
613 }
614 }
615
616 tree_compacted
617 }
618
619 #[allow(dead_code)]
623 pub(crate) fn count_element_references(&self) -> usize {
624 let mut to_process: SmallVec<[usize; 128]> = smallvec::smallvec![0];
625 let mut count = 0usize;
626 while !to_process.is_empty() {
627 let index = to_process.pop().unwrap();
628 let node = &self.nodes[index];
629 if node.is_branch() {
630 for j in 0..5 {
631 to_process.push((node.first_child_or_element + j) as usize);
632 }
633 } else {
634 count += node.element_count as usize;
635 }
636 }
637
638 debug_assert!(count >= self.element_ids.debug_len());
639 debug_assert!(count >= self.element_rects.debug_len());
640 count
641 }
642
643 #[inline]
644 fn get_root_node_data(&self) -> NodeData {
645 NodeData::new_from_root(&self.root_rect, true)
646 }
647
648 #[inline]
654 pub fn intersect_aabb(&self, rect: &AABB) -> Vec<ElementId> {
655 let root = self.get_root_node_data();
656 let mut node_set = Vec::with_capacity(128);
657
658 self.find_leaves_aabb_fn(root, rect, FindLeafHint::Query, |rect, nd| {
659 self.intersect_from_leaf(rect, nd, &mut |id| {
660 node_set.push(id);
661 });
662 });
663
664 node_set
665 }
666
667 #[inline]
675 pub fn intersect_aabb_fn<F>(&self, rect: &AABB, mut candidate_fn: F)
676 where
677 F: FnMut(ElementId),
678 {
679 let root = self.get_root_node_data();
680 self.find_leaves_aabb_fn(root, rect, FindLeafHint::Query, move |rect, nd| {
681 self.intersect_from_leaf(rect, nd, &mut |id| {
682 candidate_fn(id);
683 });
684 });
685 }
686
687 #[inline]
693 pub fn intersect_generic<T>(&self, element: &T) -> Vec<ElementId>
694 where
695 T: IntersectsWith<AABB>,
696 {
697 let root = self.get_root_node_data();
698 let mut node_set = Vec::with_capacity(128);
699
700 self.find_leaves_generic_fn(root, element, |nd| {
701 self.intersect_from_leaf(element, nd, &mut |id| {
702 node_set.push(id);
703 });
704 });
705
706 node_set
708 }
709
710 #[inline]
718 pub fn intersect_generic_fn<T, F>(&self, element: &T, mut candidate_fn: F)
719 where
720 T: IntersectsWith<AABB>,
721 F: FnMut(ElementId),
722 {
723 let root = self.get_root_node_data();
724 self.find_leaves_generic_fn(root, element, move |nd| {
725 self.intersect_from_leaf(element, nd, &mut |id| {
726 candidate_fn(id);
727 });
728 });
729 }
730
731 #[inline]
732 fn intersect_from_leaf<T, F>(&self, element: &T, leaf_data: NodeData, mut candidate_fn: F)
733 where
734 T: IntersectsWith<AABB>,
735 F: FnMut(ElementId),
736 {
737 let leaf = self.nodes[leaf_data.index as usize];
738 debug_assert!(leaf.is_leaf());
739
740 let mut elem_node_idx = leaf.first_child_or_element;
741 while elem_node_idx != free_list::SENTINEL {
742 let elem_node = unsafe { self.element_nodes.at(elem_node_idx) };
743 let elem_rect = unsafe { self.element_rects.at(elem_node.element_idx) };
744
745 if element.intersects_with(&elem_rect) {
748 let elem_id = *unsafe { self.element_ids.at(elem_node.element_idx) };
749 candidate_fn(elem_id);
750 }
751
752 elem_node_idx = elem_node.next;
753 }
754 }
755
756 #[allow(dead_code)]
758 pub(crate) fn collect_ids(&self) -> Vec<ElementId> {
759 let aabb: AABB = self.root_rect.into();
760 self.intersect_aabb(&aabb)
761 }
762}
763
764#[cfg(test)]
765pub(crate) fn build_test_tree() -> QuadTree {
766 let quad_rect = QuadRect::new(-20, -20, 40, 40);
767 let mut tree = QuadTree::new(quad_rect, 1, 1, 1);
768 tree.insert(QuadTreeElement::new(1000, AABB::new(-15, -15, -5, -5)))
770 .expect("insert should work");
771 tree.insert(QuadTreeElement::new(1001, AABB::new(-20, -20, -18, -18)))
772 .expect("insert should work");
773 tree.insert(QuadTreeElement::new(2000, AABB::new(5, -15, 15, -5)))
775 .expect("insert should work");
776 tree.insert(QuadTreeElement::new(3000, AABB::new(-15, 5, -5, 15)))
778 .expect("insert should work");
779 tree.insert(QuadTreeElement::new(4000, AABB::new(5, 5, 15, 15)))
781 .expect("insert should work");
782 tree.insert(QuadTreeElement::new(5000, AABB::new(-5, -5, 5, 5)))
784 .expect("insert should work");
785
786 assert_eq!(tree.count_element_references(), 6);
791
792 let inserted_ids = tree.collect_ids();
794 assert_eq!(inserted_ids.len(), 6);
795 assert!(inserted_ids.contains(&1000));
796 assert!(inserted_ids.contains(&1001));
797 assert!(inserted_ids.contains(&2000));
798 assert!(inserted_ids.contains(&3000));
799 assert!(inserted_ids.contains(&4000));
800 assert!(inserted_ids.contains(&5000));
801
802 tree
803}
804
805#[cfg(test)]
806mod test {
807 use super::*;
808
809 #[test]
810 fn cleanup_works() {
811 let quad_rect = QuadRect::new(-20, -20, 40, 40);
812 let mut tree = QuadTree::new(quad_rect, 1, 1, 1);
813 tree.insert(QuadTreeElement::new(1000, AABB::new(-15, -15, -5, -5)))
815 .expect("insert should work");
816 tree.insert(QuadTreeElement::new(1001, AABB::new(-20, -20, -18, -18)))
817 .expect("insert should work");
818 tree.insert(QuadTreeElement::new(2000, AABB::new(5, -15, 15, -5)))
820 .expect("insert should work");
821 tree.insert(QuadTreeElement::new(3000, AABB::new(-15, 5, -5, 15)))
823 .expect("insert should work");
824 tree.insert(QuadTreeElement::new(4000, AABB::new(5, 5, 15, 15)))
826 .expect("insert should work");
827
828 assert_eq!(tree.collect_ids().len(), 5);
830
831 tree.insert(QuadTreeElement::new(5000, AABB::new(-5, -5, 5, 5)))
833 .expect("insert should work");
834
835 assert_eq!(tree.collect_ids().len(), 6);
837 assert_eq!(tree.count_element_references(), 6);
838
839 assert!(tree.remove(&QuadTreeElement::new(1000, AABB::new(-15, -15, -5, -5))));
841 assert!(tree.remove(&QuadTreeElement::new(1001, AABB::new(-20, -20, -18, -18))));
842 assert!(tree.remove(&QuadTreeElement::new(2000, AABB::new(5, -15, 15, -5))));
843 assert!(tree.remove(&QuadTreeElement::new(3000, AABB::new(-15, 5, -5, 15))));
844 assert!(tree.remove(&QuadTreeElement::new(4000, AABB::new(5, 5, 15, 15))));
845 assert!(tree.remove(&QuadTreeElement::new(5000, AABB::new(-5, -5, 5, 5))));
846 assert_eq!(tree.collect_ids().len(), 0);
847 assert_eq!(tree.count_element_references(), 0);
848
849 assert!(tree.nodes[0].is_branch());
852 assert_eq!(tree.nodes[0].first_child_or_element, 1);
853
854 assert!(tree.cleanup());
856
857 assert!(tree.nodes[0].is_leaf());
861 assert_eq!(tree.nodes[0].element_count, 0);
862 }
863}