diff --git a/src/gfx/map.rs b/src/gfx/map.rs index 04865a6..5bb5354 100644 --- a/src/gfx/map.rs +++ b/src/gfx/map.rs @@ -50,6 +50,7 @@ struct MeshgenInfo { // i optimized the shit out of these textures: Vec, nodes: [Option>; u16::MAX as usize + 1], + node_names_to_ids: HashMap, } type MeshQueue = HashMap, MeshData>; @@ -439,10 +440,16 @@ impl MapRender { multiview: None, }); + let mut node_names_to_ids: HashMap = HashMap::new(); + for (id, def) in &nodes { + node_names_to_ids.insert(def.name.clone(), *id); + } + let meshgen_queue = Arc::new(Mutex::new(HashMap::new())); let meshgen_info = Arc::new(MeshgenInfo { - nodes: std::array::from_fn(|i| nodes.get(&(i as u16)).cloned().map(Box::new)), textures: atlas_slices, + nodes: std::array::from_fn(|i| nodes.get(&(i as u16)).cloned().map(Box::new)), + node_names_to_ids, }); let mut meshgen_threads = Vec::new(); let (meshgen_tx, meshgen_rx) = crossbeam_channel::unbounded(); diff --git a/src/gfx/map/atlas.rs b/src/gfx/map/atlas.rs index 207ee03..37933f5 100644 --- a/src/gfx/map/atlas.rs +++ b/src/gfx/map/atlas.rs @@ -52,15 +52,16 @@ pub(super) fn create_atlas( .unwrap(); match tile.animation { TileAnim::VerticalFrame { - n_frames: whatever, .. + n_frames: frame_aspect, + .. } => (|| { - if whatever.x == 0 || whatever.y == 0 { + if frame_aspect.x == 0 || frame_aspect.y == 0 { eprintln!("invalid animation for tile {}", string); return; } let tex_size = tex.dimensions(); let frame_height = - (tex_size.0 as f32 / whatever.x as f32 * whatever.y as f32) as u32; + (tex_size.0 as f32 / frame_aspect.x as f32 * frame_aspect.y as f32) as u32; tex = image::imageops::crop(&mut tex, 0, 0, tex_size.0, frame_height).to_image(); })(), diff --git a/src/gfx/map/mesh.rs b/src/gfx/map/mesh.rs index 3d56ad8..77acef5 100644 --- a/src/gfx/map/mesh.rs +++ b/src/gfx/map/mesh.rs @@ -1,6 +1,8 @@ +use std::ops; + use super::{LeavesMode, MapRenderSettings, MeshgenInfo, Vertex, CUBE, FACE_DIR}; use cgmath::Point3; -use mt_net::MapBlock; +use mt_net::{MapBlock, TileDef}; #[derive(Clone)] pub(super) struct MeshData { @@ -21,6 +23,21 @@ impl MeshData { } } +enum CowTileArray<'a> { + Borrowed(&'a [TileDef; 6]), + Owned([&'a TileDef; 6]), +} +impl<'a> ops::Index for CowTileArray<'a> { + type Output = TileDef; + + fn index(&self, index: usize) -> &Self::Output { + match self { + CowTileArray::Borrowed(tiles) => &tiles[index], + CowTileArray::Owned(tiles) => tiles[index], + } + } +} + pub(super) fn create_mesh( mkinfo: &MeshgenInfo, settings: &MapRenderSettings, @@ -38,7 +55,7 @@ pub(super) fn create_mesh( use mt_net::{DrawType, Param1Type}; use std::array::from_fn as array; - let mut tiles = &def.tiles; + let mut tiles = CowTileArray::Borrowed(&def.tiles); let mut draw_type = def.draw_type; match draw_type { @@ -46,13 +63,16 @@ pub(super) fn create_mesh( draw_type = match settings.leaves { LeavesMode::Opaque => DrawType::Cube, LeavesMode::Simple => { - tiles = &def.special_tiles; - + tiles = CowTileArray::Borrowed(&def.special_tiles); DrawType::GlassLike } LeavesMode::Fancy => DrawType::AllFaces, }; } + DrawType::Flowing => { + let s = &def.special_tiles; + tiles = CowTileArray::Owned([&s[1], &s[1], &s[0], &s[0], &s[1], &s[1]]); + } DrawType::None => continue, _ => {} } @@ -70,8 +90,17 @@ pub(super) fn create_mesh( let pos: [i16; 3] = array(|i| ((index >> (4 * i)) & 0xf) as i16); + let alt_content = match draw_type { + DrawType::Liquid => mkinfo.node_names_to_ids.get(&def.flowing_alt).copied(), + DrawType::Flowing => mkinfo.node_names_to_ids.get(&def.source_alt).copied(), + _ => None, + }; + for (f, face) in CUBE.iter().enumerate() { - if draw_type == DrawType::Cube || draw_type == DrawType::Liquid { + if draw_type == DrawType::Cube + || draw_type == DrawType::Liquid + || draw_type == DrawType::Flowing + { let c = [1, 1, 0, 0, 2, 2][f]; let mut nblk = block; @@ -93,7 +122,11 @@ pub(super) fn create_mesh( if let Some(ndef) = &mkinfo.nodes[ncontent as usize] { if match draw_type { DrawType::Cube => ndef.draw_type == DrawType::Cube, - DrawType::Liquid => ndef.draw_type == DrawType::Cube || ncontent == content, + DrawType::Liquid | DrawType::Flowing => { + ndef.draw_type == DrawType::Cube + || ncontent == content + || Some(ncontent) == alt_content + } _ => false, } { continue;