pub struct Contact {
pub point1: Point<f32>,
pub point2: Point<f32>,
pub normal1: Unit<Vector<f32>>,
pub normal2: Unit<Vector<f32>>,
pub dist: f32,
}Expand description
Geometric description of a contact between two shapes.
A contact represents the point(s) where two shapes touch or penetrate. This structure contains all the information needed to resolve collisions: contact points, surface normals, and penetration depth.
§Contact States
A Contact can represent different collision states:
- Touching (
dist ≈ 0.0): Shapes are just barely in contact - Penetrating (
dist < 0.0): Shapes are overlapping (negative distance = penetration depth) - Separated (
dist > 0.0): Shapes are close but not touching (rarely used; seeclosest_pointsinstead)
§Coordinate Systems
Contact data can be expressed in different coordinate systems:
- World space: Both shapes’ transformations applied;
normal2 = -normal1 - Local space: Relative to one shape’s coordinate system
§Use Cases
- Physics simulation: Compute collision response forces
- Collision resolution: Push objects apart when penetrating
- Trigger detection: Detect when objects touch without resolving
§Example
use parry3d::query::contact;
use parry3d::shape::Ball;
use nalgebra::{Isometry3, Vector3};
let ball1 = Ball::new(1.0);
let ball2 = Ball::new(1.0);
// Overlapping balls (centers 1.5 units apart, combined radii = 2.0)
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(1.5, 0.0, 0.0);
if let Ok(Some(contact)) = contact(&pos1, &ball1, &pos2, &ball2, 0.0) {
// Penetration depth (negative distance)
assert!(contact.dist < 0.0);
println!("Penetration: {}", -contact.dist); // 0.5 units
// Normal points from shape 1 toward shape 2
println!("Normal: {:?}", contact.normal1);
// Contact points are on each shape's surface
println!("Point on ball1: {:?}", contact.point1);
println!("Point on ball2: {:?}", contact.point2);
}Fields§
§point1: Point<f32>Position of the contact point on the first shape’s surface.
This is the point on shape 1 that is closest to (or penetrating into) shape 2. Expressed in the same coordinate system as the contact (world or local space).
point2: Point<f32>Position of the contact point on the second shape’s surface.
This is the point on shape 2 that is closest to (or penetrating into) shape 1. When shapes are penetrating, this point may be inside shape 1.
normal1: Unit<Vector<f32>>Contact normal pointing outward from the first shape.
This unit vector points from shape 1 toward shape 2, perpendicular to the contact surface. Used to compute separation direction and collision response forces for shape 1.
normal2: Unit<Vector<f32>>Contact normal pointing outward from the second shape.
In world space, this is always equal to -normal1. In local space coordinates,
it may differ due to different shape orientations.
dist: f32Signed distance between the two contact points.
- Positive: Shapes are separated (distance between surfaces)
- Zero: Shapes are exactly touching
- Negative: Shapes are penetrating (absolute value = penetration depth)
For collision resolution, use -dist as the penetration depth when dist < 0.0.
Implementations§
Source§impl Contact
impl Contact
Sourcepub fn new(
point1: Point<f32>,
point2: Point<f32>,
normal1: Unit<Vector<f32>>,
normal2: Unit<Vector<f32>>,
dist: f32,
) -> Self
pub fn new( point1: Point<f32>, point2: Point<f32>, normal1: Unit<Vector<f32>>, normal2: Unit<Vector<f32>>, dist: f32, ) -> Self
Creates a new contact with the given parameters.
§Arguments
point1- Contact point on the first shape’s surfacepoint2- Contact point on the second shape’s surfacenormal1- Unit normal pointing outward from shape 1normal2- Unit normal pointing outward from shape 2dist- Signed distance (negative = penetration depth)
§Example
use parry3d::query::Contact;
use nalgebra::{Point3, Unit, Vector3};
// Create a contact representing two spheres touching
let point1 = Point3::new(1.0, 0.0, 0.0);
let point2 = Point3::new(2.0, 0.0, 0.0);
let normal1 = Unit::new_normalize(Vector3::new(1.0, 0.0, 0.0));
let normal2 = Unit::new_normalize(Vector3::new(-1.0, 0.0, 0.0));
let contact = Contact::new(point1, point2, normal1, normal2, 0.0);
assert_eq!(contact.dist, 0.0); // Touching, not penetratingSource§impl Contact
impl Contact
Sourcepub fn flipped(self) -> Self
pub fn flipped(self) -> Self
Returns a new contact containing the swapped points and normals of self.
Sourcepub fn transform_by_mut(&mut self, pos1: &Isometry<f32>, pos2: &Isometry<f32>)
pub fn transform_by_mut(&mut self, pos1: &Isometry<f32>, pos2: &Isometry<f32>)
Transform the points and normals from this contact by the given transformations.
Sourcepub fn transform1_by_mut(&mut self, pos: &Isometry<f32>)
pub fn transform1_by_mut(&mut self, pos: &Isometry<f32>)
Transform self.point1 and self.normal1 by the pos.
Trait Implementations§
impl Copy for Contact
impl StructuralPartialEq for Contact
Auto Trait Implementations§
impl Freeze for Contact
impl RefUnwindSafe for Contact
impl Send for Contact
impl Sync for Contact
impl Unpin for Contact
impl UnwindSafe for Contact
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.