Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/gfx/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct MeshgenInfo {
// i optimized the shit out of these
textures: Vec<AtlasSlice>,
nodes: [Option<Box<NodeDef>>; u16::MAX as usize + 1],
node_names_to_ids: HashMap<String, u16>,
}

type MeshQueue = HashMap<Point3<i16>, MeshData>;
Expand Down Expand Up @@ -439,10 +440,16 @@ impl MapRender {
multiview: None,
});

let mut node_names_to_ids: HashMap<String, u16> = 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();
Expand Down
31 changes: 25 additions & 6 deletions src/gfx/map/atlas.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{super::media::MediaMgr, AtlasSlice, CUBE};
use mt_net::NodeDef;
use mt_net::{NodeDef, TileAnim, TileDef};
use rand::Rng;
use std::collections::HashMap;

Expand Down Expand Up @@ -28,13 +28,14 @@ pub(super) fn create_atlas(
.map(|x| image::imageops::flip_vertical(&x))
};

let mut make_texture = |texture: &str| {
texture
let mut make_texture = |tile: &TileDef| {
let string = &tile.texture.name;
let mut tex = string
.split('^')
.map(|part| match load_texture(part) {
Ok(v) => v,
Err(e) => {
if !texture.is_empty() && !texture.contains('[') {
if !string.is_empty() && !string.contains('[') {
eprintln!("{e}");
}

Expand All @@ -48,14 +49,32 @@ pub(super) fn create_atlas(
image::imageops::overlay(&mut base, &top, 0, 0);
base
})
.unwrap()
.unwrap();
match tile.animation {
TileAnim::VerticalFrame {
n_frames: frame_aspect,
..
} => (|| {
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 / 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();
})(),
_ => (),
};
tex
};

let mut id_map = HashMap::new();

for tile in tiles {
tile.texture.custom = *id_map.entry(tile.texture.name.clone()).or_insert_with(|| {
let img = make_texture(&tile.texture.name);
let img = make_texture(&tile);

let dimensions = img.dimensions();
let size = guillotiere::size2(dimensions.0 as i32, dimensions.1 as i32);
Expand Down
45 changes: 39 additions & 6 deletions src/gfx/map/mesh.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -21,6 +23,21 @@ impl MeshData {
}
}

enum CowTileArray<'a> {
Borrowed(&'a [TileDef; 6]),
Owned([&'a TileDef; 6]),
}
impl<'a> ops::Index<usize> 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,
Expand All @@ -38,21 +55,24 @@ 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 {
DrawType::AllFacesOpt => {
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[0], &s[0], &s[1], &s[1], &s[1], &s[1]]);
}
DrawType::None => continue,
_ => {}
}
Expand All @@ -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;
Expand All @@ -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;
Expand Down