pub struct Contact {
pub point: Vec2,
pub normal: Vec2,
pub penetration: f32,
}Expand description
Contact information from a collision.
When two shapes collide, this struct contains all information needed to resolve the collision:
- point: The contact point in world space
- normal: The collision normal (points from A to B)
- penetration: How deep the shapes overlap (positive = overlapping)
§Example
use goud_engine::ecs::collision::{circle_circle_collision, Contact};
use goud_engine::core::math::Vec2;
let contact = circle_circle_collision(
Vec2::new(0.0, 0.0), 1.0,
Vec2::new(1.5, 0.0), 1.0
).unwrap();
assert!(contact.penetration > 0.0);
assert_eq!(contact.normal, Vec2::new(1.0, 0.0));Fields§
§point: Vec2Contact point in world space.
This is the point where the two shapes are touching. For penetrating collisions, this is typically the deepest penetration point.
normal: Vec2Collision normal (unit vector from shape A to shape B).
This vector points from the first shape to the second shape and is normalized to unit length. It indicates the direction to separate the shapes to resolve the collision.
penetration: f32Penetration depth (positive = overlapping, negative = separated).
This is the distance the shapes overlap. A positive value means the shapes are penetrating. To resolve the collision, move the shapes apart by this distance along the normal.
Implementations§
Source§impl Contact
impl Contact
Sourcepub fn new(point: Vec2, normal: Vec2, penetration: f32) -> Contact
pub fn new(point: Vec2, normal: Vec2, penetration: f32) -> Contact
Creates a new contact.
§Arguments
point- Contact point in world spacenormal- Collision normal (should be normalized)penetration- Penetration depth
§Example
use goud_engine::ecs::collision::Contact;
use goud_engine::core::math::Vec2;
let contact = Contact::new(
Vec2::new(1.0, 0.0),
Vec2::new(1.0, 0.0),
0.5
);Sourcepub fn is_colliding(&self) -> bool
pub fn is_colliding(&self) -> bool
Returns true if the contact represents a collision (positive penetration).
§Example
use goud_engine::ecs::collision::Contact;
use goud_engine::core::math::Vec2;
let colliding = Contact::new(Vec2::zero(), Vec2::unit_x(), 0.5);
let separated = Contact::new(Vec2::zero(), Vec2::unit_x(), -0.1);
assert!(colliding.is_colliding());
assert!(!separated.is_colliding());Sourcepub fn separation_distance(&self) -> f32
pub fn separation_distance(&self) -> f32
Returns the separation distance needed to resolve the collision.
This is the magnitude of the vector needed to separate the shapes.
§Example
use goud_engine::ecs::collision::Contact;
use goud_engine::core::math::Vec2;
let contact = Contact::new(Vec2::zero(), Vec2::unit_x(), 0.5);
assert_eq!(contact.separation_distance(), 0.5);Sourcepub fn separation_vector(&self) -> Vec2
pub fn separation_vector(&self) -> Vec2
Returns the separation vector needed to resolve the collision.
This is the vector (normal * penetration) that would separate the shapes.
§Example
use goud_engine::ecs::collision::Contact;
use goud_engine::core::math::Vec2;
let contact = Contact::new(
Vec2::zero(),
Vec2::new(1.0, 0.0),
0.5
);
assert_eq!(contact.separation_vector(), Vec2::new(0.5, 0.0));Sourcepub fn reversed(&self) -> Contact
pub fn reversed(&self) -> Contact
Returns a contact with reversed normal (swaps A and B).
This is useful when the collision detection function expects shapes in a specific order but you have them reversed.
§Example
use goud_engine::ecs::collision::Contact;
use goud_engine::core::math::Vec2;
let contact = Contact::new(
Vec2::zero(),
Vec2::new(1.0, 0.0),
0.5
);
let reversed = contact.reversed();
assert_eq!(reversed.normal, Vec2::new(-1.0, 0.0));
assert_eq!(reversed.penetration, contact.penetration);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 UnsafeUnpin 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<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
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<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().