From 7d0f3cf2bec7a248aed699805542ad235e354753 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sun, 2 Jun 2019 13:57:54 +0200 Subject: Fix rotated hitbox point interaction implement according tests --- game_server/src/collide.rs | 87 +++++++++++++++++++++++++++++++++++----------- game_server/src/maths.rs | 23 +++++++++++- 2 files changed, 89 insertions(+), 21 deletions(-) diff --git a/game_server/src/collide.rs b/game_server/src/collide.rs index d510a04..ba39720 100644 --- a/game_server/src/collide.rs +++ b/game_server/src/collide.rs @@ -25,24 +25,35 @@ impl Collide for AABox { impl Collide for RBox { fn collides(&self, other: &Vec2) -> bool { - let v1_diff = *other + self.v1 * (-self.v1.scalar(&other) / self.v1.distance2()); - let v2_diff = *other + self.v2 * (-self.v2.scalar(&other) / self.v2.distance2()); - - self.pos < v1_diff && v1_diff < self.pos + self.v2 - && self.pos < v2_diff && v2_diff < self.pos + self.v1 + let v1_diff = *other + self.v1 * (-self.v1.scalar(&(*other - self.pos)) / self.v1.distance2()); + let v2_diff = *other + self.v2 * (-self.v2.scalar(&(*other - 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; + 0.0 <= v1_dist && v2_dist <= 1.0 + && 0.0 <= v2_dist && v2_dist <= 1.0 + //v1_diff < self.pos + self.v2 && self.pos < v1_diff + //&& v2_diff < self.pos + self.v1 && self.pos < v2_diff } } 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()); let v2_diff = other.pos + self.v2 * (-self.v2.scalar(&other.pos) / self.v2.distance2()); - let other_size = other.pos + other.size; 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()); - self.pos < v1_diff + other.size && v1_diff < self.pos + self.v2 - && self.pos < v2_diff + other.size && v2_diff < self.pos + self.v1 + 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; + + 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 } } @@ -80,11 +91,7 @@ impl> Collide for Vec { } #[test] - fn test_not_collide_aabox_aabox() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: 3.0, y: 2.5}; - let c = Vec2{x: 0.5, y: 5.0}; - let aa_box = AABox{pos: a, size: b}; + fn test_not_collide_aabox_dot() { let a = Vec2{x: 1.0, y: 7.5}; let b = Vec2{x: 3.0, y: 2.5}; let c = Vec2{x: 0.5, y: 5.0}; @@ -92,23 +99,63 @@ impl> Collide for Vec { assert!(!(aa_box.collides(&c))); } - + #[test] - fn test_collide_Rbox_dot() { + fn test_collide_aabox_aabox_intersecting() { let a = Vec2{x: 1.0, y: 2.5}; + let b = Vec2{x: 3.0, y: 2.5}; + let aa_box = AABox{pos: a, size: b}; + let a = Vec2{x: 2.0, y: 3.5}; let b = Vec2{x: 3.0, y: 7.5}; - let c = Vec2{x: 1.5, y: 5.0}; + let bb_box = AABox{pos: a, size: b}; + + assert!(aa_box.collides(&bb_box)); + } + + #[test] + fn test_collide_aabox_aabox_crossed() { + let a = Vec2{x: 2.0, y: 0.5}; + let b = Vec2{x: 1.0, y: 7.5}; let aa_box = AABox{pos: a, size: b}; + 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_aabox_aabox() { + let a = Vec2{x: 1.0, y: 1.0}; + let b = Vec2{x: 1.0, y: 1.0}; + let aa_box = AABox{pos: a, size: b}; + 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))); + } + + #[test] + fn test_collide_Rbox_dot() { + let a = Vec2{x: 1.0, y: 1.0}; + let b = Vec2{x: 1.0, y: 1.0}; + let c = Vec2{x: 1.0, y: -1.0}; + let aa_box = RBox{pos: a, v1: b, v2: c}; + + let c = Vec2{x: 1.6, y: 0.6}; assert!(aa_box.collides(&c)); } #[test] fn test_not_collide_Rbox_dot() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: 3.0, y: 2.5}; - let c = Vec2{x: 0.5, y: 5.0}; - let aa_box = AABox{pos: a, size: b}; + let a = Vec2{x: 1.0, y: 1.0}; + let b = Vec2{x: 1.0, y: 1.0}; + let c = Vec2{x: 1.0, y: -1.0}; + let aa_box = RBox{pos: a, v1: b, v2: c}; + + let c = Vec2{x: 1.4, y: 0.4}; assert!(!(aa_box.collides(&c))); } diff --git a/game_server/src/maths.rs b/game_server/src/maths.rs index cc6c777..7c4ee2f 100644 --- a/game_server/src/maths.rs +++ b/game_server/src/maths.rs @@ -53,11 +53,32 @@ impl std::ops::Mul for Vec2 { fn mul(self, scale: f32) -> Self { Self { x: self.x * scale, - y: -self.y * scale + y: self.y * scale } } } +impl std::ops::Div for Vec2 { + type Output = Self; + fn div(self, scale: f32) -> Self { + Self { + x: self.x / scale, + y: self.y / scale + } + } +} + +impl std::ops::Div for Vec2 { + type Output = Self; + fn div(self, scale: Vec2) -> Self { + Self { + x: self.x / scale.x, + y: self.y / scale.y + } + } +} + + impl std::cmp::PartialOrd for Vec2 { fn partial_cmp(&self, other: &Self) -> Option { if self.x <= other.x && self.y <= other.y { -- cgit v1.2.3-54-g00ecf