rust/hwphysics/src/grid.rs
author Wuzzy <Wuzzy2@mail.ru>
Sat, 15 Jun 2019 03:27:06 +0200
changeset 15147 d97f0b96e45f
parent 15125 febccab419b1
child 15266 501dfa1c8deb
permissions -rw-r--r--
Restrict object placement between leftX and rightX
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15125
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     1
use crate::{
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     2
    collision::{fppoint_round, CircleBounds, DetectedCollisions},
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     3
    common::GearId,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     4
};
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     5
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     6
use fpnum::FPPoint;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     7
use integral_geometry::{GridIndex, Point, Size};
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     8
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
     9
struct GridBin {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    10
    refs: Vec<GearId>,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    11
    static_entries: Vec<CircleBounds>,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    12
    dynamic_entries: Vec<CircleBounds>,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    13
}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    14
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    15
impl GridBin {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    16
    fn new() -> Self {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    17
        Self {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    18
            refs: vec![],
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    19
            static_entries: vec![],
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    20
            dynamic_entries: vec![],
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    21
        }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    22
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    23
}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    24
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    25
const GRID_BIN_SIZE: usize = 128;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    26
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    27
pub struct Grid {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    28
    bins: Vec<GridBin>,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    29
    space_size: Size,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    30
    bins_count: Size,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    31
    index: GridIndex,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    32
}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    33
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    34
impl Grid {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    35
    pub fn new(size: Size) -> Self {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    36
        assert!(size.is_power_of_two());
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    37
        let bins_count = Size::new(size.width / GRID_BIN_SIZE, size.height / GRID_BIN_SIZE);
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    38
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    39
        Self {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    40
            bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    41
            space_size: size,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    42
            bins_count,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    43
            index: Size::square(GRID_BIN_SIZE).to_grid_index(),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    44
        }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    45
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    46
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    47
    fn bin_index(&self, position: &FPPoint) -> Point {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    48
        self.index.map(fppoint_round(position))
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    49
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    50
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    51
    fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    52
        let index = self.bin_index(position);
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    53
        &mut self.bins[index.x as usize * self.bins_count.width + index.y as usize]
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    54
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    55
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    56
    pub fn insert_static(&mut self, gear_id: GearId, bounds: &CircleBounds) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    57
        self.lookup_bin(&bounds.center).static_entries.push(*bounds)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    58
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    59
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    60
    pub fn insert_dynamic(&mut self, gear_id: GearId, bounds: &CircleBounds) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    61
        self.lookup_bin(&bounds.center)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    62
            .dynamic_entries
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    63
            .push(*bounds)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    64
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    65
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    66
    pub fn check_collisions(&self, collisions: &mut DetectedCollisions) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    67
        for bin in &self.bins {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    68
            for bounds in &bin.dynamic_entries {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    69
                for other in &bin.dynamic_entries {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    70
                    if bounds.intersects(other) && bounds != other {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    71
                        collisions.push(0, 0, &bounds.center)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    72
                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    73
                }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    74
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    75
                for other in &bin.static_entries {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    76
                    if bounds.intersects(other) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    77
                        collisions.push(0, 0, &bounds.center)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    78
                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    79
                }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    80
            }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    81
        }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    82
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14721
diff changeset
    83
}