1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use crate::bounding_volume::{BoundingVolume, CircularCone, AABB};
use crate::math::Point;
use na::RealField;

/// The combination of an AABB with a circular cone to bound both the space occupied by an geometry and its normals.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SpatializedNormalCone<N: RealField> {
    /// An AABB bounding the space occupied by a geometry.
    pub aabb: AABB<N>,
    /// A circular cone bounding the normals of a geometry.
    pub normals: CircularCone<N>,
}

impl<N: RealField> BoundingVolume<N> for SpatializedNormalCone<N> {
    fn center(&self) -> Point<N> {
        self.aabb.center()
    }

    fn intersects(&self, other: &Self) -> bool {
        self.aabb.intersects(&other.aabb) && self.normals.double_cones_intersect(&other.normals)
    }

    fn contains(&self, other: &Self) -> bool {
        self.aabb.contains(&other.aabb) && self.normals.contains(&other.normals)
    }

    fn merge(&mut self, other: &Self) {
        self.aabb.merge(&other.aabb);
        self.normals.merge(&other.normals);
    }

    fn merged(&self, other: &Self) -> Self {
        SpatializedNormalCone {
            aabb: self.aabb.merged(&other.aabb),
            normals: self.normals.merged(&other.normals),
        }
    }

    fn loosen(&mut self, margin: N) {
        self.aabb.loosen(margin)
    }

    fn loosened(&self, margin: N) -> Self {
        SpatializedNormalCone {
            aabb: self.aabb.loosened(margin),
            normals: self.normals,
        }
    }

    fn tighten(&mut self, margin: N) {
        self.aabb.tighten(margin)
    }

    fn tightened(&self, margin: N) -> Self {
        SpatializedNormalCone {
            aabb: self.aabb.tightened(margin),
            normals: self.normals,
        }
    }
}