rust/hwphysics/src/grid.rs
changeset 15850 44b49f255e31
parent 15849 64b0a5cead86
child 16010 5ba4d3a0c3eb
equal deleted inserted replaced
15849:64b0a5cead86 15850:44b49f255e31
     2     collision::{fppoint_round, CircleBounds, DetectedCollisions},
     2     collision::{fppoint_round, CircleBounds, DetectedCollisions},
     3     common::GearId,
     3     common::GearId,
     4 };
     4 };
     5 
     5 
     6 use fpnum::FPPoint;
     6 use fpnum::FPPoint;
     7 use integral_geometry::{GridIndex, Point, Size};
     7 use integral_geometry::{GridIndex, Point, PotSize};
     8 
     8 
     9 struct GridBin {
     9 struct GridBin {
    10     refs: Vec<GearId>,
    10     refs: Vec<GearId>,
    11     entries: Vec<CircleBounds>,
    11     entries: Vec<CircleBounds>,
    12 }
    12 }
    37 
    37 
    38 const GRID_BIN_SIZE: usize = 128;
    38 const GRID_BIN_SIZE: usize = 128;
    39 
    39 
    40 pub struct Grid {
    40 pub struct Grid {
    41     bins: Vec<GridBin>,
    41     bins: Vec<GridBin>,
    42     space_size: Size,
    42     space_size: PotSize,
    43     bins_count: Size,
    43     bins_count: PotSize,
    44     index: GridIndex,
    44     index: GridIndex,
    45 }
    45 }
    46 
    46 
    47 impl Grid {
    47 impl Grid {
    48     pub fn new(size: Size) -> Self {
    48     pub fn new(size: PotSize) -> Self {
    49         assert!(size.is_power_of_two());
    49         let bins_count =
    50         let bins_count = Size::new(size.width / GRID_BIN_SIZE, size.height / GRID_BIN_SIZE);
    50             PotSize::new(size.width() / GRID_BIN_SIZE, size.height() / GRID_BIN_SIZE).unwrap();
    51 
    51 
    52         Self {
    52         Self {
    53             bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(),
    53             bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(),
    54             space_size: size,
    54             space_size: size,
    55             bins_count,
    55             bins_count,
    56             index: Size::square(GRID_BIN_SIZE).to_grid_index(),
    56             index: PotSize::square(GRID_BIN_SIZE).unwrap().to_grid_index(),
    57         }
    57         }
       
    58     }
       
    59 
       
    60     fn linear_bin_index(&self, index: Point) -> usize {
       
    61         self.bins_count
       
    62             .linear_index(index.x as usize, index.y as usize)
    58     }
    63     }
    59 
    64 
    60     fn bin_index(&self, position: &FPPoint) -> Point {
    65     fn bin_index(&self, position: &FPPoint) -> Point {
    61         self.index.map(fppoint_round(position))
    66         self.index.map(fppoint_round(position))
    62     }
    67     }
    63 
    68 
    64     fn get_bin(&mut self, index: Point) -> &mut GridBin {
    69     fn get_bin(&mut self, index: Point) -> &mut GridBin {
    65         &mut self.bins[index.y as usize * self.bins_count.width + index.x as usize]
    70         let index = self.linear_bin_index(index);
       
    71         &mut self.bins[index]
    66     }
    72     }
    67 
    73 
    68     fn try_get_bin(&mut self, index: Point) -> Option<&mut GridBin> {
    74     fn try_get_bin(&mut self, index: Point) -> Option<&mut GridBin> {
    69         self.bins
    75         let index = self.linear_bin_index(index);
    70             .get_mut(index.y as usize * self.bins_count.width + index.x as usize)
    76         self.bins.get_mut(index)
    71     }
    77     }
    72 
    78 
    73     fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin {
    79     fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin {
    74         self.get_bin(self.bin_index(position))
    80         self.get_bin(self.bin_index(position))
    75     }
    81     }
    92                 self.remove_all(gear_id);
    98                 self.remove_all(gear_id);
    93             }
    99             }
    94         } else {
   100         } else {
    95             self.remove_all(gear_id);
   101             self.remove_all(gear_id);
    96         }
   102         }
    97 
       
    98     }
   103     }
    99 
   104 
   100     pub fn check_collisions(&self, collisions: &mut DetectedCollisions) {
   105     pub fn check_collisions(&self, collisions: &mut DetectedCollisions) {
   101         for bin in &self.bins {
   106         for bin in &self.bins {
   102             for (index, bounds) in bin.entries.iter().enumerate() {
   107             for (index, bounds) in bin.entries.iter().enumerate() {}
   103 
       
   104             }
       
   105         }
   108         }
   106     }
   109     }
   107 }
   110 }