ncollide3d/pipeline/narrow_phase/contact_generator/
default_contact_dispatcher.rs

1#[cfg(feature = "dim3")]
2use crate::pipeline::narrow_phase::TriMeshTriMeshManifoldGenerator;
3use crate::pipeline::{
4    BallBallManifoldGenerator, BallConvexPolyhedronManifoldGenerator,
5    CapsuleCapsuleManifoldGenerator, CapsuleShapeManifoldGenerator,
6    CompositeShapeCompositeShapeManifoldGenerator, CompositeShapeShapeManifoldGenerator,
7    ContactAlgorithm, ContactDispatcher, ConvexPolyhedronConvexPolyhedronManifoldGenerator,
8    HeightFieldShapeManifoldGenerator, PlaneBallManifoldGenerator,
9    PlaneConvexPolyhedronManifoldGenerator,
10};
11#[cfg(feature = "dim3")]
12use crate::shape::TriMesh;
13use crate::shape::{Ball, Capsule, HeightField, Plane, Shape};
14use na::RealField;
15
16/// Collision dispatcher for shapes defined by `ncollide_entities`.
17pub struct DefaultContactDispatcher {}
18
19impl DefaultContactDispatcher {
20    /// Creates a new basic collision dispatcher.
21    pub fn new() -> DefaultContactDispatcher {
22        DefaultContactDispatcher {}
23    }
24}
25
26impl<N: RealField + Copy> ContactDispatcher<N> for DefaultContactDispatcher {
27    fn get_contact_algorithm(
28        &self,
29        a: &dyn Shape<N>,
30        b: &dyn Shape<N>,
31    ) -> Option<ContactAlgorithm<N>> {
32        let a_is_ball = a.is_shape::<Ball<N>>();
33        let b_is_ball = b.is_shape::<Ball<N>>();
34        let a_is_plane = a.is_shape::<Plane<N>>();
35        let b_is_plane = b.is_shape::<Plane<N>>();
36        let a_is_capsule = a.is_shape::<Capsule<N>>();
37        let b_is_capsule = b.is_shape::<Capsule<N>>();
38        let a_is_heightfield = a.is_shape::<HeightField<N>>();
39        let b_is_heightfield = b.is_shape::<HeightField<N>>();
40
41        #[cfg(feature = "dim3")]
42        {
43            let a_is_trimesh = a.is_shape::<TriMesh<N>>();
44            let b_is_trimesh = b.is_shape::<TriMesh<N>>();
45
46            if a_is_trimesh && b_is_trimesh {
47                return Some(Box::new(TriMeshTriMeshManifoldGenerator::<N>::new()));
48            }
49        }
50
51        if a_is_heightfield || b_is_heightfield {
52            return Some(Box::new(HeightFieldShapeManifoldGenerator::<N>::new(
53                b_is_heightfield,
54            )));
55        } else if a_is_capsule && b_is_capsule {
56            Some(Box::new(CapsuleCapsuleManifoldGenerator::<N>::new()))
57        } else if a_is_capsule || b_is_capsule {
58            Some(Box::new(CapsuleShapeManifoldGenerator::<N>::new(
59                b_is_capsule,
60            )))
61        } else if a_is_ball && b_is_ball {
62            Some(Box::new(BallBallManifoldGenerator::<N>::new()))
63        } else if a_is_plane && b_is_ball {
64            Some(Box::new(PlaneBallManifoldGenerator::<N>::new(false)))
65        } else if a_is_ball && b_is_plane {
66            Some(Box::new(PlaneBallManifoldGenerator::<N>::new(true)))
67        } else if a_is_plane && b.is_support_map() {
68            let gen = PlaneConvexPolyhedronManifoldGenerator::<N>::new(false);
69            Some(Box::new(gen))
70        } else if b_is_plane && a.is_support_map() {
71            let gen = PlaneConvexPolyhedronManifoldGenerator::<N>::new(true);
72            Some(Box::new(gen))
73        } else if a_is_ball && b.is_convex_polyhedron() {
74            let gen = BallConvexPolyhedronManifoldGenerator::<N>::new(false);
75            Some(Box::new(gen))
76        } else if b_is_ball && a.is_convex_polyhedron() {
77            let gen = BallConvexPolyhedronManifoldGenerator::<N>::new(true);
78            Some(Box::new(gen))
79        } else if a.is_convex_polyhedron() && b.is_convex_polyhedron() {
80            let gen = ConvexPolyhedronConvexPolyhedronManifoldGenerator::new();
81            Some(Box::new(gen))
82        } else if a.is_composite_shape() && b.is_composite_shape() {
83            Some(Box::new(
84                CompositeShapeCompositeShapeManifoldGenerator::<N>::new(),
85            ))
86        } else if a.is_composite_shape() {
87            Some(Box::new(CompositeShapeShapeManifoldGenerator::<N>::new(
88                false,
89            )))
90        } else if b.is_composite_shape() {
91            Some(Box::new(CompositeShapeShapeManifoldGenerator::<N>::new(
92                true,
93            )))
94        } else {
95            None
96        }
97    }
98}