ncollide3d/query/proximity/
proximity_support_map_support_map.rs

1use na::{self, RealField, Unit};
2
3use crate::math::{Isometry, Vector};
4use crate::query::algorithms::VoronoiSimplex;
5use crate::query::algorithms::{gjk, gjk::GJKResult, CSOPoint};
6use crate::query::Proximity;
7use crate::shape::SupportMap;
8
9/// Proximity between support-mapped shapes (`Cuboid`, `ConvexHull`, etc.)
10pub fn proximity_support_map_support_map<N, G1: ?Sized, G2: ?Sized>(
11    m1: &Isometry<N>,
12    g1: &G1,
13    m2: &Isometry<N>,
14    g2: &G2,
15    margin: N,
16) -> Proximity
17where
18    N: RealField + Copy,
19    G1: SupportMap<N>,
20    G2: SupportMap<N>,
21{
22    proximity_support_map_support_map_with_params(
23        m1,
24        g1,
25        m2,
26        g2,
27        margin,
28        &mut VoronoiSimplex::new(),
29        None,
30    )
31    .0
32}
33
34/// Proximity between support-mapped shapes (`Cuboid`, `ConvexHull`, etc.)
35///
36/// This allows a more fine grained control other the underlying GJK algorigtm.
37pub fn proximity_support_map_support_map_with_params<N, G1: ?Sized, G2: ?Sized>(
38    m1: &Isometry<N>,
39    g1: &G1,
40    m2: &Isometry<N>,
41    g2: &G2,
42    margin: N,
43    simplex: &mut VoronoiSimplex<N>,
44    init_dir: Option<Unit<Vector<N>>>,
45) -> (Proximity, Unit<Vector<N>>)
46where
47    N: RealField + Copy,
48    G1: SupportMap<N>,
49    G2: SupportMap<N>,
50{
51    assert!(
52        margin >= na::zero(),
53        "The proximity margin must be positive or zero."
54    );
55
56    let dir = if let Some(init_dir) = init_dir {
57        init_dir
58    } else if let Some(init_dir) = Unit::try_new(
59        m2.translation.vector - m1.translation.vector,
60        N::default_epsilon(),
61    ) {
62        init_dir
63    } else {
64        Vector::x_axis()
65    };
66
67    simplex.reset(CSOPoint::from_shapes(m1, g1, m2, g2, &dir));
68
69    match gjk::closest_points(m1, g1, m2, g2, margin, false, simplex) {
70        GJKResult::Intersection => (Proximity::Intersecting, dir),
71        GJKResult::Proximity(dir) => (Proximity::WithinMargin, dir),
72        GJKResult::NoIntersection(dir) => (Proximity::Disjoint, dir),
73        GJKResult::ClosestPoints(..) => unreachable!(),
74    }
75}