collide 0.4.0

Simple extensible collision management
Documentation

Collide

crates.io docs.rs

A generic trait system for collision detection in Rust. Implement collision checks between arbitrary shapes while maintaining flexibility for the vector type.

Features

  • 🧩 Generic Collider trait for cross-library interoperability
  • 📐 Compatible with any vector types
  • 🚀 Supports 2D/3D/N-D collisions
  • 🔄 Bidirectional collision data with automatic perspective flipping

Example

use std::ops::{Add, Mul, Neg, Sub};

use collide::{Collider, CollisionInfo};

#[derive(Copy, Clone, Debug, PartialEq)]
struct Vec2(f32, f32);

impl Add for Vec2 {
    type Output = Self;
    fn add(self, rhs: Self) -> Self {
        Vec2(self.0 + rhs.0, self.1 + rhs.1)
    }
}
impl Sub for Vec2 {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self {
        Vec2(self.0 - rhs.0, self.1 - rhs.1)
    }
}
impl Mul<f32> for Vec2 {
    type Output = Self;
    fn mul(self, rhs: f32) -> Self {
        Vec2(self.0 * rhs, self.1 * rhs)
    }
}
impl Neg for Vec2 {
    type Output = Self;
    fn neg(self) -> Self {
        Vec2(-self.0, -self.1)
    }
}
impl Vec2 {
    fn magnitude(self) -> f32 {
        f32::sqrt(self.0 * self.0 + self.1 * self.1)
    }
    fn normalize(self) -> Self {
        let mag = self.magnitude();
        if mag == 0.0 { self } else { self * (1.0 / mag) }
    }
}

struct Sphere {
    center: Vec2,
    radius: f32,
}

impl Collider for Sphere {
    type Vector = Vec2;

    fn collision_info(&self, other: &Self) -> Option<CollisionInfo<Vec2>> {
        let delta = other.center - self.center;
        let distance = delta.magnitude();
        if distance > self.radius + other.radius || distance == 0.0 {
            return None;
        }
        let direction = delta.normalize();
        let min_distance = self.radius + other.radius;
        Some(CollisionInfo {
            self_contact: self.center + direction * self.radius,
            other_contact: other.center - direction * other.radius,
            vector: direction * (min_distance - distance),
        })
    }
}

let s1 = Sphere {
    center: Vec2(0.0, 0.0),
    radius: 1.0,
};
let s2 = Sphere {
    center: Vec2(1.5, 0.0),
    radius: 1.0,
};
assert!(s1.check_collision(&s2));

Design Goals

  1. Interoperability: Share colliders across physics engines
  2. Flexibility: Arbitrary dimensions (2D, 3D, etc.) and number types (f32, f64, etc.)
  3. Extensibility: New collider types without breaking existing implementations