aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCrozet Sébastien <developer@crozet.re>2020-12-17 10:24:36 +0100
committerCrozet Sébastien <developer@crozet.re>2020-12-29 11:31:00 +0100
commite231bacec608fa5efd24f7a876572927dbd6c9c4 (patch)
tree596f0b6a1fc666586ffcd71d07a39a7c182c6ef8
parentcc6d1b973002b4d366bc81ec6bf9e8240ad7b404 (diff)
downloadrapier-e231bacec608fa5efd24f7a876572927dbd6c9c4.tar.gz
rapier-e231bacec608fa5efd24f7a876572927dbd6c9c4.tar.bz2
rapier-e231bacec608fa5efd24f7a876572927dbd6c9c4.zip
Move all the contact manifold computations out of Rapier.
-rw-r--r--Cargo.toml4
-rw-r--r--build/rapier2d/Cargo.toml6
-rw-r--r--build/rapier3d/Cargo.toml11
-rw-r--r--build/rapier_testbed2d/Cargo.toml2
-rw-r--r--build/rapier_testbed3d/Cargo.toml2
-rw-r--r--src/data/arena.rs2
-rw-r--r--src/data/hashmap.rs137
-rw-r--r--src/data/maybe_serializable_data.rs17
-rw-r--r--src/data/mod.rs4
-rw-r--r--src/dynamics/mod.rs2
-rw-r--r--src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs2
-rw-r--r--src/dynamics/solver/joint_constraint/prismatic_velocity_constraint.rs2
-rw-r--r--src/dynamics/solver/joint_constraint/prismatic_velocity_constraint_wide.rs2
-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
-rw-r--r--src/lib.rs8
-rw-r--r--src/utils.rs15
-rw-r--r--src_testbed/lib.rs4
-rw-r--r--src_testbed/objects/heightfield.rs2
-rw-r--r--src_testbed/objects/polyline.rs2
49 files changed, 103 insertions, 2511 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 55e9b43..eaafe91 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,8 +10,8 @@ members = [ "build/rapier2d", "build/rapier_testbed2d", "examples2d", "benchmark
#nphysics2d = { path = "../nphysics/build/nphysics2d" }
#nphysics3d = { path = "../nphysics/build/nphysics3d" }
#kiss3d = { path = "../kiss3d" }
-buckler2d = { path = "../buckler/build/buckler2d" }
-buckler3d = { path = "../buckler/build/buckler3d" }
+eagl2d = { path = "../eagl/build/eagl2d" }
+eagl3d = { path = "../eagl/build/eagl3d" }
[profile.release]
#debug = true
diff --git a/build/rapier2d/Cargo.toml b/build/rapier2d/Cargo.toml
index 987fa2f..c20833c 100644
--- a/build/rapier2d/Cargo.toml
+++ b/build/rapier2d/Cargo.toml
@@ -21,8 +21,8 @@ simd-nightly = [ "simba/packed_simd", "simd-is-enabled" ]
# enabled with the "simd-stable" or "simd-nightly" feature.
simd-is-enabled = [ ]
wasm-bindgen = [ "instant/wasm-bindgen" ]
-serde-serialize = [ "erased-serde", "nalgebra/serde-serialize", "buckler2d/serde-serialize", "serde", "generational-arena/serde", "bit-vec/serde", "arrayvec/serde" ]
-enhanced-determinism = [ "simba/libm_force", "indexmap" ]
+serde-serialize = [ "erased-serde", "nalgebra/serde-serialize", "eagl2d/serde-serialize", "serde", "generational-arena/serde", "bit-vec/serde", "arrayvec/serde" ]
+enhanced-determinism = [ "simba/libm_force", "eagl2d/enhanced-determinism", "indexmap" ]
[lib]
name = "rapier2d"
@@ -35,7 +35,7 @@ vec_map = "0.8"
instant = { version = "0.1", features = [ "now" ]}
num-traits = "0.2"
nalgebra = "0.23"
-buckler2d = "0.1"
+eagl2d = "0.1"
simba = "0.3"
approx = "0.4"
rayon = { version = "1", optional = true }
diff --git a/build/rapier3d/Cargo.toml b/build/rapier3d/Cargo.toml
index 7d5673b..a9abef8 100644
--- a/build/rapier3d/Cargo.toml
+++ b/build/rapier3d/Cargo.toml
@@ -15,14 +15,14 @@ edition = "2018"
default = [ "dim3" ]
dim3 = [ ]
parallel = [ "rayon" ]
-simd-stable = [ "buckler3d/simd-stable", "simba/wide", "simd-is-enabled" ]
-simd-nightly = [ "buckler3d/simd-nightly", "simba/packed_simd", "simd-is-enabled" ]
+simd-stable = [ "eagl3d/simd-stable", "simba/wide", "simd-is-enabled" ]
+simd-nightly = [ "eagl3d/simd-nightly", "simba/packed_simd", "simd-is-enabled" ]
# Do not enable this feature directly. It is automatically
# enabled with the "simd-stable" or "simd-nightly" feature.
simd-is-enabled = [ ]
wasm-bindgen = [ "instant/wasm-bindgen" ]
-serde-serialize = [ "erased-serde", "nalgebra/serde-serialize", "buckler3d/serde-serialize", "serde", "generational-arena/serde", "bit-vec/serde" ]
-enhanced-determinism = [ "simba/libm_force", "indexmap" ]
+serde-serialize = [ "erased-serde", "nalgebra/serde-serialize", "eagl3d/serde-serialize", "serde", "generational-arena/serde", "bit-vec/serde" ]
+enhanced-determinism = [ "simba/libm_force", "eagl3d/enhanced-determinism" ]
[lib]
name = "rapier3d"
@@ -35,7 +35,7 @@ vec_map = "0.8"
instant = { version = "0.1", features = [ "now" ]}
num-traits = "0.2"
nalgebra = "0.23"
-buckler3d = "0.1"
+eagl3d = "0.1"
simba = "0.3"
approx = "0.4"
rayon = { version = "1", optional = true }
@@ -46,7 +46,6 @@ bit-vec = "0.6"
rustc-hash = "1"
serde = { version = "1", features = [ "derive" ], optional = true }
erased-serde = { version = "0.3", optional = true }
-indexmap = { version = "1", features = [ "serde-1" ], optional = true }
downcast-rs = "1.2"
num-derive = "0.3"
bitflags = "1"
diff --git a/build/rapier_testbed2d/Cargo.toml b/build/rapier_testbed2d/Cargo.toml
index 72ead41..23be92e 100644
--- a/build/rapier_testbed2d/Cargo.toml
+++ b/build/rapier_testbed2d/Cargo.toml
@@ -31,7 +31,7 @@ instant = { version = "0.1", features = [ "web-sys", "now" ]}
bitflags = "1"
num_cpus = { version = "1", optional = true }
wrapped2d = { version = "0.4", optional = true }
-buckler2d = "0.1"
+eagl2d = "0.1"
ncollide2d = "0.26"
nphysics2d = { version = "0.18", optional = true }
crossbeam = "0.8"
diff --git a/build/rapier_testbed3d/Cargo.toml b/build/rapier_testbed3d/Cargo.toml
index d4ad764..2820a7c 100644
--- a/build/rapier_testbed3d/Cargo.toml
+++ b/build/rapier_testbed3d/Cargo.toml
@@ -30,7 +30,7 @@ instant = { version = "0.1", features = [ "web-sys", "now" ]}
bitflags = "1"
glam = { version = "0.10", optional = true }
num_cpus = { version = "1", optional = true }
-buckler3d = "0.1"
+eagl3d = "0.1"
ncollide3d = "0.26"
nphysics3d = { version = "0.18", optional = true }
physx = { version = "0.8", optional = true }
diff --git a/src/data/arena.rs b/src/data/arena.rs
index a3af45c..3a24cd1 100644
--- a/src/data/arena.rs
+++ b/src/data/arena.rs
@@ -3,7 +3,7 @@
//! See https://github.com/fitzgen/generational-arena/blob/master/src/lib.rs.
//! This has been modified to have a fully deterministic deserialization (including for the order of
//! Index attribution after a deserialization of the arena.
-use buckler::partitioning::IndexedData;
+use eagl::partitioning::IndexedData;
use std::cmp;
use std::iter::{self, Extend, FromIterator, FusedIterator};
use std::mem;
diff --git a/src/data/hashmap.rs b/src/data/hashmap.rs
deleted file mode 100644
index d2ea980..0000000
--- a/src/data/hashmap.rs
+++ /dev/null
@@ -1,137 +0,0 @@
-//! A hash-map that behaves deterministically when the
-//! `enhanced-determinism` feature is enabled.
-
-#[cfg(all(feature = "enhanced-determinism", feature = "serde-serialize"))]
-use indexmap::IndexMap as StdHashMap;
-#[cfg(all(not(feature = "enhanced-determinism"), feature = "serde-serialize"))]
-use std::collections::HashMap as StdHashMap;
-
-/// Serializes only the capacity of a hash-map instead of its actual content.
-#[cfg(feature = "serde-serialize")]
-pub fn serialize_hashmap_capacity<S: serde::Serializer, K, V, H: std::hash::BuildHasher>(
- map: &StdHashMap<K, V, H>,
- s: S,
-) -> Result<S::Ok, S::Error> {
- s.serialize_u64(map.capacity() as u64)
-}
-
-/// Creates a new hash-map with its capacity deserialized from `d`.
-#[cfg(feature = "serde-serialize")]
-pub fn deserialize_hashmap_capacity<
- 'de,
- D: serde::Deserializer<'de>,
- K,
- V,
- H: std::hash::BuildHasher + Default,
->(
- d: D,
-) -> Result<StdHashMap<K, V, H>, D::Error> {
- struct CapacityVisitor;
- impl<'de> serde::de::Visitor<'de> for CapacityVisitor {
- type Value = u64;
-
- fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
- write!(formatter, "an integer between 0 and 2^64")
- }
-
- fn visit_u64<E: serde::de::Error>(self, val: u64) -> Result<Self::Value, E> {
- Ok(val)
- }
- }
-
- let capacity = d.deserialize_u64(CapacityVisitor)? as usize;
- Ok(StdHashMap::with_capacity_and_hasher(
- capacity,
- Default::default(),
- ))
-}
-
-/*
- * FxHasher taken from rustc_hash, except that it does not depend on the pointer size.
- */
-#[cfg(feature = "enhanced-determinism")]
-pub type FxHashMap32<K, V> = indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<FxHasher32>>;
-#[cfg(feature = "enhanced-determinism")]
-pub use {self::FxHashMap32 as HashMap, indexmap::map::Entry};
-#[cfg(not(feature = "enhanced-determinism"))]
-pub use {rustc_hash::FxHashMap as HashMap, std::collections::hash_map::Entry};
-
-const K: u32 = 0x9e3779b9;
-
-// Same as FxHasher, but with the guarantee that the internal hash is
-// an u32 instead of something that depends on the platform.
-pub struct FxHasher32 {
- hash: u32,
-}
-
-impl Default for FxHasher32 {
- #[inline]
- fn default() -> FxHasher32 {
- FxHasher32 { hash: 0 }
- }
-}
-
-impl FxHasher32 {
- #[inline]
- fn add_to_hash(&mut self, i: u32) {
- use std::ops::BitXor;
- self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K);
- }
-}
-
-impl std::hash::Hasher for FxHasher32 {
- #[inline]
- fn write(&mut self, mut bytes: &[u8]) {
- use std::convert::TryInto;
- let read_u32 = |bytes: &[u8]| u32::from_ne_bytes(bytes[..4].try_into().unwrap());
- let mut hash = FxHasher32 { hash: self.hash };
- assert!(std::mem::size_of::<u32>() <= 8);
- while bytes.len() >= std::mem::size_of::<u32>() {
- hash.add_to_hash(read_u32(bytes) as u32);
- bytes = &bytes[std::mem::size_of::<u32>()..];
- }
- if (std::mem::size_of::<u32>() > 4) && (bytes.len() >= 4) {
- hash.add_to_hash(u32::from_ne_bytes(bytes[..4].try_into().unwrap()) as u32);
- bytes = &bytes[4..];
- }
- if (std::mem::size_of::<u32>() > 2) && bytes.len() >= 2 {
- hash.add_to_hash(u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as u32);
- bytes = &bytes[2..];
- }
- if (std::mem::size_of::<u32>() > 1) && bytes.len() >= 1 {
- hash.add_to_hash(bytes[0] as u32);
- }
- self.hash = hash.hash;
- }
-
- #[inline]
- fn write_u8(&mut self, i: u8) {
- self.add_to_hash(i as u32);
- }
-
- #[inline]
- fn write_u16(&mut self, i: u16) {
- self.add_to_hash(i as u32);
- }
-
- #[inline]
- fn write_u32(&mut self, i: u32) {
- self.add_to_hash(i as u32);
- }
-
- #[inline]
- fn write_u64(&mut self, i: u64) {
- self.add_to_hash(i as u32);
- self.add_to_hash((i >> 32) as u32);
- }
-
- #[inline]
- fn write_usize(&mut self, i: usize) {
- self.add_to_hash(i as u32);
- }
-
- #[inline]
- fn finish(&self) -> u64 {
- self.hash as u64
- }
-}
diff --git a/src/data/maybe_serializable_data.rs b/src/data/maybe_serializable_data.rs
deleted file mode 100644
index 8b14e1a..0000000
--- a/src/data/maybe_serializable_data.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-use downcast_rs::{impl_downcast, DowncastSync};
-#[cfg(feature = "serde-serialize")]
-use erased_serde::Serialize;
-
-/// Piece of data that may be serializable.
-pub trait MaybeSerializableData: DowncastSync {
- /// Convert this shape as a serializable entity.
- #[cfg(feature = "serde-serialize")]
- fn as_serialize(&self) -> Option<(u32, &dyn Serialize)> {
- None
- }
-
- /// Clones `self`.
- fn clone_dyn(&self) -> Box<dyn MaybeSerializableData>;
-}
-
-impl_downcast!(sync MaybeSerializableData);
diff --git a/src/data/mod.rs b/src/data/mod.rs
index 672bf94..eb0a229 100644
--- a/src/data/mod.rs
+++ b/src/data/mod.rs
@@ -1,11 +1,9 @@
//! Data structures modified with guaranteed deterministic behavior after deserialization.
pub use self::coarena::Coarena;
-pub use self::maybe_serializable_data::MaybeSerializableData;
+pub use eagl::utils::MaybeSerializableData;
pub mod arena;
mod coarena;
pub(crate) mod graph;
-pub(crate) mod hashmap;
-mod maybe_serializable_data;
pub mod pubsub;
diff --git a/src/dynamics/mod.rs b/src/dynamics/mod.rs
index 28f149a..76e9de2 100644
--- a/src/dynamics/mod.rs
+++ b/src/dynamics/mod.rs
@@ -9,7 +9,7 @@ pub use self::joint::{
};
pub use self::rigid_body::{ActivationStatus, BodyStatus, RigidBody, RigidBodyBuilder};
pub use self::rigid_body_set::{BodyPair, RigidBodyHandle, RigidBodySet};
-pub use buckler::shape::MassProperties;
+pub use eagl::shape::MassProperties;
// #[cfg(not(feature = "parallel"))]
pub(crate) use self::joint::JointGraphEdge;
pub(crate) use self::rigid_body::RigidBodyChanges;
diff --git a/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs b/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs
index 79c69c6..ce42da8 100644
--- a/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs
+++ b/src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs
@@ -13,7 +13,7 @@ use crate::utils::{WAngularInertia, WCross, WCrossMatrix};
use na::{Cholesky, Matrix6, Vector6, U3};
#[cfg(feature = "dim2")]
use {
- crate::utils::SdpMatrix3,
+ eagl::utils::SdpMatrix3,
na::{Matrix3, Vector3},
};
diff --git a/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint.rs b/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint.rs
index 49cfc7a..a2c7c2c 100644
--- a/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint.rs
+++ b/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint.rs
@@ -8,7 +8,7 @@ use crate::utils::{WAngularInertia, WCross, WCrossMatrix};
use na::{Cholesky, Matrix3x2, Matrix5, Vector5, U2, U3};
#[cfg(feature = "dim2")]
use {
- crate::utils::SdpMatrix2,
+ eagl::utils::SdpMatrix2,
na::{Matrix2, Vector2},
};
diff --git a/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint_wide.rs b/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint_wide.rs
index c05c08e..86e0c78 100644
--- a/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint_wide.rs
+++ b/src/dynamics/solver/joint_constraint/prismatic_velocity_constraint_wide.rs
@@ -12,7 +12,7 @@ use crate::utils::{WAngularInertia, WCross, WCrossMatrix};
use na::{Cholesky, Matrix3x2, Matrix5, Vector5, U2, U3};
#[cfg(feature = "dim2")]
use {
- crate::utils::SdpMatrix2,
+ eagl::utils::SdpMatrix2,
na::{Matrix2, Vector2},
};
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.