aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 92d07b76aebdaa124b8eb7ba22dac45fd0d01553 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
pub mod render;

use crate::render::{
    composite::{
        image_buffer_blit, isometric_coord_mapping, CHUNK_HEIGHT, CHUNK_SIZE, REGION_SIZE,
    },
    models::processed_block_texture,
    processing::Texture,
};
use fastanvil::{tex::Render, Block, Chunk, CurrentJavaChunk, RegionLoader};
use image::{ImageBuffer, Rgba};
use log::debug;
use std::{collections::HashMap, path::Path};

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();

    let mut visible_blocks = Vec::new();

    for x in 0..16 {
        for y in -64..256 {
            for z in 0..16 {
                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")
                            .unwrap_or(false)
                    } else {
                        false
                    }
                };
                let visible = solid(x, y, z)
                    && !(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 {
                    visible_blocks.push((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 * CHUNK_SIZE as u32,
        16 * (CHUNK_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 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();
}