summaryrefslogtreecommitdiff
path: root/src/gfx/map/mesh.rs
diff options
context:
space:
mode:
authorLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-08 17:51:21 +0200
committerLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-08 18:09:56 +0200
commitb6d021cded621e75ca66e83ebbec161130eb9f73 (patch)
tree421e015a98f76a2b8a3d5de50d02b8f1410d7e35 /src/gfx/map/mesh.rs
parentd5dcdf8078e6f2c6629469de7f38e2327ef6781e (diff)
downloadmt_client-b6d021cded621e75ca66e83ebbec161130eb9f73.tar.xz
map mesh generation performance improvements
Diffstat (limited to 'src/gfx/map/mesh.rs')
-rw-r--r--src/gfx/map/mesh.rs125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/gfx/map/mesh.rs b/src/gfx/map/mesh.rs
new file mode 100644
index 0000000..0befb1e
--- /dev/null
+++ b/src/gfx/map/mesh.rs
@@ -0,0 +1,125 @@
+use super::{LeavesMode, MapRenderSettings, MeshMakeInfo, Vertex, CUBE};
+use cgmath::Point3;
+use mt_net::MapBlock;
+use std::ops::Deref;
+use std::sync::Arc;
+
+#[derive(Clone)]
+pub(super) struct MeshData {
+ pub vertices: Vec<Vertex>,
+ pub vertices_blend: Vec<Vertex>,
+}
+
+impl MeshData {
+ pub fn new(cap: usize) -> Self {
+ Self {
+ vertices: Vec::with_capacity(cap),
+ vertices_blend: Vec::with_capacity(cap),
+ }
+ }
+
+ pub fn cap(&self) -> usize {
+ std::cmp::max(self.vertices.capacity(), self.vertices_blend.capacity())
+ }
+}
+
+pub(super) fn create_mesh(
+ buffer_cap: &mut usize,
+ mkinfo: Arc<MeshMakeInfo>,
+ settings: &MapRenderSettings,
+ pos: Point3<i16>,
+ block: Box<MapBlock>,
+) -> (Point3<i16>, MeshData) {
+ let mkinfo = mkinfo.deref();
+ let mut buffer = MeshData::new(*buffer_cap);
+
+ for (index, content) in block.param_0.iter().enumerate() {
+ let def = match &mkinfo.nodes[*content as usize] {
+ Some(x) => x,
+ None => continue,
+ };
+
+ use mt_net::{DrawType, Param1Type};
+ use std::array::from_fn as array;
+
+ let mut tiles = &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;
+
+ DrawType::GlassLike
+ }
+ LeavesMode::Fancy => DrawType::AllFaces,
+ };
+ }
+ DrawType::None => continue,
+ _ => {}
+ }
+
+ let light = match def.param1_type {
+ Param1Type::Light => block.param_1[index] as f32 / 15.0,
+ _ => 1.0,
+ };
+
+ let pos: [i16; 3] = array(|i| ((index >> (4 * i)) & 0xf) as i16);
+
+ for (f, face) in CUBE.iter().enumerate() {
+ let dir = FACE_DIR[f];
+ let npos: [i16; 3] = array(|i| dir[i] + pos[i]);
+ if npos.iter().all(|x| (0..16).contains(x)) {
+ let nindex = npos[0] | (npos[1] << 4) | (npos[2] << 8);
+
+ if let Some(ndef) = &mkinfo.nodes[block.param_0[nindex as usize] as usize] {
+ if ndef.draw_type == DrawType::Cube {
+ continue;
+ }
+ }
+ }
+
+ let tile = &tiles[f];
+ let texture = mkinfo.textures[tile.texture.custom].cube_tex_coords[f];
+
+ let mut add_vertex = |vertex: (usize, &([f32; 3], [f32; 2]))| {
+ /*println!(
+ "{:?} {:?} {:?} {:?}",
+ (vertex.1[0], vertex.1[1]),
+ (rect[0].start, rect[1].start),
+ (rect[0].end, rect[1].end),
+ (
+ vertex.1[0].lerp(rect[0].start, rect[0].end),
+ vertex.1[1].lerp(rect[1].start, rect[1].end)
+ )
+ );*/
+
+ buffer.vertices.push(Vertex {
+ pos: array(|i| pos[i] as f32 - 8.5 + vertex.1 .0[i]),
+ tex_coords: texture[vertex.0],
+ light,
+ });
+ };
+
+ face.iter().enumerate().for_each(&mut add_vertex);
+ /*if !backface_cull {
+ face.iter().enumerate().rev().for_each(&mut add_vertex);
+ }*/
+ }
+ }
+
+ *buffer_cap = buffer.cap();
+ (pos, buffer)
+}
+
+#[rustfmt::skip]
+const FACE_DIR: [[i16; 3]; 6] = [
+ [ 0, 1, 0],
+ [ 0, -1, 0],
+ [ 1, 0, 0],
+ [-1, 0, 0],
+ [ 0, 0, 1],
+ [ 0, 0, -1],
+];