diff options
Diffstat (limited to 'src/content/world')
| -rw-r--r-- | src/content/world/mines.rs | 152 |
1 files changed, 128 insertions, 24 deletions
diff --git a/src/content/world/mines.rs b/src/content/world/mines.rs index ae859bc..6ed4451 100644 --- a/src/content/world/mines.rs +++ b/src/content/world/mines.rs @@ -1,41 +1,145 @@ +use glam::{IVec2, Vec2}; + use crate::{ config::TILESET_SCALING, content::materials::MaterialId, proc_gen::{ - Biome, - tileset_loader::{Tile, TileOrientation, TilesetPixelType}, + Biome, TileCells, + tileset_loader::{Tile, TilesetPixelType}, }, - sim::cell::Cell, + sim::{cell::Cell, lib::marching_squares::compute_types}, }; -pub struct MinesBiome; +const FULL: [bool; (TILESET_SCALING * TILESET_SCALING) as usize] = + [true; (TILESET_SCALING * TILESET_SCALING) as usize]; + +const EMPTY: [bool; (TILESET_SCALING * TILESET_SCALING) as usize] = + [false; (TILESET_SCALING * TILESET_SCALING) as usize]; + +pub struct MinesBiome { + pixel_expansion_by_type: [[bool; (TILESET_SCALING * TILESET_SCALING) as usize]; 16], +} + +fn circular_pixel_expansion( + c: Vec2, + r: f32, +) -> [bool; (TILESET_SCALING * TILESET_SCALING) as usize] { + let rs = r.powi(2); + let mut ret = [false; (TILESET_SCALING * TILESET_SCALING) as usize]; + + for y in 0..TILESET_SCALING { + for x in 0..TILESET_SCALING { + // definitely can be optimized a lot + let dist = Vec2::new(x as f32, y as f32).distance_squared(c); + if dist <= rs { + ret[(x + y * TILESET_SCALING) as usize] = true; + } + } + } + + ret +} + +impl MinesBiome { + pub fn new() -> Self { + MinesBiome { + pixel_expansion_by_type: [ + // empty + EMPTY, + // BL + circular_pixel_expansion( + Vec2::new(0.0, TILESET_SCALING as f32 - 1.0), + TILESET_SCALING as f32, + ), + // BR + circular_pixel_expansion( + Vec2::new(TILESET_SCALING as f32 - 1.0, TILESET_SCALING as f32 - 1.0), + TILESET_SCALING as f32, + ), + // BL BR + FULL, + // TR + circular_pixel_expansion( + Vec2::new(TILESET_SCALING as f32 - 1.0, 0.0), + TILESET_SCALING as f32, + ), + // TR BL + FULL, + // TR BR + FULL, + // TR BR BL + FULL, + // TL + circular_pixel_expansion(Vec2::new(0.0, 0.0), TILESET_SCALING as f32), + // TL BL + FULL, + // TL BR + FULL, + // TL BR BL + FULL, + // TL TR + FULL, + // TL TR BL + FULL, + // TL TR BR + FULL, + // surrounded + FULL, + ], + } + } +} impl Biome for MinesBiome { - fn derive_world_from_tile(&self, tile: &Tile) -> Vec<Cell> { - let tp = TILESET_SCALING.pow(2) as u32; - let mut cells = - vec![Cell::void(); (tile.dimensions.short * tile.dimensions.long * tp) as usize]; - let ey = match tile.orientation { - TileOrientation::Horizontal => tile.dimensions.short, - TileOrientation::Vertical => tile.dimensions.long, - }; - let ex = match tile.orientation { - TileOrientation::Horizontal => tile.dimensions.long, - TileOrientation::Vertical => tile.dimensions.short, - }; + fn derive_world_from_tile(&self, tile: &Tile) -> TileCells { + let pixels = tile.size(); + let marched_pixels = compute_types(tile); + let size = pixels * TILESET_SCALING; + let mut cells = vec![Cell::void(); (size.x * size.y) as usize]; - for y in 0..ey { - for x in 0..ex { - let idx = (x + y * ex) * tp; - for i in 0..tp { - cells[(idx + i) as usize] = match tile.pixels[(x + y * ex) as usize] { - TilesetPixelType::Void => Cell::void(), - TilesetPixelType::Terrain => Cell::from_material(MaterialId::Dirt), + for py in 0..pixels.y { + for px in 0..pixels.x { + let pixel = tile.pixel_at(IVec2::new(px, py)); + let variant = marched_pixels[(px + py * (pixels.x + 1)) as usize]; + + // let pix = marched_pixels[(px + py * pixels.x) as usize]; + // let expansion_cells = [Cell::from_material(MaterialId::from_index( + // pix % MaterialId::ALL.len() as u8, + // )); + // (TILESET_SCALING * TILESET_SCALING) as usize]; + + // let origin = IVec2::new(px, py) * TILESET_SCALING; + // for i in 0..TILESET_SCALING { + // let y = i + origin.y; + // let row = (y * size.x + origin.x) as usize; + // cells[row..row + TILESET_SCALING as usize].copy_from_slice( + // &expansion_cells[i as usize..i as usize + TILESET_SCALING as usize], + // ); + // } + + let expansion = self.pixel_expansion_by_type[variant as usize]; + // TODO optimize + let expansion_cells = expansion.map(|c| { + if c { + Cell::from_material(MaterialId::Dirt) + } else { + Cell::void() } + }); + + let origin = IVec2::new(px, py) * TILESET_SCALING; + for i in 0..TILESET_SCALING { + let dst_y = i + origin.y; + let dst_row = (dst_y * size.x + origin.x) as usize; + let src_row = (i * TILESET_SCALING) as usize; + + cells[dst_row..dst_row + TILESET_SCALING as usize].copy_from_slice( + &expansion_cells[src_row..src_row + TILESET_SCALING as usize], + ); } } } - cells + TileCells { size, cells } } } |
