collision/dbvt/mod.rs
1//! A [dynamic bounding volume tree implementation](struct.DynamicBoundingVolumeTree.html),
2//! index based (not pointer based).
3//!
4//! The following invariants are true:
5//!
6//! * A branch node must have exactly two children.
7//! * Only leaf nodes contain user data.
8//!
9//! Internal nodes may have incorrect bounding volumes and height after insertion, removal and
10//! updates to values in the tree. These will be fixed during refitting, which is done by calling
11//! [`do_refit`](struct.DynamicBoundingVolumeTree.html#method.do_refit).
12//!
13//! The main heuristic used for insertion and tree rotation, is surface area of the bounding volume.
14//!
15//! Updating of values in the tree, can either be performed by using the
16//! [`values`](struct.DynamicBoundingVolumeTree.html#method.values) function to get a mutable
17//! iterator over the values in the tree, or by using
18//! [`update_node`](struct.DynamicBoundingVolumeTree.html#method.update_node).
19//! It is recommended to use the latter when possible. If the former is used,
20//! [`reindex_values`](struct.DynamicBoundingVolumeTree.html#method.reindex_values)
21//! must be called if the order of the values is changed in any way.
22//!
23//! The trait [`TreeValue`](trait.TreeValue.html) needs to be implemented for a type to be usable
24//! in the tree.
25//!
26//! # Examples
27//!
28//! ```
29//! # extern crate cgmath;
30//! # extern crate collision;
31//!
32//! use cgmath::{Point2, Vector2, InnerSpace};
33//! use collision::{Aabb, Aabb2, Ray2};
34//!
35//! use collision::dbvt::{DynamicBoundingVolumeTree, TreeValue, ContinuousVisitor};
36//!
37//! #[derive(Debug, Clone)]
38//! struct Value {
39//! pub id: u32,
40//! pub aabb: Aabb2<f32>,
41//! fat_aabb: Aabb2<f32>,
42//! }
43//!
44//! impl Value {
45//! pub fn new(id: u32, aabb: Aabb2<f32>) -> Self {
46//! Self {
47//! id,
48//! fat_aabb : aabb.add_margin(Vector2::new(3., 3.)),
49//! aabb,
50//! }
51//! }
52//! }
53//!
54//! impl TreeValue for Value {
55//! type Bound = Aabb2<f32>;
56//!
57//! fn bound(&self) -> &Aabb2<f32> {
58//! &self.aabb
59//! }
60//!
61//! fn get_bound_with_margin(&self) -> Aabb2<f32> {
62//! self.fat_aabb.clone()
63//! }
64//! }
65//!
66//! fn aabb2(minx: f32, miny: f32, maxx: f32, maxy: f32) -> Aabb2<f32> {
67//! Aabb2::new(Point2::new(minx, miny), Point2::new(maxx, maxy))
68//! }
69//!
70//! fn main() {
71//! let mut tree = DynamicBoundingVolumeTree::<Value>::new();
72//! tree.insert(Value::new(10, aabb2(5., 5., 10., 10.)));
73//! tree.insert(Value::new(11, aabb2(21., 14., 23., 16.)));
74//! tree.do_refit();
75//!
76//! let ray = Ray2::new(Point2::new(0., 0.), Vector2::new(-1., -1.).normalize());
77//! let mut visitor = ContinuousVisitor::<Ray2<f32>, Value>::new(&ray);
78//! assert_eq!(0, tree.query(&mut visitor).len());
79//!
80//! let ray = Ray2::new(Point2::new(6., 0.), Vector2::new(0., 1.).normalize());
81//! let mut visitor = ContinuousVisitor::<Ray2<f32>, Value>::new(&ray);
82//! let results = tree.query(&mut visitor);
83//! assert_eq!(1, results.len());
84//! assert_eq!(10, results[0].0.id);
85//! assert_eq!(Point2::new(6., 5.), results[0].1);
86//! }
87//! ```
88//!
89
90pub use self::util::*;
91pub use self::visitor::*;
92pub use self::wrapped::TreeValueWrapped;
93
94use std::cmp::max;
95use std::fmt;
96
97use cgmath::num_traits::NumCast;
98use rand;
99use rand::Rng;
100
101use crate::prelude::*;
102
103mod wrapped;
104mod visitor;
105mod util;
106
107const SURFACE_AREA_IMPROVEMENT_FOR_ROTATION: f32 = 0.3;
108const PERFORM_ROTATION_PERCENTAGE: u32 = 10;
109
110/// Trait that needs to be implemented for any value that is to be used in the
111/// [`DynamicBoundingVolumeTree`](struct.DynamicBoundingVolumeTree.html).
112///
113pub trait TreeValue: Clone {
114 /// Bounding volume type
115 type Bound;
116
117 /// Return the bounding volume of the value
118 fn bound(&self) -> &Self::Bound;
119
120 /// Return a fattened bounding volume. For shapes that do not move, this can be the same as the
121 /// base bounding volume. It is recommended for moving shapes to have a larger fat bound, so
122 /// tree rotations don't have to be performed every frame.
123 fn get_bound_with_margin(&self) -> Self::Bound;
124}
125
126/// Make it possible to run broad phase algorithms directly on the value storage in DBVT
127impl<T> HasBound for (usize, T)
128where
129 T: TreeValue,
130 T::Bound: Bound,
131{
132 type Bound = T::Bound;
133
134 fn bound(&self) -> &Self::Bound {
135 self.1.bound()
136 }
137}
138
139/// Visitor trait used for [querying](struct.DynamicBoundingVolumeTree.html#method.query) the tree.
140pub trait Visitor {
141 /// Bounding volume accepted by the visitor
142 type Bound;
143
144 /// Result returned by the acceptance test
145 type Result;
146
147 /// Acceptance test function
148 fn accept(&mut self, bound: &Self::Bound, is_leaf: bool) -> Option<Self::Result>;
149}
150
151/// A dynamic bounding volume tree, index based (not pointer based).
152///
153/// The following invariants are true:
154///
155/// * A branch node must have exactly two children.
156/// * Only leaf nodes contain user data.
157///
158/// Internal nodes may have incorrect bounding volumes and height after insertion, removal and
159/// updates to values in the tree. These will be fixed during refitting, which is done by calling
160/// [`do_refit`](struct.DynamicBoundingVolumeTree.html#method.do_refit). This function should
161/// ideally not be called more than once per frame.
162///
163/// The main heuristic used for insertion and tree rotation, is surface area of the bounding volume.
164///
165/// Updating of values in the tree, can either be performed by using the
166/// [`values`](struct.DynamicBoundingVolumeTree.html#method.values) function to get a mutable
167/// iterator over the values in the tree, or by using
168/// [`update_node`](struct.DynamicBoundingVolumeTree.html#method.update_node).
169/// It is recommended to use the latter when possible. If the former is used,
170/// [`reindex_values`](struct.DynamicBoundingVolumeTree.html#method.reindex_values)
171/// must be called if the order of the values is changed in any way.
172///
173/// # Type parameters:
174///
175/// - `T`: A type that implements [`TreeValue`](trait.TreeValue.html), and is usable in the tree.
176/// Needs to be able to store the node index of itself, and handle its own bound and
177/// fattened bound.
178///
179/// # Examples
180///
181/// ```
182/// # extern crate cgmath;
183/// # extern crate collision;
184///
185/// use cgmath::{Point2, Vector2, InnerSpace};
186/// use collision::{Aabb, Aabb2, Ray2};
187/// use collision::dbvt::{DynamicBoundingVolumeTree, TreeValue, ContinuousVisitor};
188///
189/// #[derive(Debug, Clone)]
190/// struct Value {
191/// pub id: u32,
192/// pub aabb: Aabb2<f32>,
193/// fat_aabb: Aabb2<f32>,
194/// }
195///
196/// impl Value {
197/// pub fn new(id: u32, aabb: Aabb2<f32>) -> Self {
198/// Self {
199/// id,
200/// fat_aabb : aabb.add_margin(Vector2::new(3., 3.)),
201/// aabb,
202/// }
203/// }
204/// }
205///
206/// impl TreeValue for Value {
207/// type Bound = Aabb2<f32>;
208///
209/// fn bound(&self) -> &Aabb2<f32> {
210/// &self.aabb
211/// }
212///
213/// fn get_bound_with_margin(&self) -> Aabb2<f32> {
214/// self.fat_aabb.clone()
215/// }
216/// }
217///
218/// fn aabb2(minx: f32, miny: f32, maxx: f32, maxy: f32) -> Aabb2<f32> {
219/// Aabb2::new(Point2::new(minx, miny), Point2::new(maxx, maxy))
220/// }
221///
222/// fn main() {
223/// let mut tree = DynamicBoundingVolumeTree::<Value>::new();
224/// tree.insert(Value::new(10, aabb2(5., 5., 10., 10.)));
225/// tree.insert(Value::new(11, aabb2(21., 14., 23., 16.)));
226/// tree.do_refit();
227///
228/// let ray = Ray2::new(Point2::new(0., 0.), Vector2::new(-1., -1.).normalize());
229/// let mut visitor = ContinuousVisitor::<Ray2<f32>, Value>::new(&ray);
230/// assert_eq!(0, tree.query(&mut visitor).len());
231///
232/// let ray = Ray2::new(Point2::new(6., 0.), Vector2::new(0., 1.).normalize());
233/// let mut visitor = ContinuousVisitor::<Ray2<f32>, Value>::new(&ray);
234/// let results = tree.query(&mut visitor);
235/// assert_eq!(1, results.len());
236/// assert_eq!(10, results[0].0.id);
237/// assert_eq!(Point2::new(6., 5.), results[0].1);
238/// }
239/// ```
240///
241pub struct DynamicBoundingVolumeTree<T>
242where
243 T: TreeValue,
244{
245 nodes: Vec<Node<T::Bound>>,
246 values: Vec<(usize, T)>,
247 free_list: Vec<usize>,
248 updated_list: Vec<usize>,
249 root_index: usize,
250 refit_nodes: Vec<(u32, usize)>,
251}
252
253impl<T> Default for DynamicBoundingVolumeTree<T>
254where
255 T: TreeValue,
256{
257 fn default() -> Self {
258 DynamicBoundingVolumeTree {
259 // we add Nil to first position so only the root node can have parent = 0
260 nodes: vec![Node::Nil],
261 values: Vec::default(),
262 free_list: Vec::default(),
263 updated_list: Vec::default(),
264 root_index: 0,
265 refit_nodes: Vec::default(),
266 }
267 }
268}
269
270impl<T> fmt::Debug for DynamicBoundingVolumeTree<T>
271where
272 T: TreeValue,
273 T::Bound: fmt::Debug,
274{
275 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
276 write!(f, "graph tree {{")?;
277 for n_index in 1..self.nodes.len() {
278 match self.nodes[n_index] {
279 Node::Branch(ref b) => {
280 write!(f, " n_{} [label=\"{:?}\"];", n_index, b.bound)?;
281 write!(f, " n_{} -- n_{};", n_index, b.left)?;
282 write!(f, " n_{} -- n_{};", n_index, b.right)?;
283 }
284
285 Node::Leaf(ref l) => {
286 write!(f, " n_{} [label=\"{:?}\"];", n_index, l.bound)?;
287 }
288
289 Node::Nil => (),
290 }
291 }
292 write!(f, "}}")
293 }
294}
295
296/// Branch node
297#[derive(Debug)]
298struct Branch<B> {
299 parent: usize,
300 left: usize,
301 right: usize,
302 height: u32,
303 bound: B,
304}
305
306/// Leaf node
307#[derive(Debug)]
308struct Leaf<B> {
309 parent: usize,
310 value: usize,
311 bound: B,
312}
313
314/// Nodes
315#[derive(Debug)]
316enum Node<B> {
317 Branch(Branch<B>),
318 Leaf(Leaf<B>),
319 Nil,
320}
321
322impl<T> DynamicBoundingVolumeTree<T>
323where
324 T: TreeValue,
325 T::Bound: Clone + Contains<T::Bound> + Union<T::Bound, Output = T::Bound> + SurfaceArea,
326{
327 /// Create a new tree.
328 ///
329 /// ### Type parameters:
330 ///
331 /// - `T`: A type that implements [`TreeValue`](trait.TreeValue.html), and is usable in the
332 /// tree. Needs to be able to store the node index of itself, and handle its own bound
333 /// and fattened bound.
334 /// - `T::Bound`: Bounding volume type that implements the following collision-rs traits:
335 /// [`Contains`][1] on itself, [`Union`][2] on itself, and [`SurfaceArea`][3].
336 ///
337 /// [1]: ../trait.Contains.html
338 /// [2]: ../trait.Union.html
339 /// [3]: ../trait.SurfaceArea.html
340 ///
341 pub fn new() -> Self {
342 Default::default()
343 }
344
345 /// Return the number of nodes in the tree.
346 ///
347 pub fn size(&self) -> usize {
348 // -1 because the first slot in the nodes vec is never used
349 self.nodes.len() - self.free_list.len() - 1
350 }
351
352 /// Return the height of the root node. Leafs are considered to have height 1.
353 ///
354 pub fn height(&self) -> u32 {
355 if self.values.is_empty() {
356 0
357 } else {
358 match self.nodes[self.root_index] {
359 Node::Branch(ref b) => b.height,
360 Node::Leaf(_) => 1,
361 Node::Nil => 0,
362 }
363 }
364 }
365
366 /// Get an immutable list of all values in the tree.
367 ///
368 /// ### Returns
369 ///
370 /// A immutable reference to the [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html)
371 /// of values in the tree.
372 ///
373 pub fn values(&self) -> &Vec<(usize, T)> {
374 &self.values
375 }
376
377 /// Get a mutable list of all values in the tree.
378 ///
379 /// Do not insert or remove values directly in this list, instead use
380 /// [`insert`](struct.DynamicBoundingVolumeTree.html#method.insert) and
381 /// [`remove`](struct.DynamicBoundingVolumeTree.html#method.remove)
382 /// on the tree. It is allowed to change the order of the values, but when doing so it is
383 /// required to use
384 /// [`reindex_values`](struct.DynamicBoundingVolumeTree.html#method.reindex_values)
385 /// after changing the order, and before any other operation
386 /// is performed on the tree. Otherwise the internal consistency of the tree will be broken.
387 ///
388 /// Do not change the first value in the tuple, this is the node index of the value, and without
389 /// that the tree will not function.
390 ///
391 /// ### Returns
392 ///
393 /// A mutable reference to the [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html)
394 /// of values in the tree.
395 ///
396 pub fn values_mut(&mut self) -> &mut Vec<(usize, T)> {
397 &mut self.values
398 }
399
400 /// Reindex the values list, making sure that nodes in the tree point to the correct entry in
401 /// the values list.
402 ///
403 /// Complexity is O(n).
404 ///
405 pub fn reindex_values(&mut self) {
406 for i in 0..self.values.len() {
407 if let Node::Leaf(ref mut leaf) = self.nodes[self.values[i].0] {
408 leaf.value = i;
409 }
410 }
411 }
412
413 /// Clear the tree.
414 ///
415 /// Will remove all nodes and their values.
416 ///
417 pub fn clear(&mut self) {
418 self.root_index = 0;
419 self.nodes = vec![Node::Nil];
420 self.free_list.clear();
421 self.refit_nodes.clear();
422 self.values.clear();
423 }
424
425 /// Return the value index for the given node index.
426 pub fn value_index(&self, node_index: usize) -> Option<usize> {
427 match self.nodes[node_index] {
428 Node::Leaf(ref leaf) => Some(leaf.value),
429 _ => None,
430 }
431 }
432
433 /// Query the tree for all leafs that the given visitor accepts.
434 ///
435 /// Will do a depth first search of the tree and pass all bounding volumes on the way to the
436 /// visitor.
437 ///
438 /// This function have approximate complexity O(log^2 n).
439 ///
440 /// ### Parameters:
441 ///
442 /// - `visitor`: The visitor to check for bounding volume tests.
443 ///
444 /// ### Type parameters:
445 ///
446 /// - `V`: Type that implements of [`Visitor`](trait.Visitor.html)
447 ///
448 /// ### Returns
449 ///
450 /// Will return a list of tuples of values accepted and the result returned by the visitor for
451 /// the acceptance test.
452 ///
453 pub fn query<V>(&self, visitor: &mut V) -> Vec<(&T, V::Result)>
454 where
455 V: Visitor<Bound = T::Bound>,
456 {
457 self.query_for_indices(visitor)
458 .into_iter()
459 .map(|(value_index, result)| (&self.values[value_index].1, result))
460 .collect()
461 }
462
463 /// Query the tree for all leafs that the given visitor accepts.
464 ///
465 /// Will do a depth first search of the tree and pass all bounding volumes on the way to the
466 /// visitor.
467 ///
468 /// This function have approximate complexity O(log^2 n).
469 ///
470 /// ### Parameters:
471 ///
472 /// - `visitor`: The visitor to check for bounding volume tests.
473 ///
474 /// ### Type parameters:
475 ///
476 /// - `V`: Type that implements of [`Visitor`](trait.Visitor.html)
477 ///
478 /// ### Returns
479 ///
480 /// Will return a list of tuples of value indices accepted and the result returned by the
481 /// visitor for the acceptance test.
482 ///
483 pub fn query_for_indices<V>(&self, visitor: &mut V) -> Vec<(usize, V::Result)>
484 where
485 V: Visitor<Bound = T::Bound>,
486 {
487 let mut stack = [0; 256];
488 stack[0] = self.root_index;
489 let mut stack_pointer = 1;
490 let mut values = Vec::default();
491 while stack_pointer > 0 {
492 // depth search, use last added as next test subject
493 stack_pointer -= 1;
494 let node_index = stack[stack_pointer];
495 let node = &self.nodes[node_index];
496
497 match *node {
498 Node::Leaf(ref leaf) => {
499 // if we encounter a leaf, do a real bound intersection test, and add to return
500 // values if there's an intersection
501 if let Some(result) = visitor.accept(self.values[leaf.value].1.bound(), true) {
502 values.push((leaf.value, result));
503 }
504 }
505
506 // if we encounter a branch, do intersection test, and push the children if the
507 // branch intersected
508 Node::Branch(ref branch) => if visitor.accept(&branch.bound, false).is_some() {
509 stack[stack_pointer] = branch.left;
510 stack[stack_pointer + 1] = branch.right;
511 stack_pointer += 2;
512 },
513 Node::Nil => (),
514 }
515 }
516 values
517 }
518
519 /// Update a node in the tree with a new value.
520 ///
521 /// The node will be fed its node_index after updating in the tree, so there is no need to
522 /// add that manually in the value.
523 ///
524 /// Will cause the node to be updated and be flagged as updated, which will cause
525 /// [`update`](struct.DynamicBoundingVolumeTree.html#method.update) to process the node the next
526 /// time it is called.
527 ///
528 /// ### Parameters
529 ///
530 /// - `node_index`: index of the node to update
531 /// - `new_value`: the new value to write in that node
532 ///
533 pub fn update_node(&mut self, node_index: usize, new_value: T) {
534 if let Node::Leaf(ref mut leaf) = self.nodes[node_index] {
535 self.values[leaf.value].1 = new_value;
536 }
537 self.flag_updated(node_index);
538 }
539
540 /// Flag a node as having been updated (moved/rotated).
541 ///
542 /// Will cause [`update`](struct.DynamicBoundingVolumeTree.html#method.update) to process the
543 /// node the next time it is called.
544 ///
545 /// ### Parameters
546 ///
547 /// - `node_index`: the node index of the updated node
548 ///
549 pub fn flag_updated(&mut self, node_index: usize) {
550 self.updated_list.push(node_index);
551 }
552
553 /// Go through the updated list and check the fat bounds in the tree.
554 ///
555 /// After updating values in the values list, it is possible that some of the leafs values have
556 /// outgrown their fat bounds. If so, they may need to be moved in the tree. This is done during
557 /// refitting.
558 ///
559 /// Note that no parents have their bounds/height updated directly by this function, instead
560 /// [`do_refit`](struct.DynamicBoundingVolumeTree.html#method.do_refit) should be called after
561 /// all insert/remove/updates have been performed this frame.
562 ///
563 pub fn update(&mut self) {
564 let nodes = self.updated_list
565 .iter()
566 .filter_map(|&index| {
567 if let Node::Leaf(ref l) = self.nodes[index] {
568 if !l.bound.contains(self.values[l.value].1.bound()) {
569 Some((
570 index,
571 l.parent,
572 self.values[l.value].1.get_bound_with_margin(),
573 ))
574 } else {
575 None
576 }
577 } else {
578 None
579 }
580 })
581 .collect::<Vec<(usize, usize, T::Bound)>>();
582
583 for (node_index, parent_index, fat_bound) in nodes {
584 if let Node::Leaf(ref mut leaf) = self.nodes[node_index] {
585 leaf.bound = fat_bound;
586 }
587 self.mark_for_refit(parent_index, 2);
588 }
589
590 self.updated_list.clear();
591 }
592
593 /// Utility method to perform updates and refitting. Should be called once per frame.
594 ///
595 /// Will in turn call [`update`](struct.DynamicBoundingVolumeTree.html#method.update), followed
596 /// by [`do_refit`](struct.DynamicBoundingVolumeTree.html#method.do_refit).
597 ///
598 pub fn tick(&mut self) {
599 self.update();
600 self.do_refit();
601 }
602
603 /// Insert a value into the tree.
604 ///
605 /// This will search the tree for the best leaf to pair the value up with, using the surface
606 /// area of the value's bounding volume as the main heuristic. Will always cause a new branch
607 /// node and a new leaf node (containing the given value) to be added to the tree.
608 /// This is to keep the invariant of branches always having 2 children true.
609 ///
610 /// This function should have approximate complexity O(log^2 n).
611 ///
612 /// Note that no parents have their bounds/height updated directly by this function, instead
613 /// [`do_refit`](struct.DynamicBoundingVolumeTree.html#method.do_refit) should be called after
614 /// all insert/remove/updates have been performed this frame.
615 ///
616 /// ### Parameters
617 ///
618 /// - `value`: The value to insert into the tree.
619 ///
620 /// ### Returns
621 ///
622 /// The node index of the inserted value. This value should never change after insertion.
623 ///
624 pub fn insert(&mut self, value: T) -> usize {
625 let fat_bound = value.get_bound_with_margin();
626 let value_index = self.values.len();
627 self.values.push((0, value));
628
629 // Create a new leaf node for the given value
630 let mut new_leaf = Leaf {
631 parent: 0,
632 value: value_index,
633 bound: fat_bound,
634 };
635
636 // If the root index is 0, this is the first node inserted, and we can circumvent a lot of
637 // checks.
638 if self.root_index == 0 {
639 self.root_index = self.nodes.len();
640 self.nodes.push(Node::Leaf(new_leaf));
641 self.values[value_index].0 = self.root_index;
642 self.root_index
643 } else {
644 // Start searching from the root node
645 let mut node_index = self.root_index;
646
647 // We will always insert a branch node and the new leaf node, so get 2 new indices
648 // into the node list
649 let (new_branch_index, new_leaf_index) = self.next_free();
650 // We need to tell the value what it's node index is
651 self.values[value_index].0 = new_leaf_index;
652 // The new leaf will always be a child of the new branch node.
653 new_leaf.parent = new_branch_index;
654
655 let mut branch_parent_index = 0;
656
657 loop {
658 // If we encounter a leaf node, we've found the place where we want to add the new
659 // nodes. The branch node will be inserted into the tree here, and this node will be
660 // moved down as the left child of the new branch node, and the new leaf will be the
661 // right child.
662 let add_branch = match self.nodes[node_index] {
663 Node::Leaf(ref leaf) => {
664 let new_branch = Branch {
665 left: node_index, // old leaf at the current position is left child
666 right: new_leaf_index, // new leaf node is the right child
667 parent: leaf.parent, // parent of the branch is the old leaf parent
668 height: 2, // leafs have height 1, so new branch have height 2
669 bound: leaf.bound.union(&new_leaf.bound),
670 };
671 Some((node_index, new_branch))
672 }
673
674 // If we hit a branch, we compute the surface area of the bounding volumes for
675 // if the new leaf was added to the right or left. Whichever surface area is
676 // lowest will decide which child to go to next.
677 Node::Branch(ref branch) => {
678 let left_bound = get_bound(&self.nodes[branch.left]);
679 let right_bound = get_bound(&self.nodes[branch.right]);
680 let left_area = left_bound.union(&new_leaf.bound).surface_area();
681 let right_area = right_bound.union(&new_leaf.bound).surface_area();
682 if left_area < right_area {
683 node_index = branch.left;
684 } else {
685 node_index = branch.right;
686 }
687 None
688 }
689
690 Node::Nil => break,
691 };
692
693 // time to actually update the tree
694 if let Some((leaf_index, branch)) = add_branch {
695 // the old leaf node needs to point to the new branch node as its parent
696 if let Node::Leaf(ref mut n) = self.nodes[leaf_index] {
697 n.parent = new_branch_index;
698 };
699
700 // if the old leaf node wasn't the root of tree, we update it's parent to point
701 // to the new branch node insteaf of the old leaf node
702 branch_parent_index = branch.parent;
703 if branch.parent != 0 {
704 if let Node::Branch(ref mut n) = self.nodes[branch.parent] {
705 if n.left == leaf_index {
706 n.left = new_branch_index;
707 } else {
708 n.right = new_branch_index;
709 }
710 }
711 }
712
713 // insert to new branch and leaf nodes
714 self.nodes[new_branch_index] = Node::Branch(branch);
715 self.nodes[new_leaf_index] = Node::Leaf(new_leaf);
716
717 // if the leaf node was the root of the tree,
718 // the new root is the new branch node
719 if leaf_index == self.root_index {
720 self.root_index = new_branch_index;
721 }
722 break;
723 }
724 }
725
726 // mark the new branch nodes parent for bounds/height updating and possible rotation
727 if branch_parent_index != 0 {
728 self.mark_for_refit(branch_parent_index, 3);
729 }
730
731 new_leaf_index
732 }
733 }
734
735 /// Remove the node with the given node index.
736 ///
737 /// The reason this function takes the node index and not a reference to the value, is because
738 /// the only way to get at the values in the tree is by doing a mutable borrow, making this
739 /// function unusable.
740 ///
741 /// If the given node index points to a non-leaf, this function is effectively a nop.
742 /// Else the leaf node and it's parent branch node will be removed, and the leaf nodes sibling
743 /// will take the place of the parent branch node in the tree.
744 ///
745 /// Note that no parents have their bounds/height updated directly by this function, instead
746 /// [`do_refit`](struct.DynamicBoundingVolumeTree.html#method.do_refit) should be called after
747 /// all insert/remove/updates have been performed this frame.
748 ///
749 /// This function should have approximate complexity O(log^2 n).
750 ///
751 /// ### Parameters
752 ///
753 /// - `node_index`: index of the leaf to remove
754 ///
755 /// ### Returns
756 ///
757 /// If a value was removed, the value is returned, otherwise None.
758 ///
759 pub fn remove(&mut self, node_index: usize) -> Option<T> {
760 let (value_index, parent_index) = if let Node::Leaf(ref leaf) = self.nodes[node_index] {
761 (leaf.value, leaf.parent)
762 } else {
763 // If a value points to a non-leaf something has gone wrong,
764 // ignore remove and continue with life
765 return None;
766 };
767 // remove from values list and update node list with new value indices
768 let (_, value) = self.values.swap_remove(value_index);
769 // we only need to update the node for the value that we swapped into the old values place
770 if value_index < self.values.len() {
771 // should only fail if we just removed the last value
772 if let Node::Leaf(ref mut leaf) = self.nodes[self.values[value_index].0] {
773 leaf.value = value_index;
774 }
775 }
776
777 // remove from node list and add index to free list
778 self.nodes[node_index] = Node::Nil;
779 self.free_list.push(node_index);
780
781 if parent_index != 0 {
782 // remove parent branch from node list and add index to free list
783 let (parent_parent_index, sibling_index) =
784 if let Node::Branch(ref branch) = self.nodes[parent_index] {
785 (
786 branch.parent,
787 if branch.left == node_index {
788 branch.right
789 } else {
790 branch.left
791 },
792 )
793 } else {
794 return Some(value);
795 };
796 self.nodes[parent_index] = Node::Nil;
797 self.free_list.push(parent_index);
798
799 // set sibling parent to parent.parent
800 match self.nodes[sibling_index] {
801 Node::Branch(ref mut branch) => branch.parent = parent_parent_index,
802 Node::Leaf(ref mut leaf) => leaf.parent = parent_parent_index,
803 Node::Nil => (),
804 }
805
806 // if parents parent is 0, the sibling is the last node in the tree and becomes the new
807 // root node
808 if parent_parent_index == 0 {
809 self.root_index = sibling_index;
810 } else {
811 // else we have a remaining branch, and need to update either left or right to point
812 // to the sibling, based on where the old branch node was
813 if let Node::Branch(ref mut b) = self.nodes[parent_parent_index] {
814 if b.left == parent_index {
815 b.left = sibling_index;
816 } else {
817 b.right = sibling_index;
818 }
819 }
820
821 // mark parents parent for recalculation
822 self.mark_for_refit(parent_parent_index, 0);
823 }
824 } else {
825 // if parent was 0, this was the last node in the tree, and the tree is now empty.
826 // reset all values.
827 self.clear();
828 }
829
830 Some(value)
831 }
832
833 /// Go through the list of nodes marked for refitting, update their bounds/heights and check if
834 /// any of them need to be rotated to new locations.
835 ///
836 /// This method have worst case complexity O(m * log^2 n), where m is the number of nodes in the
837 /// refit list.
838 ///
839 pub fn do_refit(&mut self) {
840 while !self.refit_nodes.is_empty() {
841 let (_, node_index) = self.refit_nodes.remove(0);
842 self.refit_node(node_index);
843 }
844 }
845
846 /// Get two new node indices, where nodes can be inserted in the tree.
847 ///
848 fn next_free(&mut self) -> (usize, usize) {
849 (self.take_free(), self.take_free())
850 }
851
852 /// Get a new node index, where a node can be inserted in the tree.
853 ///
854 fn take_free(&mut self) -> usize {
855 if self.free_list.is_empty() {
856 let index = self.nodes.len();
857 self.nodes.push(Node::Nil);
858 index
859 } else {
860 self.free_list.remove(0)
861 }
862 }
863
864 /// Add the given node to the refitting list.
865 ///
866 /// The refit list is sorted by the height of the node, and only have the same value
867 /// once, any duplicates are rejected. This because we don't want to refit the same node
868 /// twice.
869 ///
870 /// ### Parameters
871 ///
872 /// - `node_index`: index of the node to do refitting on.
873 /// - `min_height`: the minimum height the node has. Used primarily by insertion where we can't
874 /// be sure that the node has been refitted yet and might have an incorrect
875 /// height
876 ///
877 fn mark_for_refit(&mut self, node_index: usize, min_height: u32) {
878 let node_height = match self.nodes[node_index] {
879 Node::Branch(ref b) => b.height,
880 _ => 0,
881 };
882 let height = max(node_height, min_height);
883 let value = (height, node_index);
884 match self.refit_nodes.binary_search(&value) {
885 Ok(_) => (),
886 Err(i) => self.refit_nodes.insert(i, value),
887 }
888 }
889
890 /// Actually refit a node in the tree. This will check the node for rotation, and if rotated,
891 /// will update the bound/height of itself and any other rotated nodes, and also mark its parent
892 /// for refitting.
893 ///
894 fn refit_node(&mut self, node_index: usize) {
895 if let Some((parent_index, height)) = self.recalculate_node(node_index) {
896 if parent_index != 0 {
897 self.mark_for_refit(parent_index, height + 1);
898 }
899 }
900
901 // Only do rotations occasionally, as they are fairly expensive, and shouldn't be overused.
902 // For most scenarios, the majority of shapes will not have moved, so this is fine.
903 if rand::thread_rng().gen_range(0, 100) < PERFORM_ROTATION_PERCENTAGE {
904 self.rotate(node_index);
905 }
906 }
907
908 /// Recalculate the bound and height of the node.
909 ///
910 fn recalculate_node(&mut self, node_index: usize) -> Option<(usize, u32)> {
911 let (height, bound, parent_index) = {
912 let (left_height, left_bound, right_height, right_bound, parent_index) =
913 if let Node::Branch(ref branch) = self.nodes[node_index] {
914 (
915 get_height(&self.nodes[branch.left]),
916 get_bound(&self.nodes[branch.left]),
917 get_height(&self.nodes[branch.right]),
918 get_bound(&self.nodes[branch.right]),
919 branch.parent,
920 )
921 } else {
922 return None;
923 };
924 (
925 1 + max(left_height, right_height),
926 left_bound.union(right_bound),
927 parent_index,
928 )
929 };
930 if let Node::Branch(ref mut branch) = self.nodes[node_index] {
931 branch.height = height;
932 branch.bound = bound;
933 }
934
935 Some((parent_index, height))
936 }
937
938 /// Check if the node needs to be rotated, and perform the rotation if that is the case.
939 ///
940 /// ### Parameters:
941 ///
942 /// - `node_index`: index of the node to check for rotation
943 ///
944 /// ### Returns
945 ///
946 /// The parent index of the given node
947 ///
948 fn rotate(&mut self, node_index: usize) -> Option<usize> {
949 let improvement_percentage: <T::Bound as SurfaceArea>::Scalar =
950 NumCast::from(SURFACE_AREA_IMPROVEMENT_FOR_ROTATION).unwrap();
951
952 let (left_index, right_index, my_surface_area, parent_index) =
953 if let Node::Branch(ref branch) = self.nodes[node_index] {
954 (
955 branch.left,
956 branch.right,
957 branch.bound.surface_area(),
958 branch.parent,
959 )
960 } else {
961 return None;
962 };
963
964 let left_is_leaf = is_leaf(&self.nodes[left_index]);
965 let right_is_leaf = is_leaf(&self.nodes[right_index]);
966
967 // if the node is a grandparent, we can do rotation checks
968 if !left_is_leaf || !right_is_leaf {
969 let (rot, min_sa) = get_best_rotation(
970 &self.nodes,
971 left_index,
972 right_index,
973 my_surface_area,
974 left_is_leaf,
975 right_is_leaf,
976 );
977
978 // we now know which rotation will give us the best surface area
979 // only do actual rotation if the surface area is reduced by atleast 25%
980 if (my_surface_area - min_sa) / my_surface_area > improvement_percentage {
981 match rot {
982 // do nothing
983 Rotation::None => (),
984
985 // swap left child with right left grandchild
986 // right child and node needs to be recalculated
987 Rotation::LeftRightLeft => {
988 let right_left_index = get_left_index(&self.nodes[right_index]);
989 swap(
990 &mut self.nodes,
991 left_index,
992 right_left_index,
993 node_index,
994 right_index,
995 );
996 self.recalculate_node(right_index);
997 self.recalculate_node(node_index);
998 }
999
1000 // swap left child with right right grandchild
1001 // right child and node needs to be recalculated
1002 Rotation::LeftRightRight => {
1003 let right_right_index = get_right_index(&self.nodes[right_index]);
1004 swap(
1005 &mut self.nodes,
1006 left_index,
1007 right_right_index,
1008 node_index,
1009 right_index,
1010 );
1011 self.recalculate_node(right_index);
1012 self.recalculate_node(node_index);
1013 }
1014
1015 // swap right child with left left grandchild
1016 // left child and node needs to be recalculated
1017 Rotation::RightLeftLeft => {
1018 let left_left_index = get_left_index(&self.nodes[left_index]);
1019 swap(
1020 &mut self.nodes,
1021 left_left_index,
1022 right_index,
1023 left_index,
1024 node_index,
1025 );
1026 self.recalculate_node(left_index);
1027 self.recalculate_node(node_index);
1028 }
1029
1030 // swap right child with left right grandchild
1031 // left child and node needs to be recalculated
1032 Rotation::RightLeftRight => {
1033 let left_right_index = get_right_index(&self.nodes[left_index]);
1034 swap(
1035 &mut self.nodes,
1036 left_right_index,
1037 right_index,
1038 left_index,
1039 node_index,
1040 );
1041 self.recalculate_node(left_index);
1042 self.recalculate_node(node_index);
1043 }
1044
1045 // swap left left grandchild with right left grandchild
1046 // left child, right child and node needs to be recalculated
1047 Rotation::LeftLeftRightLeft => {
1048 let left_left_index = get_left_index(&self.nodes[left_index]);
1049 let right_left_index = get_left_index(&self.nodes[right_index]);
1050 swap(
1051 &mut self.nodes,
1052 left_left_index,
1053 right_left_index,
1054 left_index,
1055 right_index,
1056 );
1057 self.recalculate_node(left_index);
1058 self.recalculate_node(right_index);
1059 self.recalculate_node(node_index);
1060 }
1061
1062 // swap left left grandchild with right right grandchild
1063 // left child, right child and node needs to be recalculated
1064 Rotation::LeftLeftRightRight => {
1065 let left_left_index = get_left_index(&self.nodes[left_index]);
1066 let right_right_index = get_right_index(&self.nodes[right_index]);
1067 swap(
1068 &mut self.nodes,
1069 left_left_index,
1070 right_right_index,
1071 left_index,
1072 right_index,
1073 );
1074 self.recalculate_node(left_index);
1075 self.recalculate_node(right_index);
1076 self.recalculate_node(node_index);
1077 }
1078 }
1079 }
1080 }
1081
1082 Some(parent_index)
1083 }
1084}
1085
1086enum Rotation {
1087 None,
1088 LeftRightLeft,
1089 LeftRightRight,
1090 RightLeftLeft,
1091 RightLeftRight,
1092 LeftLeftRightLeft,
1093 LeftLeftRightRight,
1094}
1095
1096/// Swap two nodes in the tree.
1097///
1098/// left_parent.`[left,right]` = right_swap
1099/// right_parent.`[left,right]` = left_swap
1100/// left_swap.parent = right_parent
1101/// right_swap.parent = left_parent
1102///
1103#[inline]
1104fn swap<B>(
1105 nodes: &mut Vec<Node<B>>,
1106 left_swap_index: usize,
1107 right_swap_index: usize,
1108 left_parent_index: usize,
1109 right_parent_index: usize,
1110) {
1111 if let Node::Branch(ref mut left_parent) = nodes[left_parent_index] {
1112 if left_parent.left == left_swap_index {
1113 left_parent.left = right_swap_index;
1114 } else {
1115 left_parent.right = right_swap_index;
1116 }
1117 }
1118
1119 if let Node::Branch(ref mut right_parent) = nodes[right_parent_index] {
1120 if right_parent.left == right_swap_index {
1121 right_parent.left = left_swap_index;
1122 } else {
1123 right_parent.right = left_swap_index;
1124 }
1125 }
1126
1127 match nodes[left_swap_index] {
1128 Node::Branch(ref mut left) => left.parent = right_parent_index,
1129 Node::Leaf(ref mut left) => left.parent = right_parent_index,
1130 _ => (),
1131 }
1132
1133 match nodes[right_swap_index] {
1134 Node::Branch(ref mut rl) => rl.parent = left_parent_index,
1135 Node::Leaf(ref mut rl) => rl.parent = left_parent_index,
1136 _ => (),
1137 }
1138}
1139
1140/// Calculate the best rotation for a given grandparent node in the tree
1141#[inline]
1142fn get_best_rotation<B>(
1143 nodes: &[Node<B>],
1144 left_index: usize,
1145 right_index: usize,
1146 node_surface_area: <B as SurfaceArea>::Scalar,
1147 left_is_leaf: bool,
1148 right_is_leaf: bool,
1149) -> (Rotation, <B as SurfaceArea>::Scalar)
1150where
1151 B: Union<B, Output = B> + SurfaceArea,
1152{
1153 let mut rot = Rotation::None;
1154 let mut min_sa = node_surface_area;
1155
1156 // we need the left and right child bounds for 4 tests
1157 let l_bound = get_bound(&nodes[left_index]);
1158 let r_bound = get_bound(&nodes[right_index]);
1159
1160 // if the right child is not a leaf, we want to consider swapping its children with
1161 // either the left child or the left left grandchild
1162 if !right_is_leaf {
1163 let (rl_bound, rr_bound) = match nodes[right_index] {
1164 Node::Branch(ref right) => (
1165 get_bound(&nodes[right.left]),
1166 get_bound(&nodes[right.right]),
1167 ),
1168 _ => panic!(),
1169 };
1170
1171 // check for left child swapped with right left grandchild
1172 let l_rl_sa = sa(rl_bound, l_bound, rr_bound);
1173 if l_rl_sa < min_sa {
1174 rot = Rotation::LeftRightLeft;
1175 min_sa = l_rl_sa;
1176 }
1177
1178 // check for left child swapped with right right grandchild
1179 let l_rr_sa = sa(rr_bound, l_bound, rl_bound);
1180 if l_rr_sa < min_sa {
1181 rot = Rotation::LeftRightRight;
1182 min_sa = l_rr_sa;
1183 }
1184
1185 // check for left left grandchild swapped with either of the right grandchildren
1186 if !left_is_leaf {
1187 let (ll_bound, lr_bound) = match nodes[left_index] {
1188 Node::Branch(ref left) => {
1189 (get_bound(&nodes[left.left]), get_bound(&nodes[left.right]))
1190 }
1191 _ => panic!(),
1192 };
1193
1194 // check for left left grandchild swapped with right left grandchild
1195 let ll_rl_sa = sa(&rl_bound.union(lr_bound), ll_bound, rr_bound);
1196 if ll_rl_sa < min_sa {
1197 rot = Rotation::LeftLeftRightLeft;
1198 min_sa = ll_rl_sa;
1199 }
1200
1201 // check for left left grandchild swapped with right right grandchild
1202 let ll_rr_sa = sa(&rr_bound.union(lr_bound), rl_bound, ll_bound);
1203 if ll_rr_sa < min_sa {
1204 rot = Rotation::LeftLeftRightRight;
1205 min_sa = ll_rr_sa;
1206 }
1207
1208 // we don't need to check for left right grandchild swapped with any of the right
1209 // grandchildren. this would only result in mirrored trees and have the same cost
1210 // as other cases, making it redundant work
1211 }
1212 }
1213
1214 // if the left child is not a leaf, we want to consider swapping its children with the
1215 // right child
1216 if !left_is_leaf {
1217 let (ll_bound, lr_bound) = match nodes[left_index] {
1218 Node::Branch(ref left) => (get_bound(&nodes[left.left]), get_bound(&nodes[left.right])),
1219 _ => panic!(),
1220 };
1221
1222 // check for right child swapped with left left grandchild
1223 let r_ll_sa = sa(ll_bound, r_bound, lr_bound);
1224 if r_ll_sa < min_sa {
1225 rot = Rotation::RightLeftLeft;
1226 min_sa = r_ll_sa;
1227 }
1228
1229 // check for right child swapped with left right grandchild
1230 let r_lr_sa = sa(lr_bound, r_bound, ll_bound);
1231 if r_lr_sa < min_sa {
1232 rot = Rotation::RightLeftRight;
1233 min_sa = r_lr_sa;
1234 }
1235 }
1236
1237 (rot, min_sa)
1238}
1239
1240/// Calculate the surface area of 3 combined bounding volumes, a.union(b.union(c)).
1241#[inline]
1242fn sa<B>(a: &B, b: &B, c: &B) -> <B as SurfaceArea>::Scalar
1243where
1244 B: Union<B, Output = B> + SurfaceArea,
1245{
1246 a.union(&b.union(c)).surface_area()
1247}
1248
1249#[inline]
1250fn get_left_index<B>(node: &Node<B>) -> usize {
1251 match *node {
1252 Node::Branch(ref b) => b.left,
1253 _ => panic!(),
1254 }
1255}
1256
1257#[inline]
1258fn get_right_index<B>(node: &Node<B>) -> usize {
1259 match *node {
1260 Node::Branch(ref b) => b.right,
1261 _ => panic!(),
1262 }
1263}
1264
1265#[inline]
1266fn is_leaf<B>(node: &Node<B>) -> bool {
1267 match *node {
1268 Node::Leaf(_) => true,
1269 _ => false,
1270 }
1271}
1272
1273/// Get the height of the node, regardless of node type. Leafs have height 1, nil height 0.
1274///
1275#[inline]
1276fn get_height<B>(node: &Node<B>) -> u32 {
1277 match *node {
1278 Node::Branch(ref branch) => branch.height,
1279 Node::Leaf(_) => 1,
1280 Node::Nil => 0,
1281 }
1282}
1283
1284/// Get the bound of the node. Will panic if node is nil.
1285///
1286#[inline]
1287fn get_bound<B>(node: &Node<B>) -> &B {
1288 match *node {
1289 Node::Branch(ref branch) => &branch.bound,
1290 Node::Leaf(ref leaf) => &leaf.bound,
1291 Node::Nil => panic!(),
1292 }
1293}