From 3fd18f4da8476a29945fa6f0c49e0af08d1f7363 Mon Sep 17 00:00:00 2001 From: Max Whitehead Date: Sun, 10 Mar 2024 23:44:26 -0700 Subject: fix(user_changes): Fix RigidBodyType changed to Dynamic not updating active dynamic set. --- src/pipeline/physics_pipeline.rs | 71 +++++++++++++++++++++++++++++++++++++++- 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. -- cgit