diff options
| author | Max Whitehead <max.blackllama.alt3@gmail.com> | 2024-03-10 23:44:26 -0700 |
|---|---|---|
| committer | Sébastien Crozet <sebastien@crozet.re> | 2024-03-23 10:50:02 +0100 |
| commit | 3fd18f4da8476a29945fa6f0c49e0af08d1f7363 (patch) | |
| tree | cf5529fbd7011d319286f8cd8e34a5fea951dfe3 | |
| parent | f9663f894c022e25ae6c6bc572dc305fab1adb76 (diff) | |
| download | rapier-3fd18f4da8476a29945fa6f0c49e0af08d1f7363.tar.gz rapier-3fd18f4da8476a29945fa6f0c49e0af08d1f7363.tar.bz2 rapier-3fd18f4da8476a29945fa6f0c49e0af08d1f7363.zip | |
fix(user_changes): Fix RigidBodyType changed to Dynamic not updating
active dynamic set.
| -rw-r--r-- | src/pipeline/physics_pipeline.rs | 71 | ||||
| -rw-r--r-- | src/pipeline/user_changes.rs | 4 |
2 files changed, 72 insertions, 3 deletions
diff --git a/src/pipeline/physics_pipeline.rs b/src/pipeline/physics_pipeline.rs index 6dbc4e5..893882d 100644 --- a/src/pipeline/physics_pipeline.rs +++ b/src/pipeline/physics_pipeline.rs @@ -653,7 +653,7 @@ mod test { use crate::geometry::{BroadPhase, ColliderBuilder, ColliderSet, NarrowPhase}; use crate::math::Vector; use crate::pipeline::PhysicsPipeline; - use crate::prelude::MultibodyJointSet; + use crate::prelude::{MultibodyJointSet, RigidBodyType}; #[test] fn kinematic_and_fixed_contact_crash() { @@ -852,4 +852,73 @@ mod test { ); } } + + #[test] + fn rigid_body_type_changed_dynamic_is_in_active_set() { + let mut colliders = ColliderSet::new(); + let mut impulse_joints = ImpulseJointSet::new(); + let mut multibody_joints = MultibodyJointSet::new(); + let mut pipeline = PhysicsPipeline::new(); + let mut bf = BroadPhase::new(); + let mut nf = NarrowPhase::new(); + let mut islands = IslandManager::new(); + + let mut bodies = RigidBodySet::new(); + + // Initialize body as kinematic with mass + let rb = RigidBodyBuilder::kinematic_position_based() + .additional_mass(1.0) + .build(); + let h = bodies.insert(rb.clone()); + + // Step once + let gravity = Vector::y() * -9.81; + pipeline.step( + &gravity, + &IntegrationParameters::default(), + &mut islands, + &mut bf, + &mut nf, + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + &mut CCDSolver::new(), + None, + &(), + &(), + ); + + // Switch body type to Dynamic + bodies + .get_mut(h) + .unwrap() + .set_body_type(RigidBodyType::Dynamic, true); + + // Step again + pipeline.step( + &gravity, + &IntegrationParameters::default(), + &mut islands, + &mut bf, + &mut nf, + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + &mut CCDSolver::new(), + None, + &(), + &(), + ); + + let body = bodies.get(h).unwrap(); + let h_y = body.pos.position.translation.y; + + // Expect gravity to be applied on second step after switching to Dynamic + assert!(h_y < 0.0); + + // Expect body to now be in active_dynamic_set + assert!(islands.active_dynamic_set.contains(&h)); + } } diff --git a/src/pipeline/user_changes.rs b/src/pipeline/user_changes.rs index 7c3f1ac..9aa93a5 100644 --- a/src/pipeline/user_changes.rs +++ b/src/pipeline/user_changes.rs @@ -121,8 +121,8 @@ pub(crate) fn handle_user_changes_to_rigid_bodies( } // Push the body to the active set if it is not - // sleeping and if it is not already inside of the active set. - if changes.contains(RigidBodyChanges::SLEEP) + // sleeping and if it is not already inside of the active set, or if type changed to dynamic. + if (changes.contains(RigidBodyChanges::SLEEP) || changes.contains(RigidBodyChanges::TYPE)) && rb.is_enabled() && !rb.activation.sleeping // May happen if the body was put to sleep manually. && rb.is_dynamic() // Only dynamic bodies are in the active dynamic set. |
