diff options
| author | Sébastien Crozet <developer@crozet.re> | 2022-01-16 16:40:59 +0100 |
|---|---|---|
| committer | Sébastien Crozet <developer@crozet.re> | 2022-01-16 16:52:40 +0100 |
| commit | 0703e5527fd95d86bb6621e61dbcb1a6e7f9329a (patch) | |
| tree | 806e7d950015875ebfcca5520784aea6e7c5ae10 /src/dynamics/island_manager.rs | |
| parent | 4454a845e98b990abf3929ca46b59d0fca5a18ec (diff) | |
| download | rapier-0703e5527fd95d86bb6621e61dbcb1a6e7f9329a.tar.gz rapier-0703e5527fd95d86bb6621e61dbcb1a6e7f9329a.tar.bz2 rapier-0703e5527fd95d86bb6621e61dbcb1a6e7f9329a.zip | |
Fix some solver issues
- Fix the wrong codepath taken by the solver for contacts involving a collider without parent.
- Properly adress the non-linear treatment of the friction direction
- Simplify the sleeping strategy
- Add an impulse resolution multiplier
Diffstat (limited to 'src/dynamics/island_manager.rs')
| -rw-r--r-- | src/dynamics/island_manager.rs | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/dynamics/island_manager.rs b/src/dynamics/island_manager.rs index 55b47c9..53f803d 100644 --- a/src/dynamics/island_manager.rs +++ b/src/dynamics/island_manager.rs @@ -5,6 +5,7 @@ use crate::dynamics::{ }; use crate::geometry::{ColliderParent, NarrowPhase}; use crate::math::Real; +use crate::utils::WDot; /// Structure responsible for maintaining the set of active rigid-bodies, and /// putting non-moving rigid-bodies to sleep to save computation times. @@ -172,6 +173,7 @@ impl IslandManager { pub(crate) fn update_active_set_with_contacts<Bodies, Colliders>( &mut self, + dt: Real, bodies: &mut Bodies, colliders: &Colliders, narrow_phase: &NarrowPhase, @@ -207,12 +209,15 @@ impl IslandManager { let stack = &mut self.stack; let vels: &RigidBodyVelocity = bodies.index(h.0); - let pseudo_kinetic_energy = vels.pseudo_kinetic_energy(); + let sq_linvel = vels.linvel.norm_squared(); + let sq_angvel = vels.angvel.gdot(vels.angvel); bodies.map_mut_internal(h.0, |activation: &mut RigidBodyActivation| { - update_energy(activation, pseudo_kinetic_energy); + update_energy(activation, sq_linvel, sq_angvel, dt); - if activation.energy <= activation.threshold { + if activation.time_since_can_sleep + >= RigidBodyActivation::default_time_until_sleep() + { // Mark them as sleeping for now. This will // be set to false during the graph traversal // if it should not be put to sleep. @@ -346,8 +351,12 @@ impl IslandManager { } } -fn update_energy(activation: &mut RigidBodyActivation, pseudo_kinetic_energy: Real) { - let mix_factor = 0.01; - let new_energy = (1.0 - mix_factor) * activation.energy + mix_factor * pseudo_kinetic_energy; - activation.energy = new_energy.min(activation.threshold.abs() * 4.0); +fn update_energy(activation: &mut RigidBodyActivation, sq_linvel: Real, sq_angvel: Real, dt: Real) { + if sq_linvel < activation.linear_threshold * activation.linear_threshold + && sq_angvel < activation.angular_threshold * activation.angular_threshold + { + activation.time_since_can_sleep += dt; + } else { + activation.time_since_can_sleep = 0.0; + } } |
