rust/hwphysics/src/grid.rs
author Wuzzy <Wuzzy2@mail.ru>
Thu, 03 Jan 2019 19:46:48 +0100
changeset 14514 5ac181cb2396
parent 14179 abbb74b9cb62
child 14716 8e74d4eb89f5
permissions -rw-r--r--
Fix bee targeting fail across wrap world edge Previously, the bee always aimed for the light area, no matter where you actually put the target. It also got confused whenever it flew across the wrap world edge. How the bee works now: 1) The placed bee target is *not* recalculated when it was placed in the "gray" part of the wrap world edge. This allows for more fine-tuning. 1a) Place target in light area: bee aims for target light area 1b) Place target in gray area: bee aims for target, but flies to gray area first 2) Bee target is recalculated whenever bee passes the wrap world edge.
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
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    33
const GRID_BIN_SIZE: usize = 128;
14178
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
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    66
    pub fn insert_static(&mut self, gear_id: GearId, bounds: &CircleBounds) {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    67
        self.lookup_bin(&bounds.center).static_entries.push(*bounds)
14178
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    68
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    69
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    70
    pub fn insert_dynamic(&mut self, gear_id: GearId, bounds: &CircleBounds) {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    71
        self.lookup_bin(&bounds.center).dynamic_entries.push(*bounds)
14178
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
}