Allow disabling colliders, rigid-bodies and impulse joints
This commit is contained in:
@@ -176,7 +176,11 @@ impl BroadPhase {
|
||||
/// This method will actually remove from the proxy list all the proxies
|
||||
/// marked as deletable by `self.predelete_proxy`, making their proxy
|
||||
/// handles re-usable by new proxies.
|
||||
fn complete_removals(&mut self, removed_colliders: &[ColliderHandle]) {
|
||||
fn complete_removals(
|
||||
&mut self,
|
||||
colliders: &mut ColliderSet,
|
||||
removed_colliders: &[ColliderHandle],
|
||||
) {
|
||||
// If there is no layer, there is nothing to remove.
|
||||
if self.layers.is_empty() {
|
||||
return;
|
||||
@@ -224,6 +228,11 @@ impl BroadPhase {
|
||||
self.proxies.remove(proxy_id);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(co) = colliders.get_mut_internal(*removed) {
|
||||
// Reset the proxy index.
|
||||
co.bf_data.proxy_index = crate::INVALID_U32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,9 +469,10 @@ impl BroadPhase {
|
||||
// NOTE: we use `get` because the collider may no longer
|
||||
// exist if it has been removed.
|
||||
if let Some(co) = colliders.get_mut_internal(*handle) {
|
||||
if !co.changes.needs_broad_phase_update() {
|
||||
if !co.is_enabled() || !co.changes.needs_broad_phase_update() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut new_proxy_id = co.bf_data.proxy_index;
|
||||
|
||||
if self.handle_modified_collider(
|
||||
@@ -496,7 +506,7 @@ impl BroadPhase {
|
||||
|
||||
// Phase 5: bottom-up pass to remove proxies, and propagate region removed from smaller
|
||||
// layers to possible remove regions from larger layers that would become empty that way.
|
||||
self.complete_removals(removed_colliders);
|
||||
self.complete_removals(colliders, removed_colliders);
|
||||
}
|
||||
|
||||
/// Propagate regions from the smallest layers up to the larger layers.
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::geometry::{
|
||||
use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM};
|
||||
use crate::parry::transformation::vhacd::VHACDParameters;
|
||||
use crate::pipeline::{ActiveEvents, ActiveHooks};
|
||||
use crate::prelude::ColliderEnabled;
|
||||
use na::Unit;
|
||||
use parry::bounding_volume::Aabb;
|
||||
use parry::shape::{Shape, TriMeshFlags};
|
||||
@@ -154,6 +155,32 @@ impl Collider {
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this collider enabled?
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
match self.flags.enabled {
|
||||
ColliderEnabled::Enabled => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets whether or not this collider is enabled.
|
||||
pub fn set_enabled(&mut self, enabled: bool) {
|
||||
match self.flags.enabled {
|
||||
ColliderEnabled::Enabled | ColliderEnabled::DisabledByParent => {
|
||||
if !enabled {
|
||||
self.changes.insert(ColliderChanges::ENABLED_OR_DISABLED);
|
||||
self.flags.enabled = ColliderEnabled::Disabled;
|
||||
}
|
||||
}
|
||||
ColliderEnabled::Disabled => {
|
||||
if enabled {
|
||||
self.changes.insert(ColliderChanges::ENABLED_OR_DISABLED);
|
||||
self.flags.enabled = ColliderEnabled::Enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the translational part of this collider's position.
|
||||
pub fn set_translation(&mut self, translation: Vector<Real>) {
|
||||
self.changes.insert(ColliderChanges::POSITION);
|
||||
@@ -402,6 +429,8 @@ pub struct ColliderBuilder {
|
||||
pub collision_groups: InteractionGroups,
|
||||
/// The solver groups for the collider being built.
|
||||
pub solver_groups: InteractionGroups,
|
||||
/// Will the collider being built be enabled?
|
||||
pub enabled: bool,
|
||||
/// The total force magnitude beyond which a contact force event can be emitted.
|
||||
pub contact_force_event_threshold: Real,
|
||||
}
|
||||
@@ -424,6 +453,7 @@ impl ColliderBuilder {
|
||||
active_collision_types: ActiveCollisionTypes::default(),
|
||||
active_hooks: ActiveHooks::empty(),
|
||||
active_events: ActiveEvents::empty(),
|
||||
enabled: true,
|
||||
contact_force_event_threshold: 0.0,
|
||||
}
|
||||
}
|
||||
@@ -834,6 +864,12 @@ impl ColliderBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Enable or disable the collider after its creation.
|
||||
pub fn enabled(mut self, enabled: bool) -> Self {
|
||||
self.enabled = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds a new collider attached to the given rigid-body.
|
||||
pub fn build(&self) -> Collider {
|
||||
let shape = self.shape.clone();
|
||||
@@ -849,6 +885,11 @@ impl ColliderBuilder {
|
||||
active_collision_types: self.active_collision_types,
|
||||
active_hooks: self.active_hooks,
|
||||
active_events: self.active_events,
|
||||
enabled: if self.enabled {
|
||||
ColliderEnabled::Enabled
|
||||
} else {
|
||||
ColliderEnabled::Disabled
|
||||
},
|
||||
};
|
||||
let changes = ColliderChanges::all();
|
||||
let pos = ColliderPosition(self.position);
|
||||
|
||||
@@ -64,6 +64,8 @@ bitflags::bitflags! {
|
||||
/// This flags is automatically set by the `PhysicsPipeline` when the `RigidBodyChanges::DOMINANCE`
|
||||
/// or `RigidBodyChanges::TYPE` of the parent rigid-body of this collider is detected.
|
||||
const PARENT_EFFECTIVE_DOMINANCE = 1 << 7; // NF update.
|
||||
/// Flag indicating that whether or not the collider is enabled was changed.
|
||||
const ENABLED_OR_DISABLED = 1 << 8; // BF & NF updates.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,6 +374,19 @@ impl Default for ActiveCollisionTypes {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// Enum indicating whether or not a collider is enabled.
|
||||
pub enum ColliderEnabled {
|
||||
/// The collider is enabled.
|
||||
Enabled,
|
||||
/// The collider wasn’t disabled by the user explicitly but it is attached to
|
||||
/// a disabled rigid-body.
|
||||
DisabledByParent,
|
||||
/// The collider is disabled by the user explicitly.
|
||||
Disabled,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// A set of flags for controlling collision/intersection filtering, modification, and events.
|
||||
@@ -389,6 +404,8 @@ pub struct ColliderFlags {
|
||||
pub active_hooks: ActiveHooks,
|
||||
/// The events enabled for this collider.
|
||||
pub active_events: ActiveEvents,
|
||||
/// Whether or not the collider is enabled.
|
||||
pub enabled: ColliderEnabled,
|
||||
}
|
||||
|
||||
impl Default for ColliderFlags {
|
||||
@@ -399,6 +416,7 @@ impl Default for ColliderFlags {
|
||||
solver_groups: InteractionGroups::all(),
|
||||
active_hooks: ActiveHooks::empty(),
|
||||
active_events: ActiveEvents::empty(),
|
||||
enabled: ColliderEnabled::Enabled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,14 @@ impl ColliderSet {
|
||||
self.colliders.iter().map(|(h, c)| (ColliderHandle(h), c))
|
||||
}
|
||||
|
||||
/// Iterate through all the enabled colliders on this set.
|
||||
pub fn iter_enabled(&self) -> impl Iterator<Item = (ColliderHandle, &Collider)> {
|
||||
self.colliders
|
||||
.iter()
|
||||
.map(|(h, c)| (ColliderHandle(h), c))
|
||||
.filter(|(_, c)| c.is_enabled())
|
||||
}
|
||||
|
||||
/// Iterates mutably through all the colliders on this set.
|
||||
#[cfg(not(feature = "dev-remove-slow-accessors"))]
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (ColliderHandle, &mut Collider)> {
|
||||
@@ -52,6 +60,12 @@ impl ColliderSet {
|
||||
})
|
||||
}
|
||||
|
||||
/// Iterates mutably through all the enabled colliders on this set.
|
||||
#[cfg(not(feature = "dev-remove-slow-accessors"))]
|
||||
pub fn iter_enabled_mut(&mut self) -> impl Iterator<Item = (ColliderHandle, &mut Collider)> {
|
||||
self.iter_mut().filter(|(_, c)| c.is_enabled())
|
||||
}
|
||||
|
||||
/// The number of colliders on this set.
|
||||
pub fn len(&self) -> usize {
|
||||
self.colliders.len()
|
||||
@@ -268,6 +282,17 @@ impl ColliderSet {
|
||||
pub(crate) fn get_mut_internal(&mut self, handle: ColliderHandle) -> Option<&mut Collider> {
|
||||
self.colliders.get_mut(handle.0)
|
||||
}
|
||||
|
||||
// Just a very long name instead of `.get_mut` to make sure
|
||||
// this is really the method we wanted to use instead of `get_mut_internal`.
|
||||
pub(crate) fn get_mut_internal_with_modification_tracking(
|
||||
&mut self,
|
||||
handle: ColliderHandle,
|
||||
) -> Option<&mut Collider> {
|
||||
let result = self.colliders.get_mut(handle.0)?;
|
||||
Self::mark_as_modified(handle, result, &mut self.modified_colliders);
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<crate::data::Index> for ColliderSet {
|
||||
|
||||
Reference in New Issue
Block a user