summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kobert <d-kobert@web.de>2019-06-02 16:10:21 +0200
committerDennis Kobert <d-kobert@web.de>2019-06-02 16:10:21 +0200
commit483418d90d2167c1908315b603f2de676ec0f0aa (patch)
tree1a5effd86b2e2840fff42d89328c67fbc4126a7a
parent7d0f3cf2bec7a248aed699805542ad235e354753 (diff)
Fix interBox collision
-rw-r--r--game_server/src/collide.rs71
1 files changed, 62 insertions, 9 deletions
diff --git a/game_server/src/collide.rs b/game_server/src/collide.rs
index ba39720..9aab5c6 100644
--- a/game_server/src/collide.rs
+++ b/game_server/src/collide.rs
@@ -40,20 +40,33 @@ impl Collide<Vec2> for RBox {
impl Collide<AABox> for RBox {
fn collides(&self, other: &AABox) -> bool {
let other_size = other.pos + other.size;
- let v1_diff = other.pos + self.v1 * (-self.v1.scalar(&other.pos) / self.v1.distance2());
+
+ // project points onto a orthogonal line
+ let v1_diff = other.pos + self.v1 * (-self.v1.scalar(&(other.pos - self.pos)) / self.v1.distance2());
let v2_diff = other.pos + self.v2 * (-self.v2.scalar(&other.pos) / self.v2.distance2());
- let v1_diff_size = other_size + self.v1 * (-self.v1.scalar(&other_size) / self.v1.distance2());
- let v2_diff_size = other_size + self.v2 * (-self.v2.scalar(&other_size) / self.v2.distance2());
+ let v1_diff_size = other_size + self.v1 * (-self.v1.scalar(&(other_size - self.pos)) / self.v1.distance2());
+ let v2_diff_size = other_size + self.v2 * (-self.v2.scalar(&(other_size - self.pos)) / self.v2.distance2());
- let v1_dist = ((v1_diff - self.pos) / self.v2).x;
- let v2_dist = ((v2_diff - self.pos) / self.v1).x;
- let v1_dist_size = ((v1_diff_size - self.pos) / self.v2).x;
- let v2_dist_size = ((v2_diff_size - self.pos) / self.v1).x;
+ // calculate the distance
+ let v1_dist = ((v1_diff - self.pos) / self.v2);
+ let v2_dist = ((v2_diff - self.pos) / self.v1);
+ let v1_dist_size = ((v1_diff_size - self.pos) / self.v2);
+ let v2_dist_size = ((v2_diff_size - self.pos) / self.v1);
+
+ let v1_dist = if v1_dist.x.is_finite() {v1_dist.x} else {v1_dist.y};
+ let v2_dist = if v2_dist.x.is_finite() {v2_dist.x} else {v2_dist.y};
+ let v1_dist_size = if v1_dist_size.x.is_finite() {v1_dist_size.x} else {v1_dist_size.y};
+ let v2_dist_size = if v2_dist_size.x.is_finite() {v2_dist_size.x} else {v2_dist_size.y};
+
+ let minx = f32::min(self.pos.x, f32::min((self.pos + self.v1).x, (self.pos + self.v2).x));
+ let maxx = f32::max(self.pos.x, f32::max((self.pos + self.v1).x, (self.pos + self.v2).x));
+ let miny = f32::min(self.pos.y, f32::min((self.pos + self.v1).y, (self.pos + self.v2).y));
+ let maxy = f32::max(self.pos.y, f32::max((self.pos + self.v1).y, (self.pos + self.v2).y));
0.0 <= v1_dist_size && v1_dist <= 1.0
&& 0.0 <= v2_dist_size && v2_dist <= 1.0
- //v1_diff < self.pos + self.v2 && self.pos < v1_diff_size
- //&& v2_diff < self.pos + self.v1 && self.pos < v2_diff_size
+ && other.pos.x < maxx && minx < other.pos.x + other.size.x
+ && other.pos.y < maxy && miny < other.pos.y + other.size.y
}
}
@@ -159,4 +172,44 @@ impl<S, T: Collide<S>> Collide<S> for Vec<T> {
assert!(!(aa_box.collides(&c)));
}
+
+ #[test]
+ fn test_collide_rbox_rbox_intersecting() {
+ let a = Vec2{x: 1.0, y: 2.5};
+ let b = Vec2{x: 0.0, y: 2.5};
+ let c = Vec2{x: 3.0, y: 0.5};
+ let aa_box = RBox{pos: a, v1: b, v2: c};
+ let a = Vec2{x: 2.0, y: 3.5};
+ let b = Vec2{x: 3.0, y: 7.5};
+ let bb_box = AABox{pos: a, size: b};
+
+ assert!(aa_box.collides(&bb_box));
+ }
+
+ #[test]
+ fn test_collide_rbox_rbox_crossed() {
+ let a = Vec2{x: 2.0, y: 0.5};
+ let b = Vec2{x: 1.0, y: 0.0};
+ let c = Vec2{x: 0.0, y: 7.5};
+ let aa_box = RBox{pos: a, v1: b, v2: c};
+ let a = Vec2{x: 1.0, y: 3.5};
+ let b = Vec2{x: 5.0, y: 4.5};
+ let bb_box = AABox{pos: a, size: b};
+
+ assert!(aa_box.collides(&bb_box));
+ }
+
+ #[test]
+ fn test_not_collide_rbox_rbox() {
+ let a = Vec2{x: 1.0, y: 1.0};
+ let b = Vec2{x: 0.0, y: 1.0};
+ let c = Vec2{x: 1.0, y: 0.0};
+ let aa_box = RBox{pos: a, v1: b, v2: c};
+ let a = Vec2{x: 3.0, y: 3.5};
+ let b = Vec2{x: 3.0, y: 7.5};
+ let bb_box = AABox{pos: a, size: b};
+
+ assert!(!(aa_box.collides(&bb_box)));
+ }
+
}