diff options
-rw-r--r-- | Cargo.lock | 118 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 124 | ||||
-rw-r--r-- | src/render/composite.rs | 7 |
4 files changed, 207 insertions, 43 deletions
@@ -92,6 +92,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "chashmap" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff41a3c2c1e39921b9003de14bf0439c7b63a9039637c291e1a64925d8ddfa45" +dependencies = [ + "owning_ref", + "parking_lot", +] + +[[package]] name = "color_quant" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -200,7 +210,7 @@ dependencies = [ "half", "lebe", "miniz_oxide 0.6.2", - "smallvec", + "smallvec 1.10.0", "threadpool", ] @@ -258,6 +268,12 @@ dependencies = [ ] [[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] name = "futures-core" version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -384,7 +400,7 @@ dependencies = [ "itertools", "nalgebra", "num", - "rand", + "rand 0.7.3", "rand_distr", "rayon", "rusttype", @@ -458,6 +474,12 @@ dependencies = [ ] [[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -648,6 +670,37 @@ dependencies = [ ] [[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "parking_lot" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" +dependencies = [ + "owning_ref", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" +dependencies = [ + "libc", + "rand 0.4.6", + "smallvec 0.6.14", + "winapi", +] + +[[package]] name = "paste" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -722,6 +775,19 @@ dependencies = [ [[package]] name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" @@ -729,7 +795,7 @@ dependencies = [ "getrandom 0.1.16", "libc", "rand_chacha", - "rand_core", + "rand_core 0.5.1", "rand_hc", ] @@ -740,11 +806,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", ] [[package]] name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" @@ -758,7 +839,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" dependencies = [ - "rand", + "rand 0.7.3", ] [[package]] @@ -767,7 +848,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -801,6 +882,15 @@ dependencies = [ ] [[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] name = "regex" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -892,6 +982,15 @@ dependencies = [ [[package]] name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" @@ -906,6 +1005,12 @@ dependencies = [ ] [[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] name = "syn" version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -978,6 +1083,7 @@ dependencies = [ name = "trash-map" version = "0.1.0" dependencies = [ + "chashmap", "env_logger", "fastanvil", "fastnbt", @@ -12,3 +12,4 @@ imageproc = "0.23.0" log = "0.4.17" env_logger = "0.9.1" +chashmap = "2.2.2" diff --git a/src/main.rs b/src/main.rs index 92d07b7..609041b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,59 +1,56 @@ pub mod render; use crate::render::{ - composite::{ - image_buffer_blit, isometric_coord_mapping, CHUNK_HEIGHT, CHUNK_SIZE, REGION_SIZE, - }, + composite::{image_buffer_blit, isometric_coord_mapping, CHUNK_HEIGHT}, models::processed_block_texture, processing::Texture, }; -use fastanvil::{tex::Render, Block, Chunk, CurrentJavaChunk, RegionLoader}; -use image::{ImageBuffer, Rgba}; +use chashmap::{CHashMap, ReadGuard, WriteGuard}; +use fastanvil::{Block, Chunk, CurrentJavaChunk, Region, RegionFileLoader, RegionLoader}; +use image::ImageBuffer; use log::debug; -use std::{collections::HashMap, path::Path}; +use std::{collections::HashMap, fs::File, path::Path}; + +const SEG_SIZE: isize = 64; fn main() { env_logger::builder() .filter_level(log::LevelFilter::Debug) .parse_env("LOG") - .build(); - - let loader = fastanvil::RegionFileLoader::new( - Path::new("/home/muffin/containers/games/home/user/server/world/region/").to_path_buf(), - ); - - let mut region = loader - .region(fastanvil::RCoord(0), fastanvil::RCoord(0)) - .unwrap(); - - let chunk = region.read_chunk(0, 0).unwrap().unwrap(); - - let chunk: CurrentJavaChunk = fastnbt::from_bytes(&chunk).unwrap(); + .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(); - for x in 0..16 { + for x in 0..SEG_SIZE { for y in -64..256 { - for z in 0..16 { + for z in 0..SEG_SIZE { let solid = |x: isize, y: isize, z: isize| { - if x >= 0 && z >= 0 && x < 16 && z < 16 && y >= -64 && y < 256 { - chunk - .block(x as usize, y, z as usize) - .map(|b| b.name() != "minecraft:air") + if x >= 0 && z >= 0 && x < SEG_SIZE && z < SEG_SIZE && y >= -64 && y < 256 { + dim.block(x, y, z) + .map(|b| { + !matches!( + b.name(), + "minecraft:air" | "minecraft:water" | "minecraft:cave_air" + ) + }) .unwrap_or(false) } else { false } }; - let visible = solid(x, y, z) + let visible = + |b: &Block| !matches!(b.name(), "minecraft:air" | "minecraft:cave_air"); + + 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)); - - if visible { + && solid(x, y, z - 1)) + { visible_blocks.push((x, y, z)) } } @@ -66,22 +63,81 @@ fn main() { debug!("done"); let mut view: Texture = ImageBuffer::new( - 16 * CHUNK_SIZE as u32, - 16 * (CHUNK_SIZE as u32 + CHUNK_HEIGHT as u32) / 2, + 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 name = &chunk.block(x as usize, y, z as usize).unwrap().name()["minecraft:".len()..]; + let block = dim.block(x, y, z).unwrap(); + let name = &block.name()["minecraft:".len()..]; let texture = textures .entry(name.to_owned()) .or_insert_with(|| processed_block_texture(name)); - - println!("{coords:?}"); image_buffer_blit(&mut view, texture, coords); } view.save(format!("/tmp/a.png")).unwrap(); } + +struct Dimension { + loader: RegionFileLoader, + regions: CHashMap<(isize, isize), Option<Region<File>>>, + chunks: CHashMap<(isize, isize), Option<CurrentJavaChunk>>, +} +impl Dimension { + pub fn new(path: &str) -> Self { + let loader = fastanvil::RegionFileLoader::new(Path::new(path).to_path_buf()); + Self { + loader, + regions: Default::default(), + chunks: Default::default(), + } + } + pub fn region( + &self, + rx: isize, + rz: isize, + ) -> WriteGuard<'_, (isize, isize), Option<Region<File>>> { + if self.regions.contains_key(&(rx, rz)) { + self.regions.get_mut(&(rx, rz)).unwrap() + } else { + debug!("loading region {:?}", (rx, rz)); + self.regions.insert( + (rx, rz), + self.loader + .region(fastanvil::RCoord(rx), fastanvil::RCoord(rz)), + ); + self.region(rx, rz) + } + } + pub fn chunk( + &self, + cx: isize, + cz: isize, + ) -> ReadGuard<'_, (isize, isize), Option<CurrentJavaChunk>> { + if self.chunks.contains_key(&(cx, cz)) { + self.chunks.get(&(cx, cz)).unwrap() + } else { + let mut guard = self.region(cx / 32, cz / 32); + let reg = guard.as_mut().unwrap(); + let chunk = 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(); + self.chunks.insert((cx, cz), chunk); + self.chunk(cx, cz) + } + } + pub fn block(&self, x: isize, y: isize, z: isize) -> Option<Block> { + self.chunk(x / 16, z / 16) + .as_ref()? + .block(x.rem_euclid(16) as usize, y, z.rem_euclid(16) as usize) + .map(|e| e.to_owned()) + } +} diff --git a/src/render/composite.rs b/src/render/composite.rs index 51c6f6a..7409478 100644 --- a/src/render/composite.rs +++ b/src/render/composite.rs @@ -1,8 +1,10 @@ use image::ImageBuffer; use image::Rgba; +use crate::SEG_SIZE; + pub const REGION_SIZE: usize = 16 * 8; -pub const CHUNK_HEIGHT: usize = 384; +pub const CHUNK_HEIGHT: usize = 320; pub const CHUNK_SIZE: usize = 16; pub fn image_buffer_blit( @@ -28,8 +30,7 @@ pub fn image_buffer_blit( pub fn isometric_coord_mapping(x: i32, y: i32, z: i32) -> (u32, u32) { // const BASE_X: i32 = 1016; - // const BASE_Y: i32 = 2040; - const BASE_X: i32 = 128 - 8; + const BASE_X: i32 = (SEG_SIZE as i32 * 8) - 8; const BASE_Y: i32 = 2040; const XDIFF: (i32, i32) = (-8, 4); |