Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose stop_at_penetration parameter and hide time-of-impact details behind an Option #419

Merged
merged 3 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions src/geometry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,35 +82,44 @@ impl RayIntersection {
pub struct Toi {
/// The time at which the objects touch.
pub toi: Real,
/// The local-space closest point on the first shape at the time of impact.
/// Detail about the impact points.
///
/// Undefined if `status` is `Penetrating`.
/// `None` if `status` is `Penetrating`.
pub details: Option<ToiDetails>,
/// The way the time-of-impact computation algorithm terminated.
pub status: TOIStatus,
}

/// In depth information about a time-of-impact (TOI) computation.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct ToiDetails {
/// The local-space closest point on the first shape at the time of impact.
pub witness1: Vect,
/// The local-space closest point on the second shape at the time of impact.
///
/// Undefined if `status` is `Penetrating`.
pub witness2: Vect,
/// The local-space outward normal on the first shape at the time of impact.
///
/// Undefined if `status` is `Penetrating`.
pub normal1: Vect,
/// The local-space outward normal on the second shape at the time of impact.
///
/// Undefined if `status` is `Penetrating`.
pub normal2: Vect,
/// The way the time-of-impact computation algorithm terminated.
pub status: TOIStatus,
}

impl Toi {
pub(crate) fn from_rapier(physics_scale: Real, toi: rapier::parry::query::TOI) -> Self {
/// Convert from internal `rapier::Toi`.
pub fn from_rapier(physics_scale: Real, toi: rapier::parry::query::TOI) -> Self {
let details = if toi.status != TOIStatus::Penetrating {
Some(ToiDetails {
witness1: (toi.witness1 * physics_scale).into(),
witness2: (toi.witness2 * physics_scale).into(),
normal1: toi.normal1.into(),
normal2: toi.normal2.into(),
})
} else {
None
};
Self {
toi: toi.toi,
witness1: (toi.witness1 * physics_scale).into(),
witness2: (toi.witness2 * physics_scale).into(),
normal1: toi.normal1.into(),
normal2: toi.normal2.into(),
status: toi.status,
details,
}
}
}
13 changes: 11 additions & 2 deletions src/plugin/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,11 +759,19 @@ impl RapierContext {
/// collider, and are in world space.
///
/// # Parameters
/// * `shape_pos` - The initial position of the shape to cast.
/// * `shape_pos` - The initial translation of the shape to cast.
/// * `shape_rot` - The rotation of the shape to cast.
/// * `shape_vel` - The constant velocity of the shape to cast (i.e. the cast direction).
/// * `shape` - The shape to cast.
/// * `max_toi` - The maximum time-of-impact that can be reported by this cast. This effectively
/// limits the distance traveled by the shape to `shapeVel.norm() * maxToi`.
/// * `stop_at_penetration` - If the casted shape starts in a penetration state with any
/// collider, two results are possible. If `stop_at_penetration` is `true` then, the
/// result will have a `toi` equal to `start_time`. If `stop_at_penetration` is `false`
/// then the nonlinear shape-casting will see if further motion wrt. the penetration normal
/// would result in tunnelling. If it does not (i.e. we have a separating velocity along
/// that normal) then the nonlinear shape-casting will attempt to find another impact,
/// at a time `> start_time` that could result in tunnelling.
/// * `filter`: set of rules used to determine which collider is taken into account by this scene query.
#[allow(clippy::too_many_arguments)]
pub fn cast_shape(
Expand All @@ -773,6 +781,7 @@ impl RapierContext {
shape_vel: Vect,
shape: &Collider,
max_toi: Real,
stop_at_penetration: bool,
filter: QueryFilter,
) -> Option<(Entity, Toi)> {
let scaled_transform = (shape_pos / self.physics_scale, shape_rot).into();
Expand All @@ -789,7 +798,7 @@ impl RapierContext {
&(shape_vel / self.physics_scale).into(),
&*scaled_shape.raw,
max_toi,
true,
stop_at_penetration,
filter,
)
})?;
Expand Down