aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/narrow_phase.rs
diff options
context:
space:
mode:
authorSébastien Crozet <sebcrozet@dimforge.com>2024-04-21 23:42:21 +0200
committerSébastien Crozet <sebastien@crozet.re>2024-04-30 23:10:46 +0200
commit6635d49c8bdaca13011a888d3901436eb79c599e (patch)
treece6d3ded0025c9107544275b109f0570c0d54daa /src/geometry/narrow_phase.rs
parent33dd38016ccf3c4ad8e874d75e51fbc20dd060da (diff)
downloadrapier-6635d49c8bdaca13011a888d3901436eb79c599e.tar.gz
rapier-6635d49c8bdaca13011a888d3901436eb79c599e.tar.bz2
rapier-6635d49c8bdaca13011a888d3901436eb79c599e.zip
feat: add configurable distance cap to soft-ccd
Diffstat (limited to 'src/geometry/narrow_phase.rs')
-rw-r--r--src/geometry/narrow_phase.rs29
1 files changed, 16 insertions, 13 deletions
diff --git a/src/geometry/narrow_phase.rs b/src/geometry/narrow_phase.rs
index a711117..39ed253 100644
--- a/src/geometry/narrow_phase.rs
+++ b/src/geometry/narrow_phase.rs
@@ -898,19 +898,22 @@ impl NarrowPhase {
let pos12 = co1.pos.inv_mul(&co2.pos);
- let effective_prediction_distance = if rb1.map(|rb| rb.is_soft_ccd_enabled()) == Some(true) ||
- rb2.map(|rb| rb.is_soft_ccd_enabled()) == Some(true) {
-
- let aabb1 = co1.compute_aabb();
- let aabb2 = co2.compute_aabb();
-
- let linvel1 = rb1.map(|rb| *rb.linvel()).unwrap_or_default();
- let linvel2 = rb2.map(|rb| *rb.linvel()).unwrap_or_default();
-
- if !aabb1.intersects(&aabb2) && !aabb1.intersects_moving_aabb(&aabb2, linvel2 - linvel1) {
- pair.clear();
- break 'emit_events;
- }
+ let soft_ccd_prediction1 = rb1.map(|rb| rb.soft_ccd_prediction()).unwrap_or(0.0);
+ let soft_ccd_prediction2 = rb2.map(|rb| rb.soft_ccd_prediction()).unwrap_or(0.0);
+ let effective_prediction_distance = if soft_ccd_prediction1 > 0.0 || soft_ccd_prediction2 > 0.0 {
+ let aabb1 = co1.compute_aabb();
+ let aabb2 = co2.compute_aabb();
+ let inv_dt = crate::utils::inv(dt);
+
+ let linvel1 = rb1.map(|rb| rb.linvel()
+ .cap_magnitude(soft_ccd_prediction1 * inv_dt)).unwrap_or_default();
+ let linvel2 = rb2.map(|rb| rb.linvel()
+ .cap_magnitude(soft_ccd_prediction2 * inv_dt)).unwrap_or_default();
+
+ if !aabb1.intersects(&aabb2) && !aabb1.intersects_moving_aabb(&aabb2, linvel2 - linvel1) {
+ pair.clear();
+ break 'emit_events;
+ }
prediction_distance.max(