Add ActiveCollisionTypes to easily enable collision-detection between two non-static rigid-body.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle};
|
||||
use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle, RigidBodyType};
|
||||
use crate::geometry::{InteractionGroups, SAPProxyIndex, Shape, SharedShape};
|
||||
use crate::math::{Isometry, Real};
|
||||
use crate::parry::partitioning::IndexedData;
|
||||
@@ -208,27 +208,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// The groups of this collider, for filtering contact and solver pairs.
|
||||
pub struct ColliderGroups {
|
||||
/// The groups controlling the pairs of colliders that can interact (generate
|
||||
/// interaction events or contacts).
|
||||
pub collision_groups: InteractionGroups,
|
||||
/// The groups controlling the pairs of collider that have their contact
|
||||
/// points taken into account for force computation.
|
||||
pub solver_groups: InteractionGroups,
|
||||
}
|
||||
|
||||
impl Default for ColliderGroups {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
collision_groups: InteractionGroups::default(),
|
||||
solver_groups: InteractionGroups::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// The constraints solver-related properties of this collider (friction, restitution, etc.)
|
||||
@@ -272,10 +251,97 @@ impl Default for ColliderMaterial {
|
||||
}
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// Flags affecting whether or not collision-detection happens between two colliders
|
||||
/// depending on the type of rigid-bodies they are attached to.
|
||||
pub struct ActiveCollisionTypes: u16 {
|
||||
/// Enable collision-detection between a collider attached to a dynamic body
|
||||
/// and another collider attached to a dynamic body.
|
||||
const DYNAMIC_DYNAMIC = 0b0000_0000_0000_0001;
|
||||
/// Enable collision-detection between a collider attached to a dynamic body
|
||||
/// and another collider attached to a kinematic body.
|
||||
const DYNAMIC_KINEMATIC = 0b0000_0000_0000_1100;
|
||||
/// Enable collision-detection between a collider attached to a dynamic body
|
||||
/// and another collider attached to a static body (or not attached to any body).
|
||||
const DYNAMIC_STATIC = 0b0000_0000_0000_0010;
|
||||
/// Enable collision-detection between a collider attached to a kinematic body
|
||||
/// and another collider attached to a kinematic body.
|
||||
const KINEMATIC_KINEMATIC = 0b1100_1100_0000_0000;
|
||||
|
||||
/// Enable collision-detection between a collider attached to a kinematic body
|
||||
/// and another collider attached to a static body (or not attached to any body).
|
||||
const KINEMATIC_STATIC = 0b0010_0010_0000_0000;
|
||||
|
||||
/// Enable collision-detection between a collider attached to a static body (or
|
||||
/// not attached to any body) and another collider attached to a static body (or
|
||||
/// not attached to any body).
|
||||
const STATIC_STATIC = 0b0000_0000_0010_0000;
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveCollisionTypes {
|
||||
/// Test whether contact should be computed between two rigid-bodies with the given types.
|
||||
pub fn test(self, rb_type1: RigidBodyType, rb_type2: RigidBodyType) -> bool {
|
||||
// NOTE: This test is quite complicated so here is an explanation.
|
||||
// First, we associate the following bit masks:
|
||||
// - DYNAMIC = 0001
|
||||
// - STATIC = 0010
|
||||
// - KINEMATIC = 1100
|
||||
// These are equal to the bits indexed by `RigidBodyType as u32`.
|
||||
// The bit masks defined by ActiveCollisionTypes are defined is such a way
|
||||
// that the first part of the variant name (e.g. DYNAMIC_*) indicates which
|
||||
// groups of four bits should be considered:
|
||||
// - DYNAMIC_* = the first group of four bits.
|
||||
// - STATIC_* = the second group of four bits.
|
||||
// - KINEMATIC_* = the third and fourth groups of four bits.
|
||||
// The second part of the variant name (e.g. *_DYNAMIC) indicates the value
|
||||
// of the aforementioned groups of four bits.
|
||||
// For example, DYNAMIC_STATIC means that the first group of four bits (because
|
||||
// of DYNAMIC_*) must have the value 0010 (because of *_STATIC). That gives
|
||||
// us 0b0000_0000_0000_0010 for the DYNAMIC_STATIC_VARIANT.
|
||||
//
|
||||
// The KINEMATIC_* is special because it occupies two groups of four bits. This is
|
||||
// because it combines both KinematicPositionBased and KinematicVelocityBased.
|
||||
//
|
||||
// Now that we have a way of building these bit masks, let's see how we use them.
|
||||
// Given a pair of rigid-body types, the first rigid-body type is used to select
|
||||
// the group of four bits we want to test (the selection is done by to the
|
||||
// `>> (rb_type1 as u32 * 4) & 0b0000_1111`) and the second rigid-body type is
|
||||
// used to form the bit mask we test this group of four bits against.
|
||||
// In other word, the selection of the group of four bits tells us "for this type
|
||||
// of rigid-body I can have collision with rigid-body types with these bit representation".
|
||||
// Then the `(1 << rb_type2)` gives us the bit-representation of the rigid-body type,
|
||||
// which needs to be checked.
|
||||
//
|
||||
// Because that test must be symmetric, we perform two similar tests by swapping
|
||||
// rb_type1 and rb_type2.
|
||||
((self.bits >> (rb_type1 as u32 * 4)) & 0b0000_1111) & (1 << rb_type2 as u32) != 0
|
||||
|| ((self.bits >> (rb_type2 as u32 * 4)) & 0b0000_1111) & (1 << rb_type1 as u32) != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ActiveCollisionTypes {
|
||||
fn default() -> Self {
|
||||
ActiveCollisionTypes::DYNAMIC_DYNAMIC
|
||||
| ActiveCollisionTypes::DYNAMIC_KINEMATIC
|
||||
| ActiveCollisionTypes::DYNAMIC_STATIC
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// A set of flags controlling the active hooks and events for this colliders.
|
||||
/// A set of flags for controlling collision/intersection filtering, modification, and events.
|
||||
pub struct ColliderFlags {
|
||||
/// Controls whether collision-detection happens between two colliders depending on
|
||||
/// the type of the rigid-bodies they are attached to.
|
||||
pub active_collision_types: ActiveCollisionTypes,
|
||||
/// The groups controlling the pairs of colliders that can interact (generate
|
||||
/// interaction events or contacts).
|
||||
pub collision_groups: InteractionGroups,
|
||||
/// The groups controlling the pairs of collider that have their contact
|
||||
/// points taken into account for force computation.
|
||||
pub solver_groups: InteractionGroups,
|
||||
/// The physics hooks enabled for contact pairs and intersection pairs involving this collider.
|
||||
pub active_hooks: ActiveHooks,
|
||||
/// The events enabled for this collider.
|
||||
@@ -285,6 +351,9 @@ pub struct ColliderFlags {
|
||||
impl Default for ColliderFlags {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
active_collision_types: ActiveCollisionTypes::default(),
|
||||
collision_groups: InteractionGroups::all(),
|
||||
solver_groups: InteractionGroups::all(),
|
||||
active_hooks: ActiveHooks::empty(),
|
||||
active_events: ActiveEvents::empty(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user