tile_mipmapper: store tile coordinates in nested map/set

Use the same data structure as the frontend.
This commit is contained in:
Matthias Schiffer 2023-07-02 22:15:25 +02:00
parent 216aa6ceec
commit b63a18ad6f
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
2 changed files with 50 additions and 17 deletions

View file

@ -1,4 +1,5 @@
use std::{ use std::{
collections::{BTreeMap, BTreeSet},
fmt::Debug, fmt::Debug,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
@ -19,6 +20,19 @@ impl Debug for TileCoords {
} }
} }
#[derive(Debug, Clone, Default)]
pub struct TileCoordMap(pub BTreeMap<i32, BTreeSet<i32>>);
impl TileCoordMap {
pub fn contains(&self, coords: TileCoords) -> bool {
let Some(xs) = self.0.get(&coords.z) else {
return false;
};
xs.contains(&coords.x)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessedChunk { pub struct ProcessedChunk {
pub blocks: Box<layer::BlockArray>, pub blocks: Box<layer::BlockArray>,

View file

@ -15,20 +15,23 @@ impl<'a> TileMipmapper<'a> {
TileMipmapper { config } TileMipmapper { config }
} }
fn done(tiles: &BTreeSet<TileCoords>) -> bool { fn done(tiles: &TileCoordMap) -> bool {
tiles tiles
.into_iter() .0
.all(|TileCoords { x, z }| (-1..=0).contains(x) && (-1..=0).contains(z)) .iter()
.all(|(z, xs)| (-1..=0).contains(z) && xs.iter().all(|x| (-1..=0).contains(x)))
} }
fn map_coords(tiles: &BTreeSet<TileCoords>) -> BTreeSet<TileCoords> { fn map_coords(tiles: &TileCoordMap) -> TileCoordMap {
let mut ret = BTreeSet::new(); let mut ret = TileCoordMap::default();
for coords in tiles { for (&z, xs) in &tiles.0 {
ret.insert(TileCoords { for &x in xs {
x: coords.x >> 1, let xt = x >> 1;
z: coords.z >> 1, let zt = z >> 1;
});
ret.0.entry(zt).or_default().insert(xt);
}
} }
ret ret
@ -39,7 +42,7 @@ impl<'a> TileMipmapper<'a> {
kind: TileKind, kind: TileKind,
level: usize, level: usize,
coords: TileCoords, coords: TileCoords,
prev: &BTreeSet<TileCoords>, prev: &TileCoordMap,
) -> Result<()> ) -> Result<()>
where where
[P::Subpixel]: image::EncodableLayout, [P::Subpixel]: image::EncodableLayout,
@ -65,7 +68,7 @@ impl<'a> TileMipmapper<'a> {
x: 2 * coords.x + dx, x: 2 * coords.x + dx,
z: 2 * coords.z + dz, z: 2 * coords.z + dz,
}; };
if !prev.contains(&source_coords) { if !prev.contains(source_coords) {
continue; continue;
} }
@ -97,8 +100,16 @@ impl<'a> TileMipmapper<'a> {
}) })
} }
pub fn run(self, tiles: BTreeSet<TileCoords>) -> Result<Vec<BTreeSet<TileCoords>>> { pub fn run(self, tiles: BTreeSet<TileCoords>) -> Result<Vec<TileCoordMap>> {
let mut tile_stack = vec![tiles]; let mut tile_stack = {
let mut tile_map = TileCoordMap::default();
for TileCoords { x, z } in tiles {
tile_map.0.entry(z).or_default().insert(x);
}
vec![tile_map]
};
loop { loop {
let level = tile_stack.len(); let level = tile_stack.len();
@ -112,9 +123,17 @@ impl<'a> TileMipmapper<'a> {
let next = Self::map_coords(prev); let next = Self::map_coords(prev);
for &coords in &next { for (&z, xs) in &next.0 {
self.render_mipmap::<image::Rgba<u8>>(TileKind::Map, level, coords, prev)?; for &x in xs {
self.render_mipmap::<image::LumaA<u8>>(TileKind::Lightmap, level, coords, prev)?; let coords = TileCoords { x, z };
self.render_mipmap::<image::Rgba<u8>>(TileKind::Map, level, coords, prev)?;
self.render_mipmap::<image::LumaA<u8>>(
TileKind::Lightmap,
level,
coords,
prev,
)?;
}
} }
tile_stack.push(next); tile_stack.push(next);