ncollide3d/pipeline/narrow_phase/contact_generator/
capsule_capsule_manifold_generator.rs

1use crate::math::Isometry;
2use crate::pipeline::narrow_phase::{
3    ContactDispatcher, ContactManifoldGenerator, ConvexPolyhedronConvexPolyhedronManifoldGenerator,
4};
5use crate::query::{ContactManifold, ContactPrediction, ContactPreprocessor};
6use crate::shape::{Capsule, Shape};
7use na::{self, RealField};
8
9/// Collision detector between a concave shape and another shape.
10pub struct CapsuleCapsuleManifoldGenerator<N: RealField + Copy> {
11    // FIXME: use a dedicated segment-segment algorithm instead.
12    sub_detector: ConvexPolyhedronConvexPolyhedronManifoldGenerator<N>,
13}
14
15impl<N: RealField + Copy> CapsuleCapsuleManifoldGenerator<N> {
16    /// Creates a new collision detector between a concave shape and another shape.
17    pub fn new() -> CapsuleCapsuleManifoldGenerator<N> {
18        CapsuleCapsuleManifoldGenerator {
19            sub_detector: ConvexPolyhedronConvexPolyhedronManifoldGenerator::new(),
20        }
21    }
22
23    fn do_update(
24        &mut self,
25        dispatcher: &dyn ContactDispatcher<N>,
26        m1: &Isometry<N>,
27        g1: &Capsule<N>,
28        proc1: Option<&dyn ContactPreprocessor<N>>,
29        m2: &Isometry<N>,
30        g2: &Capsule<N>,
31        proc2: Option<&dyn ContactPreprocessor<N>>,
32        prediction: &ContactPrediction<N>,
33        manifold: &mut ContactManifold<N>,
34    ) -> bool {
35        let segment1 = g1.segment();
36        let segment2 = g2.segment();
37
38        let mut prediction = prediction.clone();
39        let new_linear_prediction = prediction.linear() + g1.radius + g2.radius;
40        prediction.set_linear(new_linear_prediction);
41
42        // Update all collisions
43        self.sub_detector.generate_contacts(
44            dispatcher,
45            m1,
46            &segment1,
47            Some(&(proc1, &g1.contact_preprocessor())),
48            m2,
49            &segment2,
50            Some(&(proc2, &g2.contact_preprocessor())),
51            &prediction,
52            manifold,
53        )
54    }
55}
56
57impl<N: RealField + Copy> ContactManifoldGenerator<N> for CapsuleCapsuleManifoldGenerator<N> {
58    fn generate_contacts(
59        &mut self,
60        d: &dyn ContactDispatcher<N>,
61        ma: &Isometry<N>,
62        a: &dyn Shape<N>,
63        proc1: Option<&dyn ContactPreprocessor<N>>,
64        mb: &Isometry<N>,
65        b: &dyn Shape<N>,
66        proc2: Option<&dyn ContactPreprocessor<N>>,
67        prediction: &ContactPrediction<N>,
68        manifold: &mut ContactManifold<N>,
69    ) -> bool {
70        if let (Some(cs1), Some(cs2)) = (a.as_shape::<Capsule<N>>(), b.as_shape::<Capsule<N>>()) {
71            self.do_update(d, ma, cs1, proc1, mb, cs2, proc2, prediction, manifold)
72        } else {
73            false
74        }
75    }
76}