fix(user_changes): Fix RigidBodyType changed to Dynamic not updating

active dynamic set.
This commit is contained in:
Max Whitehead
2024-03-10 23:44:26 -07:00
committed by Sébastien Crozet
parent f9663f894c
commit 3fd18f4da8
2 changed files with 72 additions and 3 deletions

View File

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

View File

@@ -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.