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
9pub 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
34pub 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}