summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kobert <d-kobert@web.de>2019-06-02 13:57:54 +0200
committerDennis Kobert <d-kobert@web.de>2019-06-02 13:57:54 +0200
commit7d0f3cf2bec7a248aed699805542ad235e354753 (patch)
tree580166a6bd5214d78a3fea57caf269be11cf06a4
parentee573fd1a02d290ec2aa9201d923805b6d998b14 (diff)
Fix rotated hitbox point interaction
implement according tests
-rw-r--r--game_server/src/collide.rs87
-rw-r--r--game_server/src/maths.rs23
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<AABox> for AABox {
impl Collide<Vec2> 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<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());
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<S, T: Collide<S>> Collide<S> for Vec<T> {
}
#[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<S, T: Collide<S>> Collide<S> for Vec<T> {
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<f32> 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<f32> for Vec2 {
+ type Output = Self;
+ fn div(self, scale: f32) -> Self {
+ Self {
+ x: self.x / scale,
+ y: self.y / scale
+ }
+ }
+}
+
+impl std::ops::Div<Vec2> 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<std::cmp::Ordering> {
if self.x <= other.x && self.y <= other.y {