aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pipeline/physics_pipeline.rs71
-rw-r--r--src/pipeline/user_changes.rs4
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.