diff options
| author | Sébastien Crozet <developer@crozet.re> | 2021-05-01 10:17:23 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-01 10:17:23 +0200 |
| commit | a385efc5582c7918f11c01a2b6bf26a46919d3a0 (patch) | |
| tree | c5b9c5e6fcb5561421e2b4b9d99f28e4c83c745e /src/geometry/collider_components.rs | |
| parent | aaf80bfa872c6f29b248cab8eb5658ab0d73cb4a (diff) | |
| parent | 2dfbd9ae92c139e306afc87994adac82489f30eb (diff) | |
| download | rapier-a385efc5582c7918f11c01a2b6bf26a46919d3a0.tar.gz rapier-a385efc5582c7918f11c01a2b6bf26a46919d3a0.tar.bz2 rapier-a385efc5582c7918f11c01a2b6bf26a46919d3a0.zip | |
Merge pull request #183 from dimforge/bundles
Make Rapier accept any kind of data storage instead of RigidBodySet/ColliderSet
Diffstat (limited to 'src/geometry/collider_components.rs')
| -rw-r--r-- | src/geometry/collider_components.rs | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/geometry/collider_components.rs b/src/geometry/collider_components.rs new file mode 100644 index 0000000..a02c706 --- /dev/null +++ b/src/geometry/collider_components.rs @@ -0,0 +1,270 @@ +use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle}; +use crate::geometry::{InteractionGroups, SAPProxyIndex, Shape, SharedShape, SolverFlags}; +use crate::math::{Isometry, Real}; +use crate::parry::partitioning::IndexedData; +use std::ops::Deref; + +/// The unique identifier of a collider added to a collider set. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[repr(transparent)] +pub struct ColliderHandle(pub crate::data::arena::Index); + +impl ColliderHandle { + /// Converts this handle into its (index, generation) components. + pub fn into_raw_parts(self) -> (u32, u32) { + self.0.into_raw_parts() + } + + /// Reconstructs an handle from its (index, generation) components. + pub fn from_raw_parts(id: u32, generation: u32) -> Self { + Self(crate::data::arena::Index::from_raw_parts(id, generation)) + } + + /// An always-invalid collider handle. + pub fn invalid() -> Self { + Self(crate::data::arena::Index::from_raw_parts( + crate::INVALID_U32, + crate::INVALID_U32, + )) + } +} + +impl IndexedData for ColliderHandle { + fn default() -> Self { + Self(IndexedData::default()) + } + + fn index(&self) -> usize { + self.0.index() + } +} + +bitflags::bitflags! { + #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] + /// Flags describing how the collider has been modified by the user. + pub struct ColliderChanges: u32 { + /// Flag indicating that any component of the collider has been modified. + const MODIFIED = 1 << 0; + /// Flag indicating that the `RigidBodyParent` component of the collider has been modified. + const PARENT = 1 << 1; // => BF & NF updates. + /// Flag indicating that the `RigidBodyPosition` component of the collider has been modified. + const POSITION = 1 << 2; // => BF & NF updates. + /// Flag indicating that the `RigidBodyGroups` component of the collider has been modified. + const GROUPS = 1 << 3; // => NF update. + /// Flag indicating that the `RigidBodyShape` component of the collider has been modified. + const SHAPE = 1 << 4; // => BF & NF update. NF pair workspace invalidation. + /// Flag indicating that the `RigidBodyType` component of the collider has been modified. + const TYPE = 1 << 5; // => NF update. NF pair invalidation. + } +} + +impl Default for ColliderChanges { + fn default() -> Self { + ColliderChanges::empty() + } +} + +impl ColliderChanges { + /// Do these changes justify a broad-phase update? + pub fn needs_broad_phase_update(self) -> bool { + self.intersects( + ColliderChanges::PARENT | ColliderChanges::POSITION | ColliderChanges::SHAPE, + ) + } + + /// Do these changes justify a narrow-phase update? + pub fn needs_narrow_phase_update(self) -> bool { + self.bits() > 1 + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +/// The type of collider. +pub enum ColliderType { + /// A collider that can generate contacts and contact events. + Solid, + /// A collider that can generate intersection and intersection events. + Sensor, +} + +impl ColliderType { + /// Is this collider a sensor? + pub fn is_sensor(self) -> bool { + self == ColliderType::Sensor + } +} + +#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +/// Data associated to a collider that takes part to a broad-phase algorithm. +pub struct ColliderBroadPhaseData { + pub(crate) proxy_index: SAPProxyIndex, +} + +impl Default for ColliderBroadPhaseData { + fn default() -> Self { + ColliderBroadPhaseData { + proxy_index: crate::INVALID_U32, + } + } +} + +/// The shape of a collider. +pub type ColliderShape = SharedShape; + +#[derive(Clone)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +/// The mass-properties of a collider. +pub enum ColliderMassProperties { + /// The collider is given a density. + /// + /// Its actual `MassProperties` are computed automatically with + /// the help of [`SharedShape::mass_properties`]. + Density(Real), + /// The collider is given explicit mass-properties. + MassProperties(Box<MassProperties>), +} + +impl Default for ColliderMassProperties { + fn default() -> Self { + ColliderMassProperties::Density(1.0) + } +} + +impl ColliderMassProperties { + /// The mass-properties of this collider. + /// + /// If `self` is the `Density` variant, then this computes the mass-properties based + /// on the given shape. + /// + /// If `self` is the `MassProperties` variant, then this returns the stored mass-properties. + pub fn mass_properties(&self, shape: &dyn Shape) -> MassProperties { + match self { + Self::Density(density) => shape.mass_properties(*density), + Self::MassProperties(mprops) => **mprops, + } + } +} + +#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +/// Information about the rigid-body this collider is attached to. +pub struct ColliderParent { + /// Handle of the rigid-body this collider is attached to. + pub handle: RigidBodyHandle, + /// Const position of this collider relative to its parent rigid-body. + pub pos_wrt_parent: Isometry<Real>, +} + +#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +/// The position of a collider. +pub struct ColliderPosition(pub Isometry<Real>); + +impl AsRef<Isometry<Real>> for ColliderPosition { + #[inline] + fn as_ref(&self) -> &Isometry<Real> { + &self.0 + } +} + +impl Deref for ColliderPosition { + type Target = Isometry<Real>; + #[inline] + fn deref(&self) -> &Isometry<Real> { + &self.0 + } +} + +impl Default for ColliderPosition { + fn default() -> Self { + Self::identity() + } +} + +impl ColliderPosition { + /// The identity position. + #[must_use] + pub fn identity() -> Self { + ColliderPosition(Isometry::identity()) + } +} + +impl<T> From<T> for ColliderPosition +where + Isometry<Real>: From<T>, +{ + fn from(position: T) -> Self { + Self(position.into()) + } +} + +#[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. + /// + /// The greater the value, the stronger the friction forces will be. + /// Should be `>= 0`. + pub friction: Real, + /// The restitution coefficient of this collider. + /// + /// Increase this value to make contacts with this collider more "bouncy". + /// Should be `>= 0` and should generally not be greater than `1` (perfectly elastic + /// collision). + pub restitution: Real, + /// The rule applied to combine the friction coefficients of two colliders in contact. + pub friction_combine_rule: CoefficientCombineRule, + /// The rule applied to combine the restitution coefficients of two colliders. + pub restitution_combine_rule: CoefficientCombineRule, + /// The solver flags attached to this collider in order to customize the way the + /// constraints solver will work with contacts involving this collider. + pub solver_flags: SolverFlags, +} + +impl ColliderMaterial { + /// Creates a new collider material with the given friction and restitution coefficients. + pub fn new(friction: Real, restitution: Real) -> Self { + Self { + friction, + restitution, + ..Default::default() + } + } +} + +impl Default for ColliderMaterial { + fn default() -> Self { + Self { + friction: 1.0, + restitution: 0.0, + friction_combine_rule: CoefficientCombineRule::default(), + restitution_combine_rule: CoefficientCombineRule::default(), + solver_flags: SolverFlags::default(), + } + } +} |
