diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 117 |
1 files changed, 54 insertions, 63 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) } |