rust/hwphysics/src/grid.rs
author alfadur
Fri, 09 Nov 2018 01:05:34 +0300
changeset 14178 a4c17cfaa4c9
child 14179 abbb74b9cb62
permissions -rw-r--r--
split hwphysics into modules
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14178
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     1
use crate::{
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     2
    common::GearId,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     3
    collision::{
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     4
        fppoint_round,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     5
        CircleBounds,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     6
        DetectedCollisions
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     7
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     8
};
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     9
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    10
use integral_geometry::{
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    11
    Point,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    12
    Size,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    13
    GridIndex
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    14
};
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    15
use fpnum::FPPoint;
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    16
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    17
struct GridBin {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    18
    refs: Vec<GearId>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    19
    static_entries: Vec<CircleBounds>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    20
    dynamic_entries: Vec<CircleBounds>
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    21
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    22
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    23
impl GridBin {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    24
    fn new() -> Self {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    25
        Self {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    26
            refs: vec![],
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    27
            static_entries: vec![],
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    28
            dynamic_entries: vec![]
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    29
        }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    30
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    31
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    32
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    33
const GRID_BIN_SIZE: usize = 256;
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    34
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    35
pub struct Grid {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    36
    bins: Vec<GridBin>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    37
    space_size: Size,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    38
    bins_count: Size,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    39
    index: GridIndex
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    40
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    41
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    42
impl Grid {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    43
    pub fn new(size: Size) -> Self {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    44
        assert!(size.is_power_of_two());
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    45
        let bins_count =
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    46
            Size::new(size.width / GRID_BIN_SIZE,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    47
                      size.height / GRID_BIN_SIZE);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    48
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    49
        Self {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    50
            bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(),
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    51
            space_size: size,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    52
            bins_count,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    53
            index: Size::square(GRID_BIN_SIZE).to_grid_index()
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    54
        }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    55
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    56
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    57
    fn bin_index(&self, position: &FPPoint) -> Point {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    58
        self.index.map(fppoint_round(position))
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    59
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    60
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    61
    fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    62
        let index = self.bin_index(position);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    63
        &mut self.bins[index.x as usize * self.bins_count.width + index.y as usize]
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    64
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    65
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    66
    pub fn insert_static(&mut self, gear_id: GearId, position: &FPPoint, bounds: &CircleBounds) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    67
        self.lookup_bin(position).static_entries.push(*bounds)
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    68
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    69
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    70
    pub fn insert_dynamic(&mut self, gear_id: GearId, position: &FPPoint, bounds: &CircleBounds) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    71
        self.lookup_bin(position).dynamic_entries.push(*bounds)
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    72
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    73
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    74
    pub fn check_collisions(&self, collisions: &mut DetectedCollisions) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    75
        for bin in &self.bins {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    76
            for bounds in &bin.dynamic_entries {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    77
                for other in &bin.dynamic_entries {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    78
                    if bounds.intersects(other) && bounds != other {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    79
                        collisions.push(0, 0, &bounds.center)
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    80
                    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    81
                }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    82
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    83
                for other in &bin.static_entries {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    84
                    if bounds.intersects(other) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    85
                        collisions.push(0, 0, &bounds.center)
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    86
                    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    87
                }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    88
            }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    89
        }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    90
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    91
}