use crate::maths::{Vec2, AABox, RBox}; pub trait Collide { fn collides(&self, other: &Rhs) -> bool; } impl Collide for Vec2 { fn collides(&self, other: &Self) -> bool { self == other } } impl Collide for AABox { fn collides(&self, other: &Vec2) -> bool { self.pos < *other && other < &(self.pos + self.size) } } impl Collide for AABox { fn collides(&self, other: &Self) -> bool { self.collides(&other.pos) || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0})) || self.collides(&(other.pos + Vec2{x: 0.0, y: other.size.y})) || self.collides(&(other.pos + other.size)) || other.collides(&(self.pos)) || other.collides(&(self.pos + Vec2{x: self.size.x, y: 0.0})) || other.collides(&(self.pos + Vec2{x: 0.0, y: self.size.y})) || other.collides(&(self.pos + self.size)) } } impl Collide for RBox { fn collides(&self, other: &Vec2) -> bool { let da = self.size.norm(); let dax = other.x - self.pos.x; let day = other.y - self.pos.y; let dot = dax * da.x + day * da.y; let px = self.pos.x + da.x * dot; let py = self.pos.y + da.y * dot; let p = Vec2{x: px, y: py}; if !(self.pos < p && p < self.pos + self.size) { return false; } let ddx = other.x-px; let ddy = other.y-py; let manhattenDistance = ddx + ddy; manhattenDistance < self.w } } impl Collide for RBox { fn collides(&self, other: &AABox) -> bool { self.collides(&other.pos) || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0})) || self.collides(&(other.pos + Vec2{x: 0.0, y: other.size.y})) || self.collides(&(other.pos + other.size)) || other.collides(&(self.pos)) || other.collides(&(self.pos + Vec2{x: self.size.x, y: 0.0})) || other.collides(&(self.pos + Vec2{x: 0.0, y: self.size.y})) || other.collides(&(self.pos + self.size)) } } impl> Collide for Vec { fn collides(&self, other: &S) -> bool { self.iter().any(|x| x.collides(other)) } }