aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/collider_components.rs
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2021-05-01 10:17:23 +0200
committerGitHub <noreply@github.com>2021-05-01 10:17:23 +0200
commita385efc5582c7918f11c01a2b6bf26a46919d3a0 (patch)
treec5b9c5e6fcb5561421e2b4b9d99f28e4c83c745e /src/geometry/collider_components.rs
parentaaf80bfa872c6f29b248cab8eb5658ab0d73cb4a (diff)
parent2dfbd9ae92c139e306afc87994adac82489f30eb (diff)
downloadrapier-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.rs270
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(),
+ }
+ }
+}