aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/collider.rs
diff options
context:
space:
mode:
authorSébastien Crozet <sebcrozet@dimforge.com>2024-04-27 11:36:35 +0200
committerSébastien Crozet <sebastien@crozet.re>2024-04-30 23:10:46 +0200
commit664645159d21d85d321531ee73f5a0c3c1a7ea7b (patch)
tree1c32556e53033cbed440c45dd9451f71e24bf948 /src/geometry/collider.rs
parentc079452a478bb2f5d976cbba162e7f92252b505d (diff)
downloadrapier-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.rs44
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,
}
}