ncollide3d/query/visitors/
aabb_sets_interferences_collector.rs

1use crate::bounding_volume::{BoundingVolume, AABB};
2use crate::math::{Isometry, Matrix, Vector};
3use crate::partitioning::{SimultaneousVisitor, VisitStatus};
4use na::RealField;
5
6/// Spatial partitioning data structure visitor collecting interferences with a given bounding volume.
7pub struct AABBSetsInterferencesCollector<'a, N: 'a + RealField + Copy, T: 'a> {
8    /// The transform from the local-space of the second bounding volumes to the local space of the first.
9    pub ls_m2: &'a Isometry<N>,
10    /// The absolute value of the rotation matrix representing `ls_m2.rotation`.
11    ///
12    /// Equals to `ls_m2.rotation.to_rotation.matrix().matrix().abs()`.
13    pub ls_m2_abs_rot: &'a Matrix<N>,
14    /// A tolerance applied to the interference tests.
15    ///
16    /// AABB pairs closer than `tolerance` will be reported as intersecting.
17    pub tolerence: N,
18    /// The data contained by the nodes with bounding volumes intersecting `self.bv`.
19    pub collector: &'a mut Vec<(T, T)>,
20}
21
22impl<'a, N: RealField + Copy, T> AABBSetsInterferencesCollector<'a, N, T> {
23    /// Creates a new `AABBSetsInterferencesCollector`.
24    #[inline]
25    pub fn new(
26        tolerence: N,
27        ls_m2: &'a Isometry<N>,
28        ls_m2_abs_rot: &'a Matrix<N>,
29        collector: &'a mut Vec<(T, T)>,
30    ) -> AABBSetsInterferencesCollector<'a, N, T> {
31        AABBSetsInterferencesCollector {
32            tolerence,
33            ls_m2,
34            ls_m2_abs_rot,
35            collector,
36        }
37    }
38}
39
40impl<'a, N: RealField + Copy, T: Clone> SimultaneousVisitor<T, AABB<N>>
41    for AABBSetsInterferencesCollector<'a, N, T>
42{
43    #[inline]
44    fn visit(
45        &mut self,
46        left_bv: &AABB<N>,
47        left_data: Option<&T>,
48        right_bv: &AABB<N>,
49        right_data: Option<&T>,
50    ) -> VisitStatus {
51        let ls_right_bv = AABB::from_half_extents(
52            self.ls_m2 * right_bv.center(),
53            self.ls_m2_abs_rot * right_bv.half_extents() + Vector::repeat(self.tolerence),
54        );
55
56        if left_bv.intersects(&ls_right_bv) {
57            if let (Some(a), Some(b)) = (left_data, right_data) {
58                self.collector.push((a.clone(), b.clone()))
59            }
60
61            VisitStatus::Continue
62        } else {
63            VisitStatus::Stop
64        }
65    }
66}