diff options
| author | Sébastien Crozet <sebcrozet@dimforge.com> | 2024-04-21 23:42:21 +0200 |
|---|---|---|
| committer | Sébastien Crozet <sebastien@crozet.re> | 2024-04-30 23:10:46 +0200 |
| commit | 6635d49c8bdaca13011a888d3901436eb79c599e (patch) | |
| tree | ce6d3ded0025c9107544275b109f0570c0d54daa /src/geometry | |
| parent | 33dd38016ccf3c4ad8e874d75e51fbc20dd060da (diff) | |
| download | rapier-6635d49c8bdaca13011a888d3901436eb79c599e.tar.gz rapier-6635d49c8bdaca13011a888d3901436eb79c599e.tar.bz2 rapier-6635d49c8bdaca13011a888d3901436eb79c599e.zip | |
feat: add configurable distance cap to soft-ccd
Diffstat (limited to 'src/geometry')
| -rw-r--r-- | src/geometry/broad_phase_multi_sap/broad_phase_multi_sap.rs | 7 | ||||
| -rw-r--r-- | src/geometry/narrow_phase.rs | 29 |
2 files changed, 21 insertions, 15 deletions
diff --git a/src/geometry/broad_phase_multi_sap/broad_phase_multi_sap.rs b/src/geometry/broad_phase_multi_sap/broad_phase_multi_sap.rs index bc09b57..fb5d407 100644 --- a/src/geometry/broad_phase_multi_sap/broad_phase_multi_sap.rs +++ b/src/geometry/broad_phase_multi_sap/broad_phase_multi_sap.rs @@ -597,8 +597,11 @@ impl BroadPhase for BroadPhaseMultiSap { let next_pos = co.parent.and_then(|p| { let parent = bodies.get(p.handle)?; - parent.is_soft_ccd_enabled().then(|| { - parent.predict_position_using_velocity_and_forces(dt) * p.pos_wrt_parent + (parent.soft_ccd_prediction() > 0.0).then(|| { + parent.predict_position_using_velocity_and_forces_with_max_dist( + dt, + parent.soft_ccd_prediction(), + ) * p.pos_wrt_parent }) }); 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( |
