diff options
| author | Sébastien Crozet <sebcrozet@dimforge.com> | 2024-04-27 11:36:35 +0200 |
|---|---|---|
| committer | Sébastien Crozet <sebastien@crozet.re> | 2024-04-30 23:10:46 +0200 |
| commit | 664645159d21d85d321531ee73f5a0c3c1a7ea7b (patch) | |
| tree | 1c32556e53033cbed440c45dd9451f71e24bf948 /src/geometry/collider.rs | |
| parent | c079452a478bb2f5d976cbba162e7f92252b505d (diff) | |
| download | rapier-664645159d21d85d321531ee73f5a0c3c1a7ea7b.tar.gz rapier-664645159d21d85d321531ee73f5a0c3c1a7ea7b.tar.bz2 rapier-664645159d21d85d321531ee73f5a0c3c1a7ea7b.zip | |
feat: implement collision skin
Diffstat (limited to 'src/geometry/collider.rs')
| -rw-r--r-- | src/geometry/collider.rs | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index c83535e..617881a 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -9,7 +9,7 @@ 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::bounding_volume::{Aabb, BoundingVolume}; use parry::shape::{Shape, TriMeshFlags}; #[cfg(feature = "dim3")] @@ -30,6 +30,7 @@ pub struct Collider { pub(crate) material: ColliderMaterial, pub(crate) flags: ColliderFlags, pub(crate) bf_data: ColliderBroadPhaseData, + collision_skin: Real, contact_force_event_threshold: Real, /// User-defined data associated to this collider. pub user_data: u128, @@ -109,6 +110,7 @@ impl Collider { bf_data: _bf_data, // Internal ids must not be overwritten. contact_force_event_threshold, user_data, + collision_skin, } = other; if self.parent.is_none() { @@ -123,6 +125,7 @@ impl Collider { self.user_data = *user_data; self.flags = *flags; self.changes = ColliderChanges::all(); + self.collision_skin = *collision_skin; } /// The physics hooks enabled for this collider. @@ -155,6 +158,16 @@ impl Collider { self.flags.active_collision_types = active_collision_types; } + /// The collision skin of this collider. + pub fn collision_skin(&self) -> Real { + self.collision_skin + } + + /// Sets the collision skin of this collider. + pub fn set_collision_skin(&mut self, skin_thickness: Real) { + self.collision_skin = skin_thickness; + } + /// The friction coefficient of this collider. pub fn friction(&self) -> Real { self.material.friction @@ -437,10 +450,21 @@ impl Collider { } /// Compute the axis-aligned bounding box of this collider. + /// + /// This AABB doesn’t take into account the collider’s collision skin. + /// [`Collider::collision_skin`]. pub fn compute_aabb(&self) -> Aabb { self.shape.compute_aabb(&self.pos) } + /// Compute the axis-aligned bounding box of this collider, taking into account the + /// [`Collider::collision_skin`] and prediction distance. + pub fn compute_collision_aabb(&self, prediction: Real) -> Aabb { + self.shape + .compute_aabb(&self.pos) + .loosened(self.collision_skin + prediction) + } + /// Compute the axis-aligned bounding box of this collider moving from its current position /// to the given `next_position` pub fn compute_swept_aabb(&self, next_position: &Isometry<Real>) -> Aabb { @@ -495,6 +519,8 @@ pub struct ColliderBuilder { pub enabled: bool, /// The total force magnitude beyond which a contact force event can be emitted. pub contact_force_event_threshold: Real, + /// An extract thickness around the collider shape to keep them further apart when in collision. + pub collision_skin: Real, } impl ColliderBuilder { @@ -517,6 +543,7 @@ impl ColliderBuilder { active_events: ActiveEvents::empty(), enabled: true, contact_force_event_threshold: 0.0, + collision_skin: 0.0, } } @@ -946,6 +973,20 @@ impl ColliderBuilder { self } + /// Sets the collision skin of the collider. + /// + /// The collision skin acts as if the collider was enlarged with a skin of width `skin_thickness` + /// around it, keeping objects further apart when colliding. + /// + /// A non-zero collision skin can increase performance, and in some cases, stability. However + /// it creates a small gap between colliding object (equal to the sum of their skin). If the + /// skin is sufficiently small, this might not be visually significant or can be hidden by the + /// rendering assets. + pub fn collision_skin(mut self, skin_thickness: Real) -> Self { + self.collision_skin = skin_thickness; + self + } + /// Enable or disable the collider after its creation. pub fn enabled(mut self, enabled: bool) -> Self { self.enabled = enabled; @@ -993,6 +1034,7 @@ impl ColliderBuilder { flags, coll_type, contact_force_event_threshold: self.contact_force_event_threshold, + collision_skin: self.collision_skin, user_data: self.user_data, } } |
