ncollide3d/pipeline/narrow_phase/contact_generator/
ball_ball_manifold_generator.rs1use 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#[derive(Clone)]
13pub struct BallBallManifoldGenerator<N: RealField + Copy> {
14 phantom: PhantomData<N>,
15}
16
17impl<N: RealField + Copy> BallBallManifoldGenerator<N> {
18 #[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(¢er_a, a, ¢er_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}