feat: add configurable distance cap to soft-ccd

This commit is contained in:
Sébastien Crozet
2024-04-21 23:42:21 +02:00
committed by Sébastien Crozet
parent 33dd38016c
commit 6635d49c8b
5 changed files with 88 additions and 42 deletions

View File

@@ -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
})
});

View File

@@ -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 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 aabb1 = co1.compute_aabb();
let aabb2 = co2.compute_aabb();
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();
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;
}
if !aabb1.intersects(&aabb2) && !aabb1.intersects_moving_aabb(&aabb2, linvel2 - linvel1) {
pair.clear();
break 'emit_events;
}
prediction_distance.max(