From 0d40cefa158f6273c37d6f1eacce50ffb637a523 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Wed, 12 Sep 2018 22:22:13 +0200 Subject: Mostly implemented capsules WIP: This is in SORE need of unit tests --- src/geometry.rs | 24 ++++++++++++++++++++++++ src/hitbox.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/geometry.rs b/src/geometry.rs index 6f7f658..64414e0 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -1,4 +1,5 @@ use std::ops::*; +use std::f64; #[derive(Debug, Clone, Copy, PartialEq)] pub struct Vec2d { @@ -35,6 +36,29 @@ impl Vec2d { y: self.y / mag } } + + pub fn dot(&self, other: Vec2d) -> f64 { + (self.x * other.x) + (self.y * other.y) + } +} + +pub struct LineSegment { + pub start: Vec2d, + pub end: Vec2d +} + +impl LineSegment { + pub fn distance(&self, other: Vec2d) -> f64 { + let length_squared = self.start.distance_squared(self.end); + if length_squared == 0.0 { + return self.start.distance(other); + } + + let t = f64::max(0., f64::min(1., (other - self.start).dot(self.end - self.start) / length_squared)); + let projection = self.start + (self.end - self.start) * t; + other.distance(projection) + } + } impl Add for Vec2d { diff --git a/src/hitbox.rs b/src/hitbox.rs index 32f432f..75cc89b 100644 --- a/src/hitbox.rs +++ b/src/hitbox.rs @@ -2,7 +2,8 @@ use geometry::*; pub enum Hitbox { Circle(CircleHitbox), - Point(PointHitbox) + Point(PointHitbox), + Capsule(CapsuleHitbox) } pub struct CircleHitbox { @@ -14,6 +15,11 @@ pub struct PointHitbox { pub pos: Vec2d } +pub struct CapsuleHitbox { + pub line: LineSegment, + pub radius: f64 +} + impl Hitbox { pub fn intersect(a: &Hitbox, b: &Hitbox) -> bool { use self::Hitbox::*; @@ -22,7 +28,12 @@ impl Hitbox { (Circle(x), Circle(y)) => circles_intersect(x, y), (Circle(x), Point(y)) => circle_point_intersect(x, y), (Point(x), Circle(y)) => circle_point_intersect(y, x), - (Point(x), Point(y)) => points_intersect(x, y) + (Point(x), Point(y)) => points_intersect(x, y), + (Capsule(x), Capsule(y)) => capsules_intersect(x, y), + (Capsule(x), Circle(y)) => capsule_circle_intersect(x, y), + (Circle(x), Capsule(y)) => capsule_circle_intersect(y, x), + (Capsule(x), Point(y)) => capsule_point_intersect(x, y), + (Point(x), Capsule(y)) => capsule_point_intersect(y, x), } } } @@ -38,3 +49,15 @@ fn circle_point_intersect(x: &CircleHitbox, y: &PointHitbox) -> bool { fn points_intersect(x: &PointHitbox, y: &PointHitbox) -> bool { x.pos == y.pos } + +fn capsules_intersect(x: &CapsuleHitbox, y: &CapsuleHitbox) -> bool { + true //TODO +} + +fn capsule_circle_intersect(x: &CapsuleHitbox, y: &CircleHitbox) -> bool { + x.line.distance(y.pos) <= x.radius + y.radius +} + +fn capsule_point_intersect(x: &CapsuleHitbox, y: &PointHitbox) -> bool { + x.line.distance(y.pos) <= x.radius +} -- cgit v1.2.3