diff options
author | metamuffin <metamuffin@disroot.org> | 2022-10-17 19:48:45 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-10-17 19:48:45 +0200 |
commit | d55dc04fd9f223ada252a6d9e71cabde5f6dd355 (patch) | |
tree | 5e9859d45e43567e373ac896657b89998b52160c | |
parent | b58c29c734978766db2c86acb436ca9425491b99 (diff) | |
download | trash-map-d55dc04fd9f223ada252a6d9e71cabde5f6dd355.tar trash-map-d55dc04fd9f223ada252a6d9e71cabde5f6dd355.tar.bz2 trash-map-d55dc04fd9f223ada252a6d9e71cabde5f6dd355.tar.zst |
works
-rw-r--r-- | src/main.rs | 117 | ||||
-rw-r--r-- | src/render/models.rs | 9 | ||||
-rw-r--r-- | src/render/processing.rs | 24 |
3 files changed, 81 insertions, 69 deletions
diff --git a/src/main.rs b/src/main.rs index 5f4e621..07cb629 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,12 @@ pub mod render; use crate::render::{ - composite::{image_buffer_blit, isometric_coord_mapping, CHUNK_HEIGHT}, - models::processed_block_texture, - processing::Texture, + composite::image_buffer_blit, models::processed_block_texture, processing::Texture, }; use chashmap::{CHashMap, ReadGuard, WriteGuard}; use fastanvil::{Block, Chunk, CurrentJavaChunk, Region, RegionFileLoader, RegionLoader}; use image::ImageBuffer; -use log::debug; +use log::{debug, info}; use std::{collections::HashMap, fs::File, path::Path}; const SEG_SIZE: isize = 128; @@ -20,70 +18,63 @@ fn main() { .init(); let dim = Dimension::new("/home/muffin/containers/games/home/user/server/world/region/"); - dim.block(123, 123, 123); - let mut visible_blocks = Vec::new(); + let solid = |x: isize, y: isize, z: isize| { + dim.block(x, y, z) + .map(|b| match b.name() { + "minecraft:air" | "minecraft:cave_air" => (false, false), + "minecraft:water" => (false, true), + _ => (true, true), + }) + .unwrap_or((true, true)) + }; - for x in 0..SEG_SIZE { - for y in -64..256 { - for z in 0..SEG_SIZE { - let solid = |x: isize, y: isize, z: isize| { - dim.block(x, y, z) - .map(|b| { - !matches!( - b.name(), - "minecraft:air" | "minecraft:water" | "minecraft:cave_air" - ) - }) - .unwrap_or(false) - }; - let visible = - |b: &Block| !matches!(b.name(), "minecraft:air" | "minecraft:cave_air"); - let ray_visible = || { - for i in 1..100 { - if solid(x - i, y + i, z - i) { - return false; - } - } - true - }; + let mut textures = HashMap::<String, Texture>::new(); + + let mut view: Texture = + ImageBuffer::new(16 * (SEG_SIZE + 1) as u32, 16 * (SEG_SIZE + 1) as u32); + + let mut visible = Vec::<((isize, isize, isize), (isize, isize, isize))>::new(); - if visible(&dim.block(x, y, z).unwrap()) - && !(solid(x + 1, y, z) - && solid(x - 1, y, z) - && solid(x, y + 1, z) - && solid(x, y - 1, z) - && solid(x, y, z + 1) - && solid(x, y, z - 1)) - && ray_visible() - { - visible_blocks.push((x, y, z)) + for ix in 0..SEG_SIZE { + for iy in 0..(SEG_SIZE * 2) { + for off in 0..=1 { + let mut y = 100; + let mut x = -ix + iy + off; + let mut z = ix + iy; + loop { + let (solid, has_texture) = solid(x, y, z); + if has_texture { + visible.push(((x, y, z), (ix, iy, off))); + } + if solid { + break; + } + y -= 1; + x -= 1; + z -= 1; } } } } + info!("{} visible blocks", visible.len()); + visible.sort_by_cached_key(|((x, y, z), _)| x + y + z); - debug!("{} potentially visible blocks", visible_blocks.len()); - debug!("sorting by z-order"); - visible_blocks.sort_by_cached_key(|(x, y, z)| x + y + z); - debug!("done"); - - let mut view: Texture = ImageBuffer::new( - 16 * SEG_SIZE as u32, - 16 * (SEG_SIZE as u32 + CHUNK_HEIGHT as u32) / 2, - ); - - let mut textures = HashMap::<String, Texture>::new(); - - for (x, y, z) in visible_blocks { - let coords = isometric_coord_mapping(x as i32, y as i32, z as i32); - let block = dim.block(x, y, z).unwrap(); - let name = &block.name()["minecraft:".len()..]; + info!("compositing textures"); + for ((x, y, z), (ix, iy, off)) in visible { + let name = match dim.block(x, y, z) { + Some(block) => block.name().to_owned(), + None => "minecraft:debug".to_owned(), + }; + let name = &name["minecraft:".len()..]; let texture = textures .entry(name.to_owned()) .or_insert_with(|| processed_block_texture(name)); - image_buffer_blit(&mut view, texture, coords); - } + let ix = ix * 16 + off * 8; + let iy = iy * 8 + off * 4; + image_buffer_blit(&mut view, texture, (ix as u32, iy as u32)); + } + info!("saving png"); view.save(format!("/tmp/a.png")).unwrap(); } @@ -109,7 +100,7 @@ impl Dimension { if self.regions.contains_key(&(rx, rz)) { self.regions.get_mut(&(rx, rz)).unwrap() } else { - debug!("loading region {:?}", (rx, rz)); + info!("loading region {:?}", (rx, rz)); self.regions.insert( (rx, rz), self.loader @@ -128,13 +119,13 @@ impl Dimension { } else { let mut guard = self.region(cx / 32, cz / 32); let reg = guard.as_mut().unwrap(); - let chunk = reg + debug!("loading chunk {:?}", (cx, cz)); + let chunk: Option<CurrentJavaChunk> = reg .read_chunk(cx.rem_euclid(32) as usize, cz.rem_euclid(32) as usize) .ok() - .unwrap() - .unwrap(); - debug!("loading chunk {:?}", (cx, cz)); - let chunk: Option<CurrentJavaChunk> = fastnbt::from_bytes(&chunk).ok(); + .flatten() + .map(|chunk| fastnbt::from_bytes(&chunk).ok()) + .flatten(); self.chunks.insert((cx, cz), chunk); self.chunk(cx, cz) } diff --git a/src/render/models.rs b/src/render/models.rs index 66b8714..24e7817 100644 --- a/src/render/models.rs +++ b/src/render/models.rs @@ -15,9 +15,12 @@ pub fn processed_block_texture(name: &str) -> ImageBuffer<Rgba<u8>, Vec<u8>> { crossed_planes(&auto_block_texture()) } "lilac" | "peony" | "rose_bush" | "tall_grass" => crossed_planes(&auto_block_texture()), - "water" => full_isometric_sides( - &crop16(&tint(&block_texture("water_still"), (0, 0, 255))), - &crop16(&tint(&block_texture("water_flow"), (0, 0, 255))), + "water" => adjust_alpha( + 64, + &full_isometric_sides( + &crop16(&tint(&block_texture("water_still"), (0, 0, 255))), + &crop16(&tint(&block_texture("water_flow"), (0, 0, 255))), + ), ), "lava" => full_isometric_sides( &crop16(&block_texture("lava_still")), diff --git a/src/render/processing.rs b/src/render/processing.rs index 451fab3..7c35736 100644 --- a/src/render/processing.rs +++ b/src/render/processing.rs @@ -8,6 +8,20 @@ pub fn biome_tint(s: &Texture) -> Texture { tint(s, (100, 200, 50)) } +pub fn adjust_alpha(fac: u8, source: &Texture) -> Texture { + let mut t = ImageBuffer::new(16, 16); + for (x, y, p) in t.enumerate_pixels_mut() { + let sp = source.get_pixel(x, y); + *p = Rgba::from([ + sp.0[0], + sp.0[1], + sp.0[2], + ((sp.0[3] as u16 * fac as u16) / 255) as u8, + ]) + } + return t; +} + pub fn tint(source: &Texture, tint: (u16, u16, u16)) -> Texture { let mut t = ImageBuffer::new(16, 16); for (x, y, p) in t.enumerate_pixels_mut() { @@ -33,15 +47,19 @@ pub fn crop16(tex: &Texture) -> Texture { pub fn transparent() -> Texture { let mut t = ImageBuffer::new(16, 16); - for (_,_,p) in t.enumerate_pixels_mut() { - *p = Rgba::from([0,0,0,255]) + for (_, _, p) in t.enumerate_pixels_mut() { + *p = Rgba::from([0, 0, 0, 255]) } return t; } pub fn block_texture(block_name: &str) -> Texture { image::open(&Path::new( - format!("./assets/assets/minecraft/textures/block/{}.png", block_name).as_str(), + format!( + "./assets/assets/minecraft/textures/block/{}.png", + block_name + ) + .as_str(), )) .unwrap_or_else(|_err| { image::open(&Path::new( |