use std::marker::PhantomData; use alga::linear::Translation; use math::{Isometry, Point}; use geometry::shape::{Ball, Shape}; use geometry::query::{Contact, ContactPrediction}; use geometry::query::contacts_internal; use narrow_phase::{ContactDispatcher, ContactGenerator}; /// Collision detector between two balls. pub struct BallBallContactGenerator { contact: Option>, mat_type: PhantomData, // FIXME: can we avoid this? } impl Clone for BallBallContactGenerator { fn clone(&self) -> BallBallContactGenerator { BallBallContactGenerator { contact: self.contact.clone(), mat_type: PhantomData, } } } impl BallBallContactGenerator { /// Creates a new persistent collision detector between two balls. #[inline] pub fn new() -> BallBallContactGenerator { BallBallContactGenerator { contact: None, mat_type: PhantomData, } } } impl> ContactGenerator for BallBallContactGenerator { fn update( &mut self, _: &ContactDispatcher, ma: &M, a: &Shape, mb: &M, b: &Shape, prediction: &ContactPrediction, ) -> bool { if let (Some(a), Some(b)) = (a.as_shape::>(), b.as_shape::>()) { self.contact = contacts_internal::ball_against_ball( &P::from_coordinates(ma.translation().to_vector()), a, &P::from_coordinates(mb.translation().to_vector()), b, prediction.linear, ); true } else { false } } #[inline] fn num_contacts(&self) -> usize { match self.contact { None => 0, Some(_) => 1, } } #[inline] fn contacts(&self, out_contacts: &mut Vec>) { match self.contact { Some(ref c) => out_contacts.push(c.clone()), None => (), } } }