ncollide3d/pipeline/narrow_phase/contact_generator/
ball_ball_manifold_generator.rs

1use crate::math::{Isometry, Point};
2use crate::pipeline::narrow_phase::{ContactDispatcher, ContactManifoldGenerator};
3use crate::query::{
4    self, ContactKinematic, ContactManifold, ContactPrediction, ContactPreprocessor,
5    NeighborhoodGeometry,
6};
7use crate::shape::{Ball, FeatureId, Shape};
8use na::RealField;
9use std::marker::PhantomData;
10
11/// Collision detector between two balls.
12#[derive(Clone)]
13pub struct BallBallManifoldGenerator<N: RealField + Copy> {
14    phantom: PhantomData<N>,
15}
16
17impl<N: RealField + Copy> BallBallManifoldGenerator<N> {
18    /// Creates a new persistent collision detector between two balls.
19    #[inline]
20    pub fn new() -> BallBallManifoldGenerator<N> {
21        BallBallManifoldGenerator {
22            phantom: PhantomData,
23        }
24    }
25}
26
27impl<N: RealField + Copy> ContactManifoldGenerator<N> for BallBallManifoldGenerator<N> {
28    fn generate_contacts(
29        &mut self,
30        _: &dyn ContactDispatcher<N>,
31        ma: &Isometry<N>,
32        a: &dyn Shape<N>,
33        proc1: Option<&dyn ContactPreprocessor<N>>,
34        mb: &Isometry<N>,
35        b: &dyn Shape<N>,
36        proc2: Option<&dyn ContactPreprocessor<N>>,
37        prediction: &ContactPrediction<N>,
38        manifold: &mut ContactManifold<N>,
39    ) -> bool {
40        if let (Some(a), Some(b)) = (a.as_shape::<Ball<N>>(), b.as_shape::<Ball<N>>()) {
41            let center_a = Point::from(ma.translation.vector);
42            let center_b = Point::from(mb.translation.vector);
43            if let Some(contact) =
44                query::contact_ball_ball(&center_a, a, &center_b, b, prediction.linear())
45            {
46                let mut kinematic = ContactKinematic::new();
47                kinematic.set_approx1(
48                    FeatureId::Face(0),
49                    Point::origin(),
50                    NeighborhoodGeometry::Point,
51                );
52                kinematic.set_approx2(
53                    FeatureId::Face(0),
54                    Point::origin(),
55                    NeighborhoodGeometry::Point,
56                );
57                kinematic.set_dilation1(a.radius);
58                kinematic.set_dilation2(b.radius);
59
60                let _ = manifold.push(contact, kinematic, Point::origin(), proc1, proc2);
61            }
62
63            true
64        } else {
65            false
66        }
67    }
68}