ncollide3d/query/contact/
contact_support_map_support_map.rs
1use crate::math::{Isometry, Vector};
2use crate::query::algorithms::{gjk, gjk::GJKResult, CSOPoint};
3use crate::query::algorithms::{VoronoiSimplex, EPA};
4use crate::query::Contact;
5use crate::shape::SupportMap;
6use na::{RealField, Unit};
7
8pub fn contact_support_map_support_map<N, G1: ?Sized, G2: ?Sized>(
10 m1: &Isometry<N>,
11 g1: &G1,
12 m2: &Isometry<N>,
13 g2: &G2,
14 prediction: N,
15) -> Option<Contact<N>>
16where
17 N: RealField + Copy,
18 G1: SupportMap<N>,
19 G2: SupportMap<N>,
20{
21 let simplex = &mut VoronoiSimplex::new();
22 match contact_support_map_support_map_with_params(m1, g1, m2, g2, prediction, simplex, None) {
23 GJKResult::ClosestPoints(world1, world2, normal) => {
24 Some(Contact::new_wo_depth(world1, world2, normal))
25 }
26 GJKResult::NoIntersection(_) => None,
27 GJKResult::Intersection => unreachable!(),
28 GJKResult::Proximity(_) => unreachable!(),
29 }
30}
31
32pub fn contact_support_map_support_map_with_params<N, G1: ?Sized, G2: ?Sized>(
39 m1: &Isometry<N>,
40 g1: &G1,
41 m2: &Isometry<N>,
42 g2: &G2,
43 prediction: N,
44 simplex: &mut VoronoiSimplex<N>,
45 init_dir: Option<Unit<Vector<N>>>,
46) -> GJKResult<N>
47where
48 N: RealField + Copy,
49 G1: SupportMap<N>,
50 G2: SupportMap<N>,
51{
52 let dir = if let Some(init_dir) = init_dir {
53 init_dir
54 } else if let Some(init_dir) = Unit::try_new(
55 m2.translation.vector - m1.translation.vector,
56 N::default_epsilon(),
57 ) {
58 init_dir
59 } else {
60 Vector::x_axis()
61 };
62
63 simplex.reset(CSOPoint::from_shapes(m1, g1, m2, g2, &dir));
64
65 let cpts = gjk::closest_points(m1, g1, m2, g2, prediction, true, simplex);
66 if cpts != GJKResult::Intersection {
67 return cpts;
68 }
69
70 let mut epa = EPA::new();
72 if let Some((p1, p2, n)) = epa.closest_points(m1, g1, m2, g2, simplex) {
73 return GJKResult::ClosestPoints(p1, p2, n);
75 }
76
77 GJKResult::NoIntersection(Vector::x_axis())
79
80 }