|
- #![allow(dead_code)]
-
- use std::collections::HashSet;
-
- use glc::vector::Vector2f;
- use specs::world::Index;
-
- use crate::components::{Position, Shape};
-
- pub struct Raster {
- size: f32,
- quads: OffsetVec<OffsetVec<Quad>>,
- }
-
- #[derive(Default)]
- struct OffsetVec<T>
- where
- T: Default,
- {
- origin: usize,
- data: Vec<T>,
- }
-
- #[derive(Default)]
- pub struct Quad {
- entities: HashSet<Index>,
- }
-
- impl Raster {
- pub fn new(size: f32) -> Self {
- Self {
- size,
- quads: OffsetVec::new(),
- }
- }
-
- pub fn size(&self) -> f32 {
- self.size
- }
-
- pub fn insert(&mut self, id: Index, position: &Position) -> bool {
- self.update_quads(position, |q| {
- q.entities.insert(id);
- })
- }
-
- pub fn remove(&mut self, id: &Index, position: &Position) -> bool {
- self.update_quads(position, |q| {
- q.entities.remove(id);
- })
- }
-
- pub fn quads(&self) -> impl Iterator<Item = (isize, isize, &Quad)> {
- self.quads.data.iter().enumerate().flat_map(move |(x, vy)| {
- vy.data.iter().enumerate().map(move |(y, q)| {
- (
- x as isize - self.quads.origin as isize,
- y as isize - vy.origin as isize,
- q,
- )
- })
- })
- }
-
- fn update_quads<F>(&mut self, position: &Position, mut f: F) -> bool
- where
- F: FnMut(&mut Quad),
- {
- let p = position.pos;
-
- match position.shape {
- Shape::Dot => {
- let x = (p.x / self.size).round() as isize;
- let y = (p.y / self.size).round() as isize;
-
- f(self.quads.get_mut(x).get_mut(y));
-
- true
- }
- Shape::Circle(r) => {
- let s = self.size;
- let min_x = ((p.x - r) / s).round() as isize - 1;
- let max_x = ((p.x + r) / s).round() as isize + 1;
- let min_y = ((p.y - r) / s).round() as isize - 1;
- let max_y = ((p.y + r) / s).round() as isize + 1;
-
- let sr = r * r;
- let s = self.size / 2.0;
- let mut ret = false;
- for x in min_x..=max_x {
- for y in min_y..=max_y {
- let fx = x as f32 * self.size;
- let fy = y as f32 * self.size;
- let quad = self.quads.get_mut(x).get_mut(y);
-
- if (Vector2f::new(fx - s, fy - s) - p).length_sqr() < sr
- || (Vector2f::new(fx + s, fy - s) - p).length_sqr() < sr
- || (Vector2f::new(fx - s, fy + s) - p).length_sqr() < sr
- || (Vector2f::new(fx + s, fy + s) - p).length_sqr() < sr
- {
- f(quad);
- ret = true;
- }
- }
- }
-
- ret
- }
- }
- }
-
- fn get_quad(&self, x: isize, y: isize) -> Option<&Quad> {
- let row = self.quads.get(x)?;
- let quad = row.get(y)?;
-
- Some(quad)
- }
-
- fn get_quad_mut(&mut self, x: isize, y: isize) -> &mut Quad {
- self.quads.get_mut(x).get_mut(y)
- }
- }
-
- impl<T> OffsetVec<T>
- where
- T: Default,
- {
- pub fn new() -> Self {
- Self {
- origin: 0,
- data: Vec::new(),
- }
- }
-
- pub fn get(&self, i: isize) -> Option<&T> {
- let low = (0usize - self.origin) as isize;
- let high = (self.data.len() - self.origin) as isize - 1;
-
- if i < low || i > high {
- None
- } else {
- Some(&self.data[(i - low) as usize])
- }
- }
-
- pub fn get_mut(&mut self, i: isize) -> &mut T {
- let low = 0isize - self.origin as isize;
- let high = (self.data.len() - self.origin) as isize - 1;
-
- if i > high {
- let add = (i - low + 1) as usize;
- self.data.resize_with(add, Default::default);
- } else if i < low {
- let add = (low - i) as usize;
-
- let mut prefix = Vec::new();
- prefix.resize_with(add, Default::default);
- prefix.append(&mut self.data);
-
- self.data = prefix;
- self.origin += add;
- }
-
- &mut self.data[(i + self.origin as isize) as usize]
- }
- }
-
- impl Quad {
- pub fn is_empty(&self) -> bool {
- self.entities.is_empty()
- }
- }
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn vec_get_mut() {
- let mut vec = OffsetVec::<usize>::new();
-
- assert_eq!(vec.origin, 0);
- assert_eq!(vec.data, Vec::<usize>::new());
-
- *vec.get_mut(0) = 100;
-
- assert_eq!(vec.origin, 0);
- assert_eq!(vec.data, vec![100]);
-
- *vec.get_mut(1) = 101;
-
- assert_eq!(vec.origin, 0);
- assert_eq!(vec.data, vec![100, 101]);
-
- *vec.get_mut(-2) = 98;
-
- assert_eq!(vec.origin, 2);
- assert_eq!(vec.data, vec![98, 0, 100, 101]);
-
- *vec.get_mut(4) = 104;
-
- assert_eq!(vec.origin, 2);
- assert_eq!(vec.data, vec![98, 0, 100, 101, 0, 0, 104]);
-
- *vec.get_mut(-4) = 96;
-
- assert_eq!(vec.origin, 4);
- assert_eq!(vec.data, vec![96, 0, 98, 0, 100, 101, 0, 0, 104]);
- }
- }
|