- // pub fn new(gravity: Point<f64>) -> Self {
- // let seed = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs() as u32;
- // let mut lvl = Level { gravity, grid: Grid::generate(seed, 10), iterations: 10, walls: vec!() };
- // lvl.filter_regions();
- // lvl
- // }
+ pub fn new(gravity: Point<f64>, grid: Grid<bool>, mut walls: Vec<Rc<WallRegion>>) -> Self {
+ let size = (2560, 1440); // TODO: get actual size from walls or something
+ let wall_grid = Level::build_wall_grid(&mut walls, &size.into());
+ dbg!(&wall_grid.cell_size);
+ Level {
+ gravity,
+ grid,
+ walls,
+ wall_grid,
+ }
+ }
+
+ /// Creates a grid of wall edges for fast lookup
+ fn build_wall_grid(walls: &mut Vec<Rc<WallRegion>>, lvlsize: &Dimension<usize>) -> Grid<Vec<Rc<WallEdge>>> {
+ let size = dimen!(lvlsize.width / 20, lvlsize.height / 20); // TODO: make sure all walls fit within the grid bounds
+ let cs = point!(lvlsize.width / size.width, lvlsize.height / size.height);
+ //let cs = point!(cell_size.width as f64, cell_size.height as f64);
+ let mut grid = vec!(vec!(vec!(); size.height); size.width);
+
+ for wall in walls {
+ for edge in &wall.edges {
+ // TODO: include cells that this edge overlaps
+ for p in &[edge.p1, edge.p2] {
+ let p = point!(p.x as usize, p.y as usize) / cs;
+ grid[0.max(p.x as usize).min(size.width - 1)][0.max(p.y as usize).min(size.height - 1)].push(Rc::clone(edge));
+ }
+ }
+ }
+
+ Grid {
+ size,
+ cell_size: dimen!(cs.x, cs.y),
+ cells: grid,
+ }
+ }