From 483418d90d2167c1908315b603f2de676ec0f0aa Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sun, 2 Jun 2019 16:10:21 +0200 Subject: Fix interBox collision --- game_server/src/collide.rs | 71 ++++++++++++++++++++++++++++++++++++++++------ 1 file 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 for RBox { impl Collide 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> Collide for Vec { 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))); + } + } -- cgit v1.2.3-54-g00ecf