aboutsummaryrefslogtreecommitdiff
path: root/src/geometry
diff options
context:
space:
mode:
Diffstat (limited to 'src/geometry')
-rw-r--r--src/geometry/broad_phase_multi_sap.rs8
-rw-r--r--src/geometry/collider.rs8
-rw-r--r--src/geometry/contact_generator/ball_ball_contact_generator.rs103
-rw-r--r--src/geometry/contact_generator/ball_convex_contact_generator.rs70
-rw-r--r--src/geometry/contact_generator/ball_polygon_contact_generator.rs1
-rw-r--r--src/geometry/contact_generator/capsule_capsule_contact_generator.rs202
-rw-r--r--src/geometry/contact_generator/contact_dispatcher.rs141
-rw-r--r--src/geometry/contact_generator/contact_generator.rs228
-rw-r--r--src/geometry/contact_generator/contact_generator_workspace.rs104
-rw-r--r--src/geometry/contact_generator/cuboid_capsule_contact_generator.rs190
-rw-r--r--src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs156
-rw-r--r--src/geometry/contact_generator/cuboid_polygon_contact_generator.rs1
-rw-r--r--src/geometry/contact_generator/cuboid_triangle_contact_generator.rs171
-rw-r--r--src/geometry/contact_generator/heightfield_shape_contact_generator.rs190
-rw-r--r--src/geometry/contact_generator/mod.rs51
-rw-r--r--src/geometry/contact_generator/pfm_pfm_contact_generator.rs146
-rw-r--r--src/geometry/contact_generator/polygon_polygon_contact_generator.rs156
-rw-r--r--src/geometry/contact_generator/serializable_workspace_tag.rs9
-rw-r--r--src/geometry/contact_generator/trimesh_shape_contact_generator.rs221
-rw-r--r--src/geometry/contact_generator/voxels_shape_contact_generator.rs0
-rw-r--r--src/geometry/contact_pair.rs (renamed from src/geometry/contact.rs)32
-rw-r--r--src/geometry/mod.rs53
-rw-r--r--src/geometry/narrow_phase.rs58
-rw-r--r--src/geometry/polygon.rs2
-rw-r--r--src/geometry/proximity_detector/ball_convex_proximity_detector.rs2
-rw-r--r--src/geometry/proximity_detector/cuboid_cuboid_proximity_detector.rs4
-rw-r--r--src/geometry/proximity_detector/cuboid_triangle_proximity_detector.rs2
-rw-r--r--src/geometry/proximity_detector/trimesh_shape_proximity_detector.rs4
-rw-r--r--src/geometry/proximity_pair.rs (renamed from src/geometry/proximity.rs)0
-rw-r--r--src/geometry/triangle.rs7
-rw-r--r--src/geometry/z_order.rs70
31 files changed, 70 insertions, 2320 deletions
diff --git a/src/geometry/broad_phase_multi_sap.rs b/src/geometry/broad_phase_multi_sap.rs
index 56c05df..4242d77 100644
--- a/src/geometry/broad_phase_multi_sap.rs
+++ b/src/geometry/broad_phase_multi_sap.rs
@@ -1,10 +1,10 @@
-use crate::data::hashmap::HashMap;
use crate::data::pubsub::Subscription;
use crate::dynamics::RigidBodySet;
use crate::geometry::{ColliderHandle, ColliderSet, RemovedCollider};
use crate::math::{Point, Vector, DIM};
use bit_vec::BitVec;
-use buckler::bounding_volume::{BoundingVolume, AABB};
+use eagl::bounding_volume::{BoundingVolume, AABB};
+use eagl::utils::hashmap::HashMap;
use std::cmp::Ordering;
use std::ops::{Index, IndexMut};
@@ -477,8 +477,8 @@ pub struct BroadPhase {
#[cfg_attr(
feature = "serde-serialize",
serde(
- serialize_with = "crate::data::hashmap::serialize_hashmap_capacity",
- deserialize_with = "crate::data::hashmap::deserialize_hashmap_capacity"
+ serialize_with = "eagl::utils::hashmap::serialize_hashmap_capacity",
+ deserialize_with = "eagl::utils::hashmap::deserialize_hashmap_capacity"
)
)]
reporting: HashMap<(u32, u32), bool>, // Workspace
diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs
index 1275358..db418a3 100644
--- a/src/geometry/collider.rs
+++ b/src/geometry/collider.rs
@@ -1,13 +1,13 @@
-use crate::buckler::shape::HalfSpace;
use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet};
+use crate::eagl::shape::HalfSpace;
use crate::geometry::InteractionGroups;
use crate::math::{AngVector, Isometry, Point, Rotation, Vector};
-use buckler::bounding_volume::AABB;
-use buckler::shape::{
+use eagl::bounding_volume::AABB;
+use eagl::shape::{
Ball, Capsule, Cuboid, HeightField, Segment, Shape, ShapeType, TriMesh, Triangle,
};
#[cfg(feature = "dim3")]
-use buckler::shape::{Cone, Cylinder, RoundCylinder};
+use eagl::shape::{Cone, Cylinder, RoundCylinder};
use na::Point3;
use std::ops::Deref;
use std::sync::Arc;
diff --git a/src/geometry/contact_generator/ball_ball_contact_generator.rs b/src/geometry/contact_generator/ball_ball_contact_generator.rs
deleted file mode 100644
index f2ca7af..0000000
--- a/src/geometry/contact_generator/ball_ball_contact_generator.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{Contact, ContactManifoldData, KinematicsCategory};
-use crate::math::{Point, Vector};
-#[cfg(feature = "simd-is-enabled")]
-use {
- crate::geometry::contact_generator::PrimitiveContactGenerationContextSimd,
- crate::geometry::{WBall, WContact},
- crate::math::{Isometry, SimdReal, SIMD_WIDTH},
- simba::simd::SimdValue,
-};
-
-#[cfg(feature = "simd-is-enabled")]
-fn generate_contacts_simd(ball1: &WBall, ball2: &WBall, pos21: &Isometry<SimdReal>) -> WContact {
- let dcenter = ball2.center - ball1.center;
- let center_dist = dcenter.magnitude();
- let normal = dcenter / center_dist;
-
- WContact {
- local_p1: ball1.center + normal * ball1.radius,
- local_p2: pos21 * (ball2.center - normal * ball2.radius),
- local_n1: normal,
- local_n2: pos21 * -normal,
- fid1: [0; SIMD_WIDTH],
- fid2: [0; SIMD_WIDTH],
- dist: center_dist - ball1.radius - ball2.radius,
- }
-}
-
-#[cfg(feature = "simd-is-enabled")]
-pub fn generate_contacts_ball_ball_simd(ctxt: &mut PrimitiveContactGenerationContextSimd) {
- let pos_ba = ctxt.positions2.inverse() * ctxt.positions1;
- let radii_a =
- SimdReal::from(array![|ii| ctxt.shapes1[ii].as_ball().unwrap().radius; SIMD_WIDTH]);
- let radii_b =
- SimdReal::from(array![|ii| ctxt.shapes2[ii].as_ball().unwrap().radius; SIMD_WIDTH]);
-
- let wball_a = WBall::new(Point::origin(), radii_a);
- let wball_b = WBall::new(pos_ba.inverse_transform_point(&Point::origin()), radii_b);
- let contacts = generate_contacts_simd(&wball_a, &wball_b, &pos_ba);
-
- for (i, manifold) in ctxt.manifolds.iter_mut().enumerate() {
- // FIXME: compare the dist before extracting the contact.
- let (contact, local_n1, local_n2) = contacts.extract(i);
- if contact.dist <= ctxt.prediction_distance {
- if manifold.points.len() != 0 {
- manifold.points[0].copy_geometry_from(contact);
- } else {
- manifold.points.push(contact);
- }
-
- manifold.local_n1 = local_n1;
- manifold.local_n2 = local_n2;
- manifold.kinematics.category = KinematicsCategory::PointPoint;
- manifold.kinematics.radius1 = radii_a.extract(i);
- manifold.kinematics.radius2 = radii_b.extract(i);
- ContactManifoldData::update_warmstart_multiplier(manifold);
- } else {
- manifold.points.clear();
- }
-
- manifold.sort_contacts(ctxt.prediction_distance);
- }
-}
-
-pub fn generate_contacts_ball_ball(ctxt: &mut PrimitiveContactGenerationContext) {
- let pos_ba = ctxt.position2.inverse() * ctxt.position1;
- let radius_a = ctxt.shape1.as_ball().unwrap().radius;
- let radius_b = ctxt.shape2.as_ball().unwrap().radius;
-
- let dcenter = pos_ba.inverse_transform_point(&Point::origin()).coords;
- let center_dist = dcenter.magnitude();
- let dist = center_dist - radius_a - radius_b;
-
- if dist < ctxt.prediction_distance {
- let local_n1 = if center_dist != 0.0 {
- dcenter / center_dist
- } else {
- Vector::y()
- };
-
- let local_n2 = pos_ba.inverse_transform_vector(&-local_n1);
- let local_p1 = local_n1 * radius_a;
- let local_p2 = local_n2 * radius_b;
- let contact = Contact::new(local_p1.into(), local_p2.into(), 0, 0, dist);
-
- if ctxt.manifold.points.len() != 0 {
- ctxt.manifold.points[0].copy_geometry_from(contact);
- } else {
- ctxt.manifold.points.push(contact);
- }
-
- ctxt.manifold.local_n1 = local_n1;
- ctxt.manifold.local_n2 = local_n2;
- ctxt.manifold.kinematics.category = KinematicsCategory::PointPoint;
- ctxt.manifold.kinematics.radius1 = radius_a;
- ctxt.manifold.kinematics.radius2 = radius_b;
- ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
- } else {
- ctxt.manifold.points.clear();
- }
-
- ctxt.manifold.sort_contacts(ctxt.prediction_distance);
-}
diff --git a/src/geometry/contact_generator/ball_convex_contact_generator.rs b/src/geometry/contact_generator/ball_convex_contact_generator.rs
deleted file mode 100644
index 88f1912..0000000
--- a/src/geometry/contact_generator/ball_convex_contact_generator.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{Ball, Contact, ContactManifoldData, KinematicsCategory};
-use crate::math::Isometry;
-use buckler::query::PointQuery;
-use na::Unit;
-
-pub fn generate_contacts_ball_convex(ctxt: &mut PrimitiveContactGenerationContext) {
- if let Some(ball1) = ctxt.shape1.as_ball() {
- ctxt.manifold.swap_identifiers();
- do_generate_contacts(ctxt.shape2, ball1, ctxt, true);
- } else if let Some(ball2) = ctxt.shape2.as_ball() {
- do_generate_contacts(ctxt.shape1, ball2, ctxt, false);
- }
-
- ctxt.manifold.sort_contacts(ctxt.prediction_distance);
-}
-
-fn do_generate_contacts<P: ?Sized + PointQuery>(
- point_query1: &P,
- ball2: &Ball,
- ctxt: &mut PrimitiveContactGenerationContext,
- swapped: bool,
-) {
- let position1;
- let position2;
-
- if swapped {
- position1 = ctxt.position2;
- position2 = ctxt.position1;
- } else {
- position1 = ctxt.position1;
- position2 = ctxt.position2;
- }
-
- let local_p2_1 = position1.inverse_transform_point(&position2.translation.vector.into());
- let proj = point_query1.project_local_point(&local_p2_1, cfg!(feature = "dim3"));
- let dpos = local_p2_1 - proj.local_point;
-
- #[allow(unused_mut)] // Because `mut local_n1, mut dist` is needed in 2D but not in 3D.
- if let Some((mut local_n1, mut dist)) = Unit::try_new_and_get(dpos, 0.0) {
- #[cfg(feature = "dim2")]
- if proj.is_inside {
- local_n1 = -local_n1;
- dist = -dist;
- }
-
- if dist <= ball2.radius + ctxt.prediction_distance {
- let local_n2 = position2.inverse_transform_vector(&(position1 * -*local_n1));
- let local_p2 = (local_n2 * ball2.radius).into();
- let contact_point = Contact::new(proj.local_point, local_p2, 0, 0, dist - ball2.radius);
-
- if ctxt.manifold.points.len() != 1 {
- ctxt.manifold.points.clear();
- ctxt.manifold.points.push(contact_point);
- } else {
- // Copy only the geometry so we keep the warmstart impulses.
- ctxt.manifold.points[0].copy_geometry_from(contact_point);
- }
-
- ctxt.manifold.local_n1 = *local_n1;
- ctxt.manifold.local_n2 = local_n2;
- ctxt.manifold.kinematics.category = KinematicsCategory::PlanePoint;
- ctxt.manifold.kinematics.radius1 = 0.0;
- ctxt.manifold.kinematics.radius2 = ball2.radius;
- ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
- } else {
- ctxt.manifold.points.clear();
- }
- }
-}
diff --git a/src/geometry/contact_generator/ball_polygon_contact_generator.rs b/src/geometry/contact_generator/ball_polygon_contact_generator.rs
deleted file mode 100644
index 8b13789..0000000
--- a/src/geometry/contact_generator/ball_polygon_contact_generator.rs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/geometry/contact_generator/capsule_capsule_contact_generator.rs b/src/geometry/contact_generator/capsule_capsule_contact_generator.rs
deleted file mode 100644
index 9090b36..0000000
--- a/src/geometry/contact_generator/capsule_capsule_contact_generator.rs
+++ /dev/null
@@ -1,202 +0,0 @@
-use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{Capsule, Contact, ContactManifold, ContactManifoldData, KinematicsCategory};
-use crate::math::Isometry;
-use crate::math::Vector;
-use approx::AbsDiffEq;
-#[cfg(feature = "dim2")]
-use buckler::shape::SegmentPointLocation;
-use na::Unit;
-
-pub fn generate_contacts_capsule_capsule(ctxt: &mut PrimitiveContactGenerationContext) {
- if let (Some(capsule1), Some(capsule2)) = (ctxt.shape1.as_capsule(), ctxt.shape2.as_capsule()) {
- generate_contacts(
- ctxt.prediction_distance,
- capsule1,
- ctxt.position1,
- capsule2,
- ctxt.position2,
- ctxt.manifold,
- );
- }
-
- ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
- ctxt.manifold.sort_contacts(ctxt.prediction_distance);
-}
-
-#[cfg(feature = "dim2")]
-pub fn generate_contacts<'a>(
- prediction_distance: f32,
- capsule1: &'a Capsule,
- pos1: &'a Isometry<f32>,
- capsule2: &'a Capsule,
- pos2: &'a Isometry<f32>,
- manifold: &mut ContactManifold,
-) {
- // FIXME: the contact kinematics is not correctly set here.
- // We use the common "Point-Plane" kinematics with zero radius everytime.
- // Instead we should select point/point ore point-plane (with non-zero
- // radius for the point) depending on the features involved in the contact.
- let pos12 = pos1.inverse() * pos2;
- let pos21 = pos12.inverse();
-
- let seg1 = capsule1.segment;
- let seg2_1 = capsule2.segment.transformed(&pos12);
- let (loc1, loc2) = buckler::query::details::closest_points_segment_segment_with_locations_nD(
- (&seg1.a, &seg1.b),
- (&seg2_1.a, &seg2_1.b),
- );
-
- // We do this clone to perform contact tracking and transfer impulses.
- // FIXME: find a more efficient way of doing this.
- let old_manifold_points = manifold.points.clone();
- manifold.points.clear();
-
- let swapped = false;
-
- let fid1 = if let SegmentPointLocation::OnVertex(v1) = loc1 {
- v1 as u8 * 2
- } else {
- 1
- };
- let fid2 = if let SegmentPointLocation::OnVertex(v2) = loc2 {
- v2 as u8 * 2
- } else {
- 1
- };
-
- let bcoords1 = loc1.barycentric_coordinates();
- let bcoords2 = loc2.barycentric_coordinates();
- let local_p1 = seg1.a * bcoords1[0] + seg1.b.coords * bcoords1[1];
- let local_p2 = seg2_1.a * bcoords2[0] + seg2_1.b.coords * bcoords2[1];
-
- let local_n1 =
- Unit::try_new(local_p2 - local_p1, f32::default_epsilon()).unwrap_or(Vector::y_axis());
- let dist = (local_p2 - local_p1).dot(&local_n1) - capsule1.radius - capsule2.radius;
-
- if dist <= prediction_distance {
- let local_n2 = pos21 * -local_n1;
- let contact = Contact::new(local_p1, pos21 * local_p2, fid1, fid2, dist);
- manifold.points.push(contact);
-
- manifold.local_n1 = *local_n1;
- manifold.local_n2 = *local_n2;
- manifold.kinematics.category = KinematicsCategory::PlanePoint;
- manifold.kinematics.radius1 = 0.0;
- manifold.kinematics.radius2 = 0.0;
- } else {
- // No contact within tolerance.
- return;
- }
-
- if let (Some(dir1), Some(dir2)) = (seg1.direction(), seg2_1.direction()) {
- if dir1.dot(&dir2).abs() >= crate::utils::COS_FRAC_PI_8
- && dir1.dot(&local_n1).abs() < crate::utils::SIN_FRAC_PI_8
- {
- // Capsules axes are almost parallel and are almost perpendicular to the normal.
- // Find a second contact point.
- if let Some((clip_a, clip_b)) =
- buckler::query::details::clip_segment_segment_with_normal(
- (seg1.a, seg1.b),
- (seg2_1.a, seg2_1.b),
- *local_n1,
- )
- {
- let contact =
- if (clip_a.0 - local_p1).norm_squared() > f32::default_epsilon() * 100.0 {
- // Use clip_a as the second contact.
- Contact::new(
- clip_a.0,
- pos21 * clip_a.1,
- clip_a.2 as u8,
- clip_a.3 as u8,
- (clip_a.1 - clip_a.0).dot(&local_n1),
- )
- } else {
- // Use clip_b as the second contact.
- Contact::new(
- clip_b.0,
- pos21 * clip_b.1,
- clip_b.2 as u8,
- clip_b.3 as u8,
- (clip_b.1 - clip_b.0).dot(&local_n1),
- )
- };
-
- manifold.points.push(contact);
- }
- }
- }
-
- if swapped {
- for point in &mut manifold.points {
- point.local_p1 += manifold.local_n1 * capsule2.radius;
- point.local_p2 += manifold.local_n2 * capsule1.radius;
- point.dist -= capsule1.radius + capsule2.radius;
- }
- } else {
- for point in &mut manifold.points {
- point.local_p1 += manifold.local_n1 * capsule1.radius;
- point.local_p2 += manifold.local_n2 * capsule2.radius;
- point.dist -= capsule1.radius + capsule2.radius;
- }
- }
-
- manifold.match_contacts(&old_manifold_points, swapped);
-}
-
-#[cfg(feature = "dim3")]
-pub fn generate_contacts<'a>(
- prediction_distance: f32,
- capsule1: &'a Capsule,
- pos1: &'a Isometry<f32>,
- capsule2: &'a Capsule,
- pos2: &'a Isometry<f32>,
- manifold: &mut ContactManifold,
-) {
- let pos12 = pos1.inverse() * pos2;
- let pos21 = pos12.inverse();
-
- let seg1 = capsule1.segment;
- let seg2_1 = capsule2.segment.transformed(&pos12);
- let (loc1, loc2) =
- buckler::query::closest_points::closest_points_segment_segment_with_locations_nD(
- (&seg1.a, &seg1.b),
- (&seg2_1.a, &seg2_1.b),
- );
-
- {
- let bcoords1 = loc1.barycentric_coordinates();
- let bcoords2 = loc2.barycentric_coordinates();
- let local_p1 = seg1.a * bcoords1[0] + seg1.b.coords * bcoords1[1];
- let local_p2 = seg2_1.a * bcoords2[0] + seg2_1.b.coords * bcoords2[1];
-
- let local_n1 =
- Unit::try_new(local_p2 - local_p1, f32::default_epsilon()).unwrap_or(Vector::y_axis());
- let dist = (local_p2 - local_p1).dot(&local_n1) - capsule1.radius - capsule2.radius;
-
- if dist <= prediction_distance {
- let local_n2 = pos21 * -local_n1;
- let contact = Contact::new(
- local_p1 + *local_n1 * capsule1.radius,
- pos21 * local_p2 + *local_n2 * capsule2.radius,
- 0,
- 0,
- dist,
- );
-
- if manifold.points.len() != 0 {
- manifold.points[0].copy_geometry_from(contact);
- } else {
- manifold.points.push(contact);
- }
-
- manifold.local_n1 = *local_n1;
- manifold.local_n2 = *local_n2;
- manifold.kinematics.category = KinematicsCategory::PlanePoint;
- manifold.kinematics.radius1 = 0.0;
- manifold.kinematics.radius2 = 0.0;
- } else {
- manifold.points.clear();
- }
- }
-}
diff --git a/src/geometry/contact_generator/contact_dispatcher.rs b/src/geometry/contact_generator/contact_dispatcher.rs
deleted file mode 100644
index 9b247f3..0000000
--- a/src/geometry/contact_generator/contact_dispatcher.rs
+++ /dev/null
@@ -1,141 +0,0 @@
-#[cfg(feature = "dim3")]
-use crate::geometry::contact_generator::PfmPfmContactManifoldGeneratorWorkspace;
-use crate::geometry::contact_generator::{
- ContactGenerator, ContactGeneratorWorkspace, ContactPhase,
- HeightFieldShapeContactGeneratorWorkspace, PrimitiveContactGenerator,
- TriMeshShapeContactGeneratorWorkspace,
-};
-use buckler::shape::ShapeType;
-
-/// 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<ContactGeneratorWorkspace>);
- /// Select the collision-detection algorithm for the given pair of non-primitive shapes.
- fn dispatch(
- &self,
- shape1: ShapeType,
- shape2: ShapeType,
- ) -> (ContactPhase, Option<ContactGeneratorWorkspace>);
-}
-
-/// The default contact dispatcher used by Rapier.
-pub struct DefaultContactDispatcher;
-
-impl ContactDispatcher for DefaultContactDispatcher {
- fn dispatch_primitives(
- &self,
- shape1: ShapeType,
- shape2: ShapeType,
- ) -> (PrimitiveContactGenerator, Option<ContactGeneratorWorkspace>) {
- 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(ContactGeneratorWorkspace::from(
- PfmPfmContactManifoldGeneratorWorkspace::default(),
- )),
- ),
- _ => (PrimitiveContactGenerator::default(), None),
- }
- }
-
- fn dispatch(
- &self,
- shape1: ShapeType,
- shape2: ShapeType,
- ) -> (ContactPhase, Option<ContactGeneratorWorkspace>) {
- match (shape1, shape2) {
- (ShapeType::TriMesh, _) | (_, ShapeType::TriMesh) => (
- ContactPhase::NearPhase(ContactGenerator {
- generate_contacts: super::generate_contacts_trimesh_shape,
- ..ContactGenerator::default()
- }),
- Some(ContactGeneratorWorkspace::from(
- TriMeshShapeContactGeneratorWorkspace::new(),
- )),
- ),
- (ShapeType::HeightField, _) | (_, ShapeType::HeightField) => (
- ContactPhase::NearPhase(ContactGenerator {
- generate_contacts: super::generate_contacts_heightfield_shape,
- ..ContactGenerator::default()
- }),
- Some(ContactGeneratorWorkspace::from(
- HeightFieldShapeContactGeneratorWorkspace::new(),
- )),
- ),
- _ => {
- let (gen, workspace) = self.dispatch_primitives(shape1, shape2);
- (ContactPhase::ExactPhase(gen), workspace)
- }
- }
- }
-}
diff --git a/src/geometry/contact_generator/contact_generator.rs b/src/geometry/contact_generator/contact_generator.rs
deleted file mode 100644
index 06ab265..0000000
--- a/src/geometry/contact_generator/contact_generator.rs
+++ /dev/null
@@ -1,228 +0,0 @@
-use crate::data::MaybeSerializableData;
-use crate::geometry::{
- Collider, ColliderSet, ContactDispatcher, ContactEvent, ContactManifold, ContactPair, Shape,
- ShapeType, SolverFlags,
-};
-use crate::math::Isometry;
-#[cfg(feature = "simd-is-enabled")]
-use crate::math::{SimdReal, SIMD_WIDTH};
-use crate::pipeline::EventHandler;
-
-#[derive(Copy, Clone)]
-pub enum ContactPhase {
- NearPhase(ContactGenerator),
- ExactPhase(PrimitiveContactGenerator),
-}
-
-impl ContactPhase {
- #[inline]
- pub fn generate_contacts(
- self,
- mut context: ContactGenerationContext,
- events: &dyn EventHandler,
- ) {
- let had_contacts_before = context.pair.has_any_active_contact();
-
- match self {
- Self::NearPhase(gen) => (gen.generate_contacts)(&mut context),
- Self::ExactPhase(gen) => {
- // Build the primitive context from the non-primitive context and dispatch.
- let (collider1, collider2, manifold, workspace) = context
- .pair
- .single_manifold(context.colliders, context.solver_flags);
- let mut context2 = PrimitiveContactGenerationContext {
- prediction_distance: context.prediction_distance,
- collider1,
- collider2,
- shape1: collider1.shape(),
- shape2: collider2.shape(),
- position1: collider1.position(),
- position2: collider2.position(),
- manifold,
- workspace,
- };
-
- (gen.generate_contacts)(&mut context2)
- }
- }
-
- if had_contacts_before != context.pair.has_any_active_contact() {
- if had_contacts_before {
- events.handle_contact_event(ContactEvent::Stopped(
- context.pair.pair.collider1,
- context.pair.pair.collider2,
- ));
- } else {
- events.handle_contact_event(ContactEvent::Started(
- context.pair.pair.collider1,
- context.pair.pair.collider2,
- ))
- }
- }
- }
-
- #[cfg(feature = "simd-is-enabled")]
- #[inline]
- pub fn generate_contacts_simd(
- self,
- mut context: ContactGenerationContextSimd,
- events: &dyn EventHandler,
- ) {
- let mut had_contacts_before = [false; SIMD_WIDTH];
-
- for (i, pair) in context.pairs.iter().enumerate() {
- had_contacts_before[i] = pair.has_any_active_contact()
- }
-
- match self {
- Self::NearPhase(gen) => (gen.generate_contacts_simd)(&mut context),
- Self::ExactPhase(gen) => {
- // Build the primitive context from the non-primitive context and dispatch.
- use arrayvec::ArrayVec;
- let mut colliders_arr: ArrayVec<[(&Collider, &Collider); SIMD_WIDTH]> =
- ArrayVec::new();
- let mut manifold_arr: ArrayVec<[&mut ContactManifold; SIMD_WIDTH]> =
- ArrayVec::new();
- let mut workspace_arr: ArrayVec<
- [Option<&mut (dyn MaybeSerializableData)>; SIMD_WIDTH],
- > = ArrayVec::new();
-
- for (pair, solver_flags) in
- context.pairs.iter_mut().zip(context.solver_flags.iter())
- {
- let (collider1, collider2, manifold, workspace) =
- pair.single_manifold(context.colliders, *solver_flags);
- colliders_arr.push((collider1, collider2));
- manifold_arr.push(manifold);
- workspace_arr.push(workspace);
- }
-
- let max_index = colliders_arr.len() - 1;
- let colliders1 = array![|ii| colliders_arr[ii.min(max_index)].0; SIMD_WIDTH];
- let colliders2 = array![|ii| colliders_arr[ii.min(max_index)].1; SIMD_WIDTH];
-
- let mut context2 = PrimitiveContactGenerationContextSimd {
- prediction_distance: context.prediction_distance,
- colliders1,
- colliders2,
- shapes1: array![|ii| colliders1[ii].shape(); SIMD_WIDTH],
- shapes2: array![|ii| colliders2[ii].shape(); SIMD_WIDTH],
- positions1: &Isometry::from(
- array![|ii| *colliders1[ii].position(); SIMD_WIDTH],
- ),
- p