Mostly implemented capsules
authorJustin Worthe <justin@worthe-it.co.za>
Wed, 12 Sep 2018 20:22:13 +0000 (22:22 +0200)
committerJustin Worthe <justin@worthe-it.co.za>
Wed, 12 Sep 2018 20:22:13 +0000 (22:22 +0200)
WIP: This is in SORE need of unit tests

src/geometry.rs
src/hitbox.rs

index 6f7f658..64414e0 100644 (file)
@@ -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 {
index 32f432f..75cc89b 100644 (file)
@@ -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
+}