diff options
| author | Crozet Sébastien <developer@crozet.re> | 2021-06-01 17:59:07 +0200 |
|---|---|---|
| committer | Crozet Sébastien <developer@crozet.re> | 2021-06-01 17:59:07 +0200 |
| commit | 7153eb7779a29853289df90f28efaac738620386 (patch) | |
| tree | 561a81b65609b60c4429c134ea474a160d70d80e /src/geometry/collider_components.rs | |
| parent | 1839f61d816af37c95889caf592b5a7cf8d89412 (diff) | |
| download | rapier-7153eb7779a29853289df90f28efaac738620386.tar.gz rapier-7153eb7779a29853289df90f28efaac738620386.tar.bz2 rapier-7153eb7779a29853289df90f28efaac738620386.zip | |
Add ActiveCollisionTypes to easily enable collision-detection between two non-static rigid-body.
Diffstat (limited to 'src/geometry/collider_components.rs')
| -rw-r--r-- | src/geometry/collider_components.rs | 115 |
1 files changed, 92 insertions, 23 deletions
diff --git a/src/geometry/collider_components.rs b/src/geometry/collider_components.rs index 5923a42..111f527 100644 --- a/src/geometry/collider_components.rs +++ b/src/geometry/collider_components.rs @@ -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; @@ -210,27 +210,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.) pub struct ColliderMaterial { /// The friction coefficient of this collider. @@ -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(), } |
