Properly take initial sleeping state set by the user when creating a rigid-body

This commit is contained in:
Sébastien Crozet
2022-12-11 17:47:16 +01:00
parent cb9350fd80
commit 0207f8cf96
6 changed files with 46 additions and 21 deletions

View File

@@ -14,6 +14,11 @@
- Add the `QueryPipeline` as an optional argument to `PhysicsPipeline::step` and `CollisionPipeline::step`. If this - Add the `QueryPipeline` as an optional argument to `PhysicsPipeline::step` and `CollisionPipeline::step`. If this
argument is specified, then the query pipeline will be incrementally (i.e. more efficiently) update at the same time as argument is specified, then the query pipeline will be incrementally (i.e. more efficiently) update at the same time as
these other pipelines. In that case, calling `QueryPipeline::update` a `PhysicsPipeline::step` isnt needed. these other pipelines. In that case, calling `QueryPipeline::update` a `PhysicsPipeline::step` isnt needed.
- `RigidBody::set_body_type` now takes an extra boolean argument indicating if the rigid-body should be woken-up
(if it becomes dynamic).
### Fix
- Fix bug resulting in rigid-bodies being awakened after they are created, even if they are created sleeping.
## v0.16.1 (10 Nov. 2022) ## v0.16.1 (10 Nov. 2022)
### Fix ### Fix

View File

@@ -1,6 +1,6 @@
use crate::dynamics::{ use crate::dynamics::{
ImpulseJointSet, MultibodyJointSet, RigidBodyActivation, RigidBodyColliders, RigidBodyHandle, ImpulseJointSet, MultibodyJointSet, RigidBodyActivation, RigidBodyChanges, RigidBodyColliders,
RigidBodyIds, RigidBodySet, RigidBodyType, RigidBodyVelocity, RigidBodyHandle, RigidBodyIds, RigidBodySet, RigidBodyType, RigidBodyVelocity,
}; };
use crate::geometry::{ColliderSet, NarrowPhase}; use crate::geometry::{ColliderSet, NarrowPhase};
use crate::math::Real; use crate::math::Real;
@@ -96,15 +96,21 @@ impl IslandManager {
// attempting to wake-up a rigid-body that has already been deleted. // attempting to wake-up a rigid-body that has already been deleted.
if bodies.get(handle).map(|rb| rb.body_type()) == Some(RigidBodyType::Dynamic) { if bodies.get(handle).map(|rb| rb.body_type()) == Some(RigidBodyType::Dynamic) {
let rb = bodies.index_mut_internal(handle); let rb = bodies.index_mut_internal(handle);
// Check that the user didnt change the sleeping state explicitly, in which
// case we dont overwrite it.
if !rb.changes.contains(RigidBodyChanges::SLEEP) {
rb.activation.wake_up(strong); rb.activation.wake_up(strong);
if rb.is_enabled() && self.active_dynamic_set.get(rb.ids.active_set_id) != Some(&handle) if rb.is_enabled()
&& self.active_dynamic_set.get(rb.ids.active_set_id) != Some(&handle)
{ {
rb.ids.active_set_id = self.active_dynamic_set.len(); rb.ids.active_set_id = self.active_dynamic_set.len();
self.active_dynamic_set.push(handle); self.active_dynamic_set.push(handle);
} }
} }
} }
}
/// Iter through all the active kinematic rigid-bodies on this set. /// Iter through all the active kinematic rigid-bodies on this set.
pub fn active_kinematic_bodies(&self) -> &[RigidBodyHandle] { pub fn active_kinematic_bodies(&self) -> &[RigidBodyHandle] {

View File

@@ -135,7 +135,7 @@ impl RigidBody {
} }
/// Sets the type of this rigid-body. /// Sets the type of this rigid-body.
pub fn set_body_type(&mut self, status: RigidBodyType) { pub fn set_body_type(&mut self, status: RigidBodyType, wake_up: bool) {
if status != self.body_type { if status != self.body_type {
self.changes.insert(RigidBodyChanges::TYPE); self.changes.insert(RigidBodyChanges::TYPE);
self.body_type = status; self.body_type = status;
@@ -143,6 +143,10 @@ impl RigidBody {
if status == RigidBodyType::Fixed { if status == RigidBodyType::Fixed {
self.vels = RigidBodyVelocity::zero(); self.vels = RigidBodyVelocity::zero();
} }
if self.is_dynamic() && wake_up {
self.wake_up(true);
}
} }
} }

View File

@@ -299,7 +299,13 @@ impl NarrowPhase {
} }
} }
self.handle_modified_colliders(islands, modified_colliders, colliders, bodies, events); self.handle_user_changes_on_colliders(
islands,
modified_colliders,
colliders,
bodies,
events,
);
} }
pub(crate) fn remove_collider( pub(crate) fn remove_collider(
@@ -393,7 +399,7 @@ impl NarrowPhase {
} }
} }
pub(crate) fn handle_modified_colliders( pub(crate) fn handle_user_changes_on_colliders(
&mut self, &mut self,
mut islands: Option<&mut IslandManager>, mut islands: Option<&mut IslandManager>,
modified_colliders: &[ColliderHandle], modified_colliders: &[ColliderHandle],

View File

@@ -5,7 +5,7 @@ use crate::counters::Counters;
use crate::dynamics::IslandSolver; use crate::dynamics::IslandSolver;
use crate::dynamics::{ use crate::dynamics::{
CCDSolver, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet, CCDSolver, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet,
RigidBodyPosition, RigidBodyType, RigidBodyChanges, RigidBodyHandle, RigidBodyPosition, RigidBodyType,
}; };
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
use crate::dynamics::{JointGraphEdge, ParallelIslandSolver as IslandSolver}; use crate::dynamics::{JointGraphEdge, ParallelIslandSolver as IslandSolver};
@@ -77,6 +77,18 @@ impl PhysicsPipeline {
} }
} }
fn clear_modified_bodies(
&mut self,
bodies: &mut RigidBodySet,
modified_bodies: &mut Vec<RigidBodyHandle>,
) {
for handle in modified_bodies.drain(..) {
if let Some(rb) = bodies.get_mut_internal(handle) {
rb.changes = RigidBodyChanges::empty();
}
}
}
fn detect_collisions( fn detect_collisions(
&mut self, &mut self,
integration_parameters: &IntegrationParameters, integration_parameters: &IntegrationParameters,
@@ -430,7 +442,7 @@ impl PhysicsPipeline {
&modified_colliders[..], &modified_colliders[..],
); );
let modified_bodies = bodies.take_modified(); let mut modified_bodies = bodies.take_modified();
super::user_changes::handle_user_changes_to_rigid_bodies( super::user_changes::handle_user_changes_to_rigid_bodies(
Some(islands), Some(islands),
bodies, bodies,
@@ -481,6 +493,7 @@ impl PhysicsPipeline {
} }
self.clear_modified_colliders(colliders, &mut modified_colliders); self.clear_modified_colliders(colliders, &mut modified_colliders);
self.clear_modified_bodies(bodies, &mut modified_bodies);
removed_colliders.clear(); removed_colliders.clear();
let mut remaining_time = integration_parameters.dt; let mut remaining_time = integration_parameters.dt;

View File

@@ -86,14 +86,6 @@ pub(crate) fn handle_user_changes_to_rigid_bodies(
ids.active_set_id, ids.active_set_id,
)); ));
} }
// Add to the active dynamic set.
activation.wake_up(true);
// Make sure the sleep change flag is set (even if for some
// reasons the rigid-body was already awake) to make
// sure the code handling sleeping change adds the body to
// the active_dynamic_set.
changes.set(RigidBodyChanges::SLEEP, true);
} }
RigidBodyType::KinematicVelocityBased RigidBodyType::KinematicVelocityBased
| RigidBodyType::KinematicPositionBased => { | RigidBodyType::KinematicPositionBased => {
@@ -216,7 +208,6 @@ pub(crate) fn handle_user_changes_to_rigid_bodies(
} }
} }
rb.changes = RigidBodyChanges::empty();
rb.ids = ids; rb.ids = ids;
rb.activation = activation; rb.activation = activation;
} }