author | unC0Rr |
Mon, 03 Feb 2025 16:52:05 +0100 | |
changeset 16084 | 36862a9ec59b |
parent 15981 | 5ba4d3a0c3eb |
permissions | -rw-r--r-- |
15120 | 1 |
use crate::{ |
15981 | 2 |
collision::{CircleBounds, DetectedCollisions}, |
15120 | 3 |
common::GearId, |
4 |
}; |
|
5 |
||
6 |
use fpnum::FPPoint; |
|
15828 | 7 |
use integral_geometry::{GridIndex, Point, PotSize}; |
15120 | 8 |
|
9 |
struct GridBin { |
|
15827 | 10 |
refs: Vec<GearId>, |
11 |
entries: Vec<CircleBounds>, |
|
15120 | 12 |
} |
13 |
||
14 |
impl GridBin { |
|
15 |
fn new() -> Self { |
|
16 |
Self { |
|
15827 | 17 |
refs: vec![], |
18 |
entries: vec![], |
|
19 |
} |
|
20 |
} |
|
21 |
||
22 |
fn add(&mut self, gear_id: GearId, bounds: &CircleBounds) { |
|
23 |
self.refs.push(gear_id); |
|
24 |
self.entries.push(*bounds); |
|
25 |
} |
|
26 |
||
27 |
fn remove(&mut self, gear_id: GearId) -> bool { |
|
28 |
if let Some(pos) = self.refs.iter().position(|id| *id == gear_id) { |
|
29 |
self.refs.swap_remove(pos); |
|
30 |
self.entries.swap_remove(pos); |
|
31 |
true |
|
32 |
} else { |
|
33 |
false |
|
15120 | 34 |
} |
35 |
} |
|
36 |
} |
|
37 |
||
16084
36862a9ec59b
Update lib-hedgewars-engine to use newer versions of dependencies
unC0Rr
parents:
15981
diff
changeset
|
38 |
const GRID_BIN_SIZE: u32 = 128; |
15120 | 39 |
|
40 |
pub struct Grid { |
|
41 |
bins: Vec<GridBin>, |
|
15828 | 42 |
space_size: PotSize, |
43 |
bins_count: PotSize, |
|
15120 | 44 |
index: GridIndex, |
45 |
} |
|
46 |
||
47 |
impl Grid { |
|
15828 | 48 |
pub fn new(size: PotSize) -> Self { |
49 |
let bins_count = |
|
50 |
PotSize::new(size.width() / GRID_BIN_SIZE, size.height() / GRID_BIN_SIZE).unwrap(); |
|
15120 | 51 |
|
52 |
Self { |
|
53 |
bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(), |
|
54 |
space_size: size, |
|
55 |
bins_count, |
|
15828 | 56 |
index: PotSize::square(GRID_BIN_SIZE).unwrap().to_grid_index(), |
15120 | 57 |
} |
58 |
} |
|
59 |
||
16084
36862a9ec59b
Update lib-hedgewars-engine to use newer versions of dependencies
unC0Rr
parents:
15981
diff
changeset
|
60 |
fn linear_bin_index(&self, index: Point) -> u32 { |
15828 | 61 |
self.bins_count |
16084
36862a9ec59b
Update lib-hedgewars-engine to use newer versions of dependencies
unC0Rr
parents:
15981
diff
changeset
|
62 |
.linear_index(index.x as u32, index.y as u32) |
15828 | 63 |
} |
64 |
||
15120 | 65 |
fn bin_index(&self, position: &FPPoint) -> Point { |
15981 | 66 |
self.index.map(Point::from_fppoint(position)) |
15120 | 67 |
} |
68 |
||
15261 | 69 |
fn get_bin(&mut self, index: Point) -> &mut GridBin { |
15828 | 70 |
let index = self.linear_bin_index(index); |
16084
36862a9ec59b
Update lib-hedgewars-engine to use newer versions of dependencies
unC0Rr
parents:
15981
diff
changeset
|
71 |
&mut self.bins[index as usize] |
15261 | 72 |
} |
73 |
||
15757 | 74 |
fn try_get_bin(&mut self, index: Point) -> Option<&mut GridBin> { |
15828 | 75 |
let index = self.linear_bin_index(index); |
16084
36862a9ec59b
Update lib-hedgewars-engine to use newer versions of dependencies
unC0Rr
parents:
15981
diff
changeset
|
76 |
self.bins.get_mut(index as usize) |
15757 | 77 |
} |
78 |
||
15120 | 79 |
fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin { |
15261 | 80 |
self.get_bin(self.bin_index(position)) |
15120 | 81 |
} |
82 |
||
15827 | 83 |
pub fn insert(&mut self, gear_id: GearId, bounds: &CircleBounds) { |
84 |
self.lookup_bin(&bounds.center).add(gear_id, bounds); |
|
15261 | 85 |
} |
86 |
||
15827 | 87 |
fn remove_all(&mut self, gear_id: GearId) { |
88 |
for bin in &mut self.bins { |
|
89 |
if bin.remove(gear_id) { |
|
90 |
break; |
|
15757 | 91 |
} |
15261 | 92 |
} |
15120 | 93 |
} |
94 |
||
15827 | 95 |
pub fn remove(&mut self, gear_id: GearId, bounds: Option<&CircleBounds>) { |
96 |
if let Some(bounds) = bounds { |
|
97 |
if !self.lookup_bin(&bounds.center).remove(gear_id) { |
|
98 |
self.remove_all(gear_id); |
|
99 |
} |
|
100 |
} else { |
|
101 |
self.remove_all(gear_id); |
|
102 |
} |
|
103 |
} |
|
104 |
||
15120 | 105 |
pub fn check_collisions(&self, collisions: &mut DetectedCollisions) { |
106 |
for bin in &self.bins { |
|
15828 | 107 |
for (index, bounds) in bin.entries.iter().enumerate() {} |
15120 | 108 |
} |
109 |
} |
|
110 |
} |