aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/contact_generator
diff options
context:
space:
mode:
Diffstat (limited to 'src/geometry/contact_generator')
-rw-r--r--src/geometry/contact_generator/ball_ball_contact_generator.rs6
-rw-r--r--src/geometry/contact_generator/ball_convex_contact_generator.rs18
-rw-r--r--src/geometry/contact_generator/capsule_capsule_contact_generator.rs33
-rw-r--r--src/geometry/contact_generator/cuboid_capsule_contact_generator.rs37
-rw-r--r--src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs23
-rw-r--r--src/geometry/contact_generator/cuboid_triangle_contact_generator.rs38
-rw-r--r--src/geometry/contact_generator/heightfield_shape_contact_generator.rs14
-rw-r--r--src/geometry/contact_generator/mod.rs30
-rw-r--r--src/geometry/contact_generator/pfm_pfm_contact_generator.rs30
-rw-r--r--src/geometry/contact_generator/polygon_polygon_contact_generator.rs175
-rw-r--r--src/geometry/contact_generator/trimesh_shape_contact_generator.rs18
11 files changed, 123 insertions, 299 deletions
diff --git a/src/geometry/contact_generator/ball_ball_contact_generator.rs b/src/geometry/contact_generator/ball_ball_contact_generator.rs
index 96ac235..7122998 100644
--- a/src/geometry/contact_generator/ball_ball_contact_generator.rs
+++ b/src/geometry/contact_generator/ball_ball_contact_generator.rs
@@ -1,5 +1,5 @@
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{Contact, KinematicsCategory};
+use crate::geometry::{Contact, ContactManifoldData, KinematicsCategory};
use crate::math::{Point, Vector};
#[cfg(feature = "simd-is-enabled")]
use {
@@ -53,7 +53,7 @@ pub fn generate_contacts_ball_ball_simd(ctxt: &mut PrimitiveContactGenerationCon
manifold.kinematics.category = KinematicsCategory::PointPoint;
manifold.kinematics.radius1 = radii_a.extract(i);
manifold.kinematics.radius2 = radii_b.extract(i);
- manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(manifold);
} else {
manifold.points.clear();
}
@@ -94,7 +94,7 @@ pub fn generate_contacts_ball_ball(ctxt: &mut PrimitiveContactGenerationContext)
ctxt.manifold.kinematics.category = KinematicsCategory::PointPoint;
ctxt.manifold.kinematics.radius1 = radius_a;
ctxt.manifold.kinematics.radius2 = radius_b;
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
} else {
ctxt.manifold.points.clear();
}
diff --git a/src/geometry/contact_generator/ball_convex_contact_generator.rs b/src/geometry/contact_generator/ball_convex_contact_generator.rs
index 69bc5e3..88f1912 100644
--- a/src/geometry/contact_generator/ball_convex_contact_generator.rs
+++ b/src/geometry/contact_generator/ball_convex_contact_generator.rs
@@ -1,8 +1,8 @@
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{Ball, Contact, KinematicsCategory};
+use crate::geometry::{Ball, Contact, ContactManifoldData, KinematicsCategory};
use crate::math::Isometry;
+use buckler::query::PointQuery;
use na::Unit;
-use ncollide::query::PointQuery;
pub fn generate_contacts_ball_convex(ctxt: &mut PrimitiveContactGenerationContext) {
if let Some(ball1) = ctxt.shape1.as_ball() {
@@ -15,7 +15,7 @@ pub fn generate_contacts_ball_convex(ctxt: &mut PrimitiveContactGenerationContex
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
}
-fn do_generate_contacts<P: ?Sized + PointQuery<f32>>(
+fn do_generate_contacts<P: ?Sized + PointQuery>(
point_query1: &P,
ball2: &Ball,
ctxt: &mut PrimitiveContactGenerationContext,
@@ -33,12 +33,8 @@ fn do_generate_contacts<P: ?Sized + PointQuery<f32>>(
}
let local_p2_1 = position1.inverse_transform_point(&position2.translation.vector.into());
-
- // TODO: add a `project_local_point` to the PointQuery trait to avoid
- // the identity isometry.
- let proj =
- point_query1.project_point(&Isometry::identity(), &local_p2_1, cfg!(feature = "dim3"));
- let dpos = local_p2_1 - proj.point;
+ 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) {
@@ -51,8 +47,8 @@ fn do_generate_contacts<P: ?Sized + PointQuery<f32>>(
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);
- let contact_point = Contact::new(proj.point, local_p2, 0, 0, dist - ball2.radius);
if ctxt.manifold.points.len() != 1 {
ctxt.manifold.points.clear();
ctxt.manifold.points.push(contact_point);
@@ -66,7 +62,7 @@ fn do_generate_contacts<P: ?Sized + PointQuery<f32>>(
ctxt.manifold.kinematics.category = KinematicsCategory::PlanePoint;
ctxt.manifold.kinematics.radius1 = 0.0;
ctxt.manifold.kinematics.radius2 = ball2.radius;
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
} else {
ctxt.manifold.points.clear();
}
diff --git a/src/geometry/contact_generator/capsule_capsule_contact_generator.rs b/src/geometry/contact_generator/capsule_capsule_contact_generator.rs
index 3104496..9090b36 100644
--- a/src/geometry/contact_generator/capsule_capsule_contact_generator.rs
+++ b/src/geometry/contact_generator/capsule_capsule_contact_generator.rs
@@ -1,11 +1,11 @@
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{Capsule, Contact, ContactManifold, KinematicsCategory};
+use crate::geometry::{Capsule, Contact, ContactManifold, ContactManifoldData, KinematicsCategory};
use crate::math::Isometry;
use crate::math::Vector;
use approx::AbsDiffEq;
-use na::Unit;
#[cfg(feature = "dim2")]
-use ncollide::shape::SegmentPointLocation;
+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()) {
@@ -19,7 +19,7 @@ pub fn generate_contacts_capsule_capsule(ctxt: &mut PrimitiveContactGenerationCo
);
}
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
}
@@ -41,7 +41,7 @@ pub fn generate_contacts<'a>(
let seg1 = capsule1.segment;
let seg2_1 = capsule2.segment.transformed(&pos12);
- let (loc1, loc2) = ncollide::query::closest_points_segment_segment_with_locations_nD(
+ let (loc1, loc2) = buckler::query::details::closest_points_segment_segment_with_locations_nD(
(&seg1.a, &seg1.b),
(&seg2_1.a, &seg2_1.b),
);
@@ -94,11 +94,13 @@ pub fn generate_contacts<'a>(
{
// Capsules axes are almost parallel and are almost perpendicular to the normal.
// Find a second contact point.
- if let Some((clip_a, clip_b)) = crate::geometry::clip_segments_with_normal(
- (seg1.a, seg1.b),
- (seg2_1.a, seg2_1.b),
- *local_n1,
- ) {
+ 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.
@@ -139,7 +141,7 @@ pub fn generate_contacts<'a>(
}
}
- super::match_contacts(manifold, &old_manifold_points, swapped);
+ manifold.match_contacts(&old_manifold_points, swapped);
}
#[cfg(feature = "dim3")]
@@ -156,10 +158,11 @@ pub fn generate_contacts<'a>(
let seg1 = capsule1.segment;
let seg2_1 = capsule2.segment.transformed(&pos12);
- let (loc1, loc2) = ncollide::query::closest_points_segment_segment_with_locations_nD(
- (&seg1.a, &seg1.b),
- (&seg2_1.a, &seg2_1.b),
- );
+ 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();
diff --git a/src/geometry/contact_generator/cuboid_capsule_contact_generator.rs b/src/geometry/contact_generator/cuboid_capsule_contact_generator.rs
index 3fd4a17..9f5d856 100644
--- a/src/geometry/contact_generator/cuboid_capsule_contact_generator.rs
+++ b/src/geometry/contact_generator/cuboid_capsule_contact_generator.rs
@@ -1,11 +1,12 @@
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-#[cfg(feature = "dim3")]
-use crate::geometry::PolyhedronFace;
-use crate::geometry::{cuboid, sat, Capsule, ContactManifold, Cuboid, KinematicsCategory};
-#[cfg(feature = "dim2")]
-use crate::geometry::{CuboidFeature, CuboidFeatureFace};
+use crate::geometry::{Capsule, ContactManifold, ContactManifoldData, Cuboid, KinematicsCategory};
use crate::math::Isometry;
use crate::math::Vector;
+use buckler::query::sat;
+#[cfg(feature = "dim3")]
+use buckler::shape::PolyhedronFeature;
+#[cfg(feature = "dim2")]
+use buckler::shape::{CuboidFeature, CuboidFeatureFace};
pub fn generate_contacts_cuboid_capsule(ctxt: &mut PrimitiveContactGenerationContext) {
if let (Some(cube1), Some(capsule2)) = (ctxt.shape1.as_cuboid(), ctxt.shape2.as_capsule()) {
@@ -18,7 +19,7 @@ pub fn generate_contacts_cuboid_capsule(ctxt: &mut PrimitiveContactGenerationCon
ctxt.manifold,
false,
);
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
} else if let (Some(capsule1), Some(cube2)) =
(ctxt.shape1.as_capsule(), ctxt.shape2.as_cuboid())
{
@@ -31,7 +32,7 @@ pub fn generate_contacts_cuboid_capsule(ctxt: &mut PrimitiveContactGenerationCon
ctxt.manifold,
true,
);
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
}
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
}
@@ -61,7 +62,8 @@ pub fn generate_contacts<'a>(
* Point-Face cases.
*
*/
- let sep1 = sat::cube_support_map_find_local_separating_normal_oneway(cube1, &segment2, &pos12);
+ let sep1 =
+ sat::cuboid_support_map_find_local_separating_normal_oneway(cube1, &segment2, &pos12);
if sep1.0 > capsule2.radius + prediction_distance {
manifold.points.clear();
return;
@@ -84,8 +86,7 @@ pub fn generate_contacts<'a>(
#[cfg(feature = "dim2")]
let sep3 = (-f32::MAX, Vector::x()); // This case does not exist in 2D.
#[cfg(feature = "dim3")]
- let sep3 =
- sat::cube_segment_find_local_separating_edge_twoway(cube1, &segment2, &pos12, &pos21);
+ let sep3 = sat::cuboid_segment_find_local_separating_edge_twoway(cube1, &segment2, &pos12);
if sep3.0 > capsule2.radius + prediction_distance {
manifold.points.clear();
return;
@@ -118,20 +119,20 @@ pub fn generate_contacts<'a>(
{
if swapped_reference {
feature1 = CuboidFeatureFace::from(segment2);
- feature2 = cuboid::support_face(cube1, pos21 * -best_sep.1);
+ feature2 = cube1.support_face(pos21 * -best_sep.1);
} else {
- feature1 = cuboid::support_face(cube1, best_sep.1);
+ feature1 = cube1.support_face(best_sep.1);
feature2 = CuboidFeatureFace::from(segment2);
}
}
#[cfg(feature = "dim3")]
{
if swapped_reference {
- feature1 = PolyhedronFace::from(segment2);
- feature2 = cuboid::polyhedron_support_face(cube1, pos21 * -best_sep.1);
+ feature1 = PolyhedronFeature::from(segment2);
+ feature2 = cube1.polyhedron_support_face(pos21 * -best_sep.1);
} else {
- feature1 = cuboid::polyhedron_support_face(cube1, best_sep.1);
- feature2 = PolyhedronFace::from(segment2);
+ feature1 = cube1.polyhedron_support_face(best_sep.1);
+ feature2 = PolyhedronFeature::from(segment2);
}
}
@@ -156,7 +157,7 @@ pub fn generate_contacts<'a>(
manifold,
);
#[cfg(feature = "dim3")]
- PolyhedronFace::contacts(
+ PolyhedronFeature::contacts(
prediction_distance + capsule2.radius,
&feature1,
&best_sep.1,
@@ -185,5 +186,5 @@ pub fn generate_contacts<'a>(
}
// Transfer impulses.
- super::match_contacts(manifold, &old_manifold_points, swapped ^ swapped_reference);
+ manifold.match_contacts(&old_manifold_points, swapped ^ swapped_reference);
}
diff --git a/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs b/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs
index 5be5af3..1d750ef 100644
--- a/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs
+++ b/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs
@@ -1,9 +1,10 @@
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{cuboid, sat, ContactManifold, CuboidFeature, KinematicsCategory};
+use crate::geometry::{ContactManifold, ContactManifoldData, KinematicsCategory};
use crate::math::Isometry;
#[cfg(feature = "dim2")]
use crate::math::Vector;
-use ncollide::shape::Cuboid;
+use buckler::query::sat;
+use buckler::shape::{Cuboid, CuboidFeature};
pub fn generate_contacts_cuboid_cuboid(ctxt: &mut PrimitiveContactGenerationContext) {
if let (Some(cube1), Some(cube2)) = (ctxt.shape1.as_cuboid(), ctxt.shape2.as_cuboid()) {
@@ -19,15 +20,15 @@ pub fn generate_contacts_cuboid_cuboid(ctxt: &mut PrimitiveContactGenerationCont
unreachable!()
}
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
}
pub fn generate_contacts<'a>(
prediction_distance: f32,
- mut cube1: &'a Cuboid<f32>,
+ mut cube1: &'a Cuboid,
mut pos1: &'a Isometry<f32>,
- mut cube2: &'a Cuboid<f32>,
+ mut cube2: &'a Cuboid,
mut pos2: &'a Isometry<f32>,
manifold: &mut ContactManifold,
) {
@@ -43,13 +44,13 @@ pub fn generate_contacts<'a>(
* Point-Face
*
*/
- let sep1 = sat::cuboid_cuboid_find_local_separating_normal_oneway(cube1, cube2, &pos12, &pos21);
+ let sep1 = sat::cuboid_cuboid_find_local_separating_normal_oneway(cube1, cube2, &pos12);
if sep1.0 > prediction_distance {
manifold.points.clear();
return;
}
- let sep2 = sat::cuboid_cuboid_find_local_separating_normal_oneway(cube2, cube1, &pos21, &pos12);
+ let sep2 = sat::cuboid_cuboid_find_local_separating_normal_oneway(cube2, cube1, &pos21);
if sep2.0 > prediction_distance {
manifold.points.clear();
return;
@@ -63,7 +64,7 @@ pub fn generate_contacts<'a>(
#[cfg(feature = "dim2")]
let sep3 = (-f32::MAX, Vector::x()); // This case does not exist in 2D.
#[cfg(feature = "dim3")]
- let sep3 = sat::cuboid_cuboid_find_local_separating_edge_twoway(cube1, cube2, &pos12, &pos21);
+ let sep3 = sat::cuboid_cuboid_find_local_separating_edge_twoway(cube1, cube2, &pos12);
if sep3.0 > prediction_distance {
manifold.points.clear();
return;
@@ -97,8 +98,8 @@ pub fn generate_contacts<'a>(
// Now the reference feature is from `cube1` and the best separation is `best_sep`.
// Everything must be expressed in the local-space of `cube1` for contact clipping.
- let feature1 = cuboid::support_feature(cube1, best_sep.1);
- let mut feature2 = cuboid::support_feature(cube2, pos21 * -best_sep.1);
+ let feature1 = cube1.support_feature(best_sep.1);
+ let mut feature2 = cube2.support_feature(pos21 * -best_sep.1);
feature2.transform_by(&pos12);
match (&feature1, &feature2) {
@@ -151,5 +152,5 @@ pub fn generate_contacts<'a>(
manifold.kinematics.radius2 = 0.0;
// Transfer impulses.
- super::match_contacts(manifold, &old_manifold_points, swapped);
+ manifold.match_contacts(&old_manifold_points, swapped);
}
diff --git a/src/geometry/contact_generator/cuboid_triangle_contact_generator.rs b/src/geometry/contact_generator/cuboid_triangle_contact_generator.rs
index 562d7d6..06dc6f0 100644
--- a/src/geometry/contact_generator/cuboid_triangle_contact_generator.rs
+++ b/src/geometry/contact_generator/cuboid_triangle_contact_generator.rs
@@ -1,13 +1,11 @@
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-#[cfg(feature = "dim3")]
-use crate::geometry::PolyhedronFace;
-use crate::geometry::{cuboid, sat, ContactManifold, Cuboid, KinematicsCategory, Triangle};
+use crate::geometry::{ContactManifold, ContactManifoldData, Cuboid, KinematicsCategory, Triangle};
use crate::math::Isometry;
#[cfg(feature = "dim2")]
-use crate::{
- geometry::{triangle, CuboidFeature},
- math::Vector,
-};
+use crate::{buckler::shape::CuboidFeature, geometry::triangle, math::Vector};
+use buckler::query::sat;
+#[cfg(feature = "dim3")]
+use buckler::shape::PolyhedronFeature;
pub fn generate_contacts_cuboid_triangle(ctxt: &mut PrimitiveContactGenerationContext) {
if let (Some(cube1), Some(triangle2)) = (ctxt.shape1.as_cuboid(), ctxt.shape2.as_triangle()) {
@@ -20,7 +18,7 @@ pub fn generate_contacts_cuboid_triangle(ctxt: &mut PrimitiveContactGenerationCo
ctxt.manifold,
false,
);
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
} else if let (Some(triangle1), Some(cube2)) =
(ctxt.shape1.as_triangle(), ctxt.shape2.as_cuboid())
{
@@ -33,7 +31,7 @@ pub fn generate_contacts_cuboid_triangle(ctxt: &mut PrimitiveContactGenerationCo
ctxt.manifold,
true,
);
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
}
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
}
@@ -61,7 +59,8 @@ pub fn generate_contacts<'a>(
* Point-Face cases.
*
*/
- let sep1 = sat::cube_support_map_find_local_separating_normal_oneway(cube1, triangle2, &pos12);
+ let sep1 =
+ sat::cuboid_support_map_find_local_separating_normal_oneway(cube1, triangle2, &pos12);
if sep1.0 > prediction_distance {
manifold.points.clear();
return;
@@ -81,8 +80,7 @@ pub fn generate_contacts<'a>(
#[cfg(feature = "dim2")]
let sep3 = (-f32::MAX, Vector::x()); // This case does not exist in 2D.
#[cfg(feature = "dim3")]
- let sep3 =
- sat::cube_triangle_find_local_separating_edge_twoway(cube1, triangle2, &pos12, &pos21);
+ let sep3 = sat::cuboid_triangle_find_local_separating_edge_twoway(cube1, triangle2, &pos12);
if sep3.0 > prediction_distance {
manifold.points.clear();
return;
@@ -115,20 +113,20 @@ pub fn generate_contacts<'a>(
{
if swapped_reference {
feature1 = triangle::support_face(triangle2, best_sep.1);
- feature2 = cuboid::support_face(cube1, pos21 * -best_sep.1);
+ feature2 = cube1.support_face(pos21 * -best_sep.1);
} else {
- feature1 = cuboid::support_face(cube1, best_sep.1);
+ feature1 = cube1.support_face(best_sep.1);
feature2 = triangle::support_face(triangle2, pos21 * -best_sep.1);
}
}
#[cfg(feature = "dim3")]
{
if swapped_reference {
- feature1 = PolyhedronFace::from(*triangle2);
- feature2 = cuboid::polyhedron_support_face(cube1, pos21 * -best_sep.1);
+ feature1 = PolyhedronFeature::from(*triangle2);
+ feature2 = cube1.polyhedron_support_face(pos21 * -best_sep.1);
} else {
- feature1 = cuboid::polyhedron_support_face(cube1, best_sep.1);
- feature2 = PolyhedronFace::from(*triangle2);
+ feature1 = cube1.polyhedron_support_face(best_sep.1);
+ feature2 = PolyhedronFeature::from(*triangle2);
}
}
@@ -153,7 +151,7 @@ pub fn generate_contacts<'a>(
manifold,
);
#[cfg(feature = "dim3")]
- PolyhedronFace::contacts(
+ PolyhedronFeature::contacts(
prediction_distance,
&feature1,
&best_sep.1,
@@ -169,5 +167,5 @@ pub fn generate_contacts<'a>(
manifold.kinematics.radius2 = 0.0;
// Transfer impulses.
- super::match_contacts(manifold, &old_manifold_points, swapped ^ swapped_reference);
+ manifold.match_contacts(&old_manifold_points, swapped ^ swapped_reference);
}
diff --git a/src/geometry/contact_generator/heightfield_shape_contact_generator.rs b/src/geometry/contact_generator/heightfield_shape_contact_generator.rs
index 70360c9..358ac84 100644
--- a/src/geometry/contact_generator/heightfield_shape_contact_generator.rs
+++ b/src/geometry/contact_generator/heightfield_shape_contact_generator.rs
@@ -1,3 +1,4 @@
+use crate::buckler::bounding_volume::BoundingVolume;
use crate::data::hashmap::{Entry, HashMap};
use crate::data::MaybeSerializableData;
use crate::geometry::contact_generator::{
@@ -6,8 +7,7 @@ use crate::geometry::contact_generator::{
};
#[cfg(feature = "dim2")]
use crate::geometry::Capsule;
-use crate::geometry::{Collider, ContactManifold, HeightField, Shape};
-use crate::ncollide::bounding_volume::BoundingVolume;
+use crate::geometry::{Collider, ContactManifold, ContactManifoldData, HeightField, Shape};
#[cfg(feature = "serde-serialize")]
use erased_serde::Serialize;
@@ -88,7 +88,7 @@ fn do_generate_contacts(
let solver_flags = ctxt.solver_flags;
let shape_type2 = collider2.shape().shape_type();
- heightfield1.map_elements_in_local_aabb(&ls_aabb2, &mut |i, part1, _| {
+ heightfield1.map_elements_in_local_aabb(&ls_aabb2, &mut |i, part1| {
let position1 = collider1.position();
#[cfg(feature = "dim2")]
let sub_shape1 = Capsule::new(part1.a, part1.b, 0.0); // TODO: use a segment instead.
@@ -113,15 +113,13 @@ fn do_generate_contacts(
timestamp: new_timestamp,
workspace: workspace2,
};
- let manifold = ContactManifold::with_subshape_indices(
+ let manifold_data = ContactManifoldData::from_colliders(
coll_pair,
collider1,
collider2,
- i,
- 0,
solver_flags,
);
- manifolds.push(manifold);
+ manifolds.push(ContactManifold::with_data((i, 0), manifold_data));
entry.insert(sub_detector)
}
@@ -142,7 +140,7 @@ fn do_generate_contacts(
let manifold = &mut manifolds[sub_detector.manifold_id];
- let mut ctxt2 = if coll_pair.collider1 != manifold.pair.collider1 {
+ let mut ctxt2 = if coll_pair.collider1 != manifold.data.pair.collider1 {
PrimitiveContactGenerationContext {
prediction_distance,
collider1: collider2,
diff --git a/src/geometry/contact_generator/mod.rs b/src/geometry/contact_generator/mod.rs
index 9b14711..f539d7a 100644
--- a/src/geometry/contact_generator/mod.rs
+++ b/src/geometry/contact_generator/mod.rs
@@ -28,10 +28,6 @@ pub use self::trimesh_shape_contact_generator::{
generate_contacts_trimesh_shape, TrimeshShapeContactGeneratorWorkspace,
};
-pub(crate) use self::polygon_polygon_contact_generator::clip_segments;
-#[cfg(feature = "dim2")]
-pub(crate) use self::polygon_polygon_contact_generator::clip_segments_with_normal;
-
pub(self) use self::serializable_workspace_tag::WorkspaceSerializationTag;
mod ball_ball_contact_generator;
@@ -53,29 +49,3 @@ mod serializable_workspace_tag;
mod trimesh_shape_contact_generator;
use crate::geometry::{Contact, ContactManifold};
-
-pub(crate) fn match_contacts(
- manifold: &mut ContactManifold,
- old_contacts: &[Contact],
- swapped: bool,
-) {
- for contact in &mut manifold.points {
- if !swapped {
- for old_contact in old_contacts {
- if contact.fid1 == old_contact.fid1 && contact.fid2 == old_contact.fid2 {
- // Transfer impulse cache.
- contact.impulse = old_contact.impulse;
- contact.tangent_impulse = old_contact.tangent_impulse;
- }
- }
- } else {
- for old_contact in old_contacts {
- if contact.fid1 == old_contact.fid2 && contact.fid2 == old_contact.fid1 {
- // Transfer impulse cache.
- contact.impulse = old_contact.impulse;
- contact.tangent_impulse = old_contact.tangent_impulse;
- }
- }
- }
- }
-}
diff --git a/src/geometry/contact_generator/pfm_pfm_contact_generator.rs b/src/geometry/contact_generator/pfm_pfm_contact_generator.rs
index 5bc213e..721d5dc 100644
--- a/src/geometry/contact_generator/pfm_pfm_contact_generator.rs
+++ b/src/geometry/contact_generator/pfm_pfm_contact_generator.rs
@@ -1,12 +1,15 @@
use crate::data::MaybeSerializableData;
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{KinematicsCategory, PolygonalFeatureMap, PolyhedronFace};
+use crate::geometry::{ContactManifoldData, KinematicsCategory};
use crate::math::{Isometry, Vector};
+use buckler::query::{
+ self,
+ gjk::{GJKResult, VoronoiSimplex},
+};
+use buckler::shape::{PolygonalFeatureMap, PolyhedronFeature};
#[cfg(feature = "serde-serialize")]
use erased_serde::Serialize;
use na::Unit;
-use ncollide::query;
-use ncollide::query::algorithms::{gjk::GJKResult, VoronoiSimplex};
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Clone)]
@@ -15,12 +18,12 @@ pub struct PfmPfmContactManifoldGeneratorWorkspace {
feature = "serde-serialize",
serde(skip, default = "VoronoiSimplex::new")
)]
- simplex: VoronoiSimplex<f32>,
+ simplex: VoronoiSimplex,
last_gjk_dir: Option<Unit<Vector<f32>>>,
#[cfg_attr(feature = "serde-serialize", serde(skip))]
- feature1: PolyhedronFace,
+ feature1: PolyhedronFeature,
#[cfg_attr(feature = "serde-serialize", serde(skip))]
- feature2: PolyhedronFace,
+ feature2: PolyhedronFeature,
}
impl Default for PfmPfmContactManifoldGeneratorWorkspace {
@@ -28,8 +31,8 @@ impl Default for PfmPfmContactManifoldGeneratorWorkspace {
Self {
simplex: VoronoiSimplex::new(),
last_gjk_dir: None,
- feature1: PolyhedronFace::new(),
- feature2: PolyhedronFace::new(),
+ feature1: PolyhedronFeature::new(),
+ feature2: PolyhedronFeature::new(),
}
}
}
@@ -40,7 +43,7 @@ pub fn generate_contacts_pfm_pfm(ctxt: &mut PrimitiveContactGenerationContext) {
ctxt.shape2.as_polygonal_feature_map(),
) {
do_generate_contacts(pfm1, border_radius1, pfm2, border_radius2, ctxt);
- ctxt.manifold.update_warmstart_multiplier();
+ ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
}
}
@@ -73,10 +76,9 @@ fn do_generate_contacts(
.expect("Invalid workspace type, expected a PfmPfmContactManifoldGeneratorWorkspace.");
let total_prediction = ctxt.prediction_distance + border_radius1 + border_radius2;
- let contact = query::contact_support_map_support_map_with_params(
- &Isometry::identity(),
- pfm1,
+ let contact = query::contact::contact_support_map_support_map_with_params(
&pos12,
+ pfm1,
pfm2,
total_prediction,
&mut workspace.simplex,
@@ -95,7 +97,7 @@ fn do_generate_contacts(
pfm2.local_support_feature(&normal2, &mut workspace.feature2);
workspace.feature2.transform_by(&pos12);
- PolyhedronFace::contacts(
+ PolyhedronFeature::contacts(
total_prediction,
&workspace.feature1,
&normal1,
@@ -126,7 +128,7 @@ fn do_generate_contacts(
}
// Transfer impulses.
- super::match_contacts(&mut ctxt.manifold, &old_manifold_points, false);
+ ctxt.manifold.match_contacts(&old_manifold_points, false);
}
impl MaybeSerializableData for PfmPfmContactManifoldGeneratorWorkspace {
diff --git a/src/geometry/contact_generator/polygon_polygon_contact_generator.rs b/src/geometry/contact_generator/polygon_polygon_contact_generator.rs
index 0e7543d..7e80fe7 100644
--- a/src/geometry/contact_generator/polygon_polygon_contact_generator.rs
+++ b/src/geometry/contact_generator/polygon_polygon_contact_generator.rs
@@ -1,10 +1,13 @@
#![allow(dead_code)] // TODO: remove this once we support polygons.
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
-use crate::geometry::{sat, Contact, ContactManifold, KinematicsCategory, Polygon};
+use crate::geometry::{
+ sat, Contact, ContactData, ContactManifold, ContactManifoldData, KinematicsCategory, Polygon,
+};
use crate::math::{Isometry, Point};
#[cfg(feature = "dim2")]
use crate::{math::Vector, utils};
+use buckler::query;
pub fn generate_contacts_polygon_polygon(_ctxt: &mut PrimitiveContactGenerationContext) {
unimplemented!()
@@ -16,7 +19,7 @@ pub fn generate_contacts_polygon_polygon(_ctxt: &mut PrimitiveContactGenerationC
// &ctxt.position2,
// ctxt.manifold,
// );
- // ctxt.manifold.update_warmstart_multiplier();
+ // ContactManifoldData::update_warmstart_multiplier(ctxt.manifold);
// } else {
// unreachable!()
// }
@@ -75,12 +78,12 @@ fn generate_contacts<'a>(
m12 * p2.vertices[support_face2],
m12 * p2.vertices[(support_face2 + 1) % len2],
);
- if let Some((clip_a, clip_b)) = clip_segments(seg1, seg2) {
+ if let Some((clip_a, clip_b)) = query::details::clip_segment_segment(seg1, seg2) {
let dist_a = (clip_a.1 - clip_a.0).dot(&local_n1);
let dist_b = (clip_b.1 - clip_b.0).dot(&local_n1);
- let mut impulses_a = (0.0, Contact::zero_tangent_impulse());
- let mut impulses_b = (0.0, Contact::zero_tangent_impulse());
+ let mut data_a = ContactData::default();
+ let mut data_b = ContactData::default();
let fids_a = (
((support_face1 * 2 + clip_a.2) % (len1 * 2)) as u8,
@@ -111,26 +114,15 @@ fn generate_contacts<'a>(
}
if fids_a == original_fids_a {
- impulses_a = (
- manifold.points[0].impulse,
- manifold.points[0].tangent_impulse,
- );
+ data_a = manifold.points[0].data;
} else if fids_a == original_fids_b {
- impulses_a = (
- manifold.points[1].impulse,
- manifold.points[1].tangent_impulse,
- );
+ data_a = manifold.points[1].data;
}
+
if fids_b == original_fids_a {
- impulses_b = (
- manifold.points[0].impulse,
- manifold.points[0].tangent_impulse,
- );
+ data_b = manifold.points[0].data;
} else if fids_b == original_fids_b {
- impulses_b = (
- manifold.points[1].impulse,
- manifold.points[1].tangent_impulse,
- );
+ data_b = manifold.points[1].data;
}
}
@@ -138,21 +130,19 @@ fn generate_contacts<'a>(
manifold.points.push(Contact {
local_p1: clip_a.0,
local_p2: m21 * clip_a.1,
- impulse: impulses_a.0,
- tangent_impulse: impulses_a.1,
fid1: fids_a.0,
fid2: fids_a.1,
dist: dist_a,
+ data: data_a,
});
manifold.points.push(Contact {
local_p1: clip_b.0,
local_p2: m21 * clip_b.1,
- impulse: impulses_b.0,
- tangent_impulse: impulses_b.1,
fid1: fids_b.0,
fid2: fids_b.1,
dist: dist_b,
+ data: data_b,
});
manifold.local_n1 = local_n1;
@@ -164,138 +154,3 @@ fn generate_contacts<'a>(
manifold.points.clear();
}
}
-
-// Features in clipping points are:
-// 0 = First vertex.
-// 1 = On the face.
-// 2 = Second vertex.
-pub(crate) type ClippingPoints = (Point<f32>, Point<f32>, usize, usize);
-
-#[cfg(feature = "dim2")]
-pub(crate) fn clip_segments_with_normal(
- mut seg1: (Point<f32>, Point<f32>),
- mut seg2: (Point<f32>, Point<f32>),
- normal: Vector<f32>,
-) -> Option<(ClippingPoints, ClippingPoints)> {
- use crate::utils::WBasis;
- let tangent = normal.orthonormal_basis()[0];
-
- let mut range1 = [seg1.0.coords.dot(&tangent), seg1.1.coords.dot(&tangent)];
- let mut range2 = [seg2.0.coords.dot(&tangent), seg2.1.coords.dot(&tangent)];
- let mut features1 = [0, 2];
- let mut features2 = [0, 2];
-
- if range1[1] < range1[0] {
- range1.swap(0, 1);
- features1.swap(0, 1);
- std::mem::swap(&mut seg1.0, &mut seg1.1);
- }
-
- if range2[1] < range2[0] {
- range2.swap(0, 1);
- features2.swap(0, 1);
- std::mem::swap(&mut seg2.0, &mut seg2.1);
- }
-
- if range2[0] > range1[1] || range1[0] > range2[1] {
- // No clip point.
- return None;
- }