summaryrefslogtreecommitdiff
path: root/game_server/src/collide.rs
blob: 21ec99cac547f9ac3658112577a6090a9e4e8de9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use crate::maths::{Vec2, AABox, RBox};

pub trait Collide<Rhs> {
    fn collides(&self, other: &Rhs) -> bool;
}

impl Collide<Vec2> for Vec2 {
    fn collides(&self, other: &Self) -> bool {
        self == other
    }
}

impl Collide<Vec2> for AABox {
    fn collides(&self, other: &Vec2) -> bool {
        self.pos < *other && other < &(self.pos + self.size) 
    }
}

impl Collide<AABox> for AABox {
    fn collides(&self, other: &Self) -> bool {
        self.collides(&other.pos)
        || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0}))
        || self.collides(&(other.pos + Vec2{x: 0.0, y: other.size.y}))
        || self.collides(&(other.pos + other.size))

        || other.collides(&(self.pos))
        || other.collides(&(self.pos + Vec2{x: self.size.x, y: 0.0}))
        || other.collides(&(self.pos + Vec2{x: 0.0, y: self.size.y}))
        || other.collides(&(self.pos + self.size))
    }
}

impl Collide<Vec2> for RBox {
    fn collides(&self, other: &Vec2) -> bool {

        let da = self.size.norm();
        let dax = other.x - self.pos.x;
        let day = other.y - self.pos.y;
        
        let dot = dax * da.x + day * da.y;
        let px = self.pos.x + dx * dot;
        let py = self.pos.y + da.y * dot;
       
        let p = Vec2{x: px, y: py};
        if !(self.pos < p && p < self.pos + self.size) {
            return false; 
        } 

        let ddx = other.x-px; 
        let ddy = other.y-py;
        let manhattenDistance = ddx + ddy;

        manhattenDistance < self.w 
    }
}

impl Collide<AABox> for RBox {
    fn collides(&self, other: &Box) -> bool {
        self.collides(&other.pos)
        || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0}))
        || self.collides(&(other.pos + Vec2{x: 0.0, y: other.size.y}))
        || self.collides(&(other.pos + other.size))

        || other.collides(&(self.pos))
        || other.collides(&(self.pos + Vec2{x: self.size.x, y: 0.0}))
        || other.collides(&(self.pos + Vec2{x: 0.0, y: self.size.y}))
        || other.collides(&(self.pos + self.size))
        
    }
}

impl<S, T: Collide<S>> Collide<S> for Vec<T> {
    fn collides(&self, other: &S) -> bool {
        self.iter().any(|x| x.collides(other))
    }
}