Files
rapier/src/geometry/contact_generator/contact_dispatcher.rs

142 lines
5.5 KiB
Rust

#[cfg(feature = "dim3")]
use crate::geometry::contact_generator::PfmPfmContactManifoldGeneratorWorkspace;
use crate::geometry::contact_generator::{
ContactGenerator, ContactPhase, HeightFieldShapeContactGeneratorWorkspace,
PrimitiveContactGenerator, TrimeshShapeContactGeneratorWorkspace,
};
use crate::geometry::ShapeType;
use std::any::Any;
/// Trait implemented by structures responsible for selecting a collision-detection algorithm
/// for a given pair of shapes.
pub trait ContactDispatcher {
/// Select the collision-detection algorithm for the given pair of primitive shapes.
fn dispatch_primitives(
&self,
shape1: ShapeType,
shape2: ShapeType,
) -> (
PrimitiveContactGenerator,
Option<Box<dyn Any + Send + Sync>>,
);
/// Select the collision-detection algorithm for the given pair of non-primitive shapes.
fn dispatch(
&self,
shape1: ShapeType,
shape2: ShapeType,
) -> (ContactPhase, Option<Box<dyn Any + Send + Sync>>);
}
/// The default contact dispatcher used by Rapier.
pub struct DefaultContactDispatcher;
impl ContactDispatcher for DefaultContactDispatcher {
fn dispatch_primitives(
&self,
shape1: ShapeType,
shape2: ShapeType,
) -> (
PrimitiveContactGenerator,
Option<Box<dyn Any + Send + Sync>>,
) {
match (shape1, shape2) {
(ShapeType::Ball, ShapeType::Ball) => (
PrimitiveContactGenerator {
generate_contacts: super::generate_contacts_ball_ball,
#[cfg(feature = "simd-is-enabled")]
generate_contacts_simd: super::generate_contacts_ball_ball_simd,
..PrimitiveContactGenerator::default()
},
None,
),
(ShapeType::Cuboid, ShapeType::Cuboid) => (
PrimitiveContactGenerator {
generate_contacts: super::generate_contacts_cuboid_cuboid,
..PrimitiveContactGenerator::default()
},
None,
),
// (ShapeType::Polygon, ShapeType::Polygon) => (
// PrimitiveContactGenerator {
// generate_contacts: super::generate_contacts_polygon_polygon,
// ..PrimitiveContactGenerator::default()
// },
// None,
// ),
(ShapeType::Capsule, ShapeType::Capsule) => (
PrimitiveContactGenerator {
generate_contacts: super::generate_contacts_capsule_capsule,
..PrimitiveContactGenerator::default()
},
None,
),
(_, ShapeType::Ball) | (ShapeType::Ball, _) => (
PrimitiveContactGenerator {
generate_contacts: super::generate_contacts_ball_convex,
..PrimitiveContactGenerator::default()
},
None,
),
(ShapeType::Capsule, ShapeType::Cuboid) | (ShapeType::Cuboid, ShapeType::Capsule) => (
PrimitiveContactGenerator {
generate_contacts: super::generate_contacts_cuboid_capsule,
..PrimitiveContactGenerator::default()
},
None,
),
(ShapeType::Triangle, ShapeType::Cuboid) | (ShapeType::Cuboid, ShapeType::Triangle) => {
(
PrimitiveContactGenerator {
generate_contacts: super::generate_contacts_cuboid_triangle,
..PrimitiveContactGenerator::default()
},
None,
)
}
#[cfg(feature = "dim3")]
(ShapeType::Cylinder, _)
| (_, ShapeType::Cylinder)
| (ShapeType::Cone, _)
| (_, ShapeType::Cone)
| (ShapeType::RoundCylinder, _)
| (_, ShapeType::RoundCylinder)
| (ShapeType::Capsule, _)
| (_, ShapeType::Capsule) => (
PrimitiveContactGenerator {
generate_contacts: super::generate_contacts_pfm_pfm,
..PrimitiveContactGenerator::default()
},
Some(Box::new(PfmPfmContactManifoldGeneratorWorkspace::default())),
),
_ => (PrimitiveContactGenerator::default(), None),
}
}
fn dispatch(
&self,
shape1: ShapeType,
shape2: ShapeType,
) -> (ContactPhase, Option<Box<dyn Any + Send + Sync>>) {
match (shape1, shape2) {
(ShapeType::Trimesh, _) | (_, ShapeType::Trimesh) => (
ContactPhase::NearPhase(ContactGenerator {
generate_contacts: super::generate_contacts_trimesh_shape,
..ContactGenerator::default()
}),
Some(Box::new(TrimeshShapeContactGeneratorWorkspace::new())),
),
(ShapeType::HeightField, _) | (_, ShapeType::HeightField) => (
ContactPhase::NearPhase(ContactGenerator {
generate_contacts: super::generate_contacts_heightfield_shape,
..ContactGenerator::default()
}),
Some(Box::new(HeightFieldShapeContactGeneratorWorkspace::new())),
),
_ => {
let (gen, workspace) = self.dispatch_primitives(shape1, shape2);
(ContactPhase::ExactPhase(gen), workspace)
}
}
}
}