use std::intrinsics::TypeId; use std::any::Any; use na::{Translate, Cross, Rotation}; use geometry::Contact; use entities::shape::Ball; use narrow_phase::{CollisionDetector, OneShotContactManifoldGenerator}; use math::{Scalar, Point, Vector, Isometry}; /// Generates a contact manifold from an existing single-contact generator. pub fn generate_contact_manifold(m1: &M, g1: &G1, m2: &M, g2: &G2, prediction: N, generator: fn(&M, &G1, &M, &G2, N) -> Option>, out: &mut Vec>) where N: Scalar, P: Point, V: Vector + Translate

+ Cross, AV: Vector, M: Isometry + Rotation, G1: Any, G2: Any { // Do not try to generate a manifold for balls. if g1.get_type_id() == TypeId::of::>() || g2.get_type_id() == TypeId::of::>() { match generator(m1, g1, m2, g2, prediction) { Some(c) => out.push(c), None => { } } } else { let one_contact_generator = AdHocContactGenerator::new(generator, prediction); let mut manifold_generator = OneShotContactManifoldGenerator::new(prediction, one_contact_generator); manifold_generator.update(m1, g1, m2, g2); manifold_generator.colls(out); } } struct AdHocContactGenerator { generator: fn(&M, &G1, &M, &G2, N) -> Option>, prediction: N, contact: Option> } impl AdHocContactGenerator { pub fn new(generator: fn(&M, &G1, &M, &G2, N) -> Option>, prediction: N) -> AdHocContactGenerator { AdHocContactGenerator { generator: generator, prediction: prediction, contact: None } } } impl CollisionDetector for AdHocContactGenerator where N: Clone, P: Clone, V: Clone { fn update(&mut self, m1: &M, g1: &G1, m2: &M, g2: &G2) { self.contact = (self.generator)(m1, g1, m2, g2, self.prediction.clone()); } #[inline] fn num_colls(&self) -> usize { if self.contact.is_some() { 1 } else { 0 } } #[inline] fn colls(&self, out_colls: &mut Vec>) { match self.contact { Some(ref c) => out_colls.push(c.clone()), None => { } } } }