diff --git a/common/src/terrain/chonk.rs b/common/src/terrain/chonk.rs index 9d812957e8..245aa09ab3 100644 --- a/common/src/terrain/chonk.rs +++ b/common/src/terrain/chonk.rs @@ -32,6 +32,14 @@ impl Chonk { } } + pub fn get_z_min(&self) -> i32 { + self.z_offset + } + + pub fn get_z_max(&self) -> i32 { + self.z_offset + (self.sub_chunks.len() as u32 * TerrainChunkSize::SIZE.z) as i32 + } + fn sub_chunk_idx(&self, z: i32) -> usize { ((z - self.z_offset) as u32 / TerrainChunkSize::SIZE.z as u32) as usize } diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index f250f86926..8e2e341dbe 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -51,55 +51,16 @@ impl + ReadVol, S: VolSize + Clone> Meshable for VolMap2 fn generate_mesh(&self, range: Self::Supplement) -> Mesh { let mut mesh = Mesh::new(); - let mut last_chunk_pos = self.pos_key(range.min); - let mut last_chunk = self.get_key(last_chunk_pos); - - let size = range.max - range.min; - for x in 1..size.x - 1 { - for y in 1..size.y - 1 { - for z in 0..size.z { + for x in range.min.x + 1..range.max.x - 1 { + for y in range.min.y + 1..range.max.y - 1 { + for z in range.min.z..range.max.z { let pos = Vec3::new(x, y, z); + let offs = (pos - range.min * Vec3::new(1, 1, 0)).map(|e| e as f32) - Vec3::new(1.0, 1.0, 0.0); - let new_chunk_pos = self.pos_key(range.min + pos); - if last_chunk_pos != new_chunk_pos { - last_chunk = self.get_key(new_chunk_pos); - last_chunk_pos = new_chunk_pos; - } - let offs = pos.map(|e| e as f32) - Vec3::new(1.0, 1.0, 0.0); - if let Some(chunk) = last_chunk { - let chunk_pos = Self::chunk_offs(range.min + pos); - if let Some(col) = chunk.get(chunk_pos).ok().and_then(|vox| vox.get_color()) - { - let col = col.map(|e| e as f32 / 255.0); + if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { + let col = col.map(|e| e as f32 / 255.0); - vol::push_vox_verts( - &mut mesh, - self, - range.min + pos, - offs, - col, - TerrainVertex::new, - false, - ); - } - } else { - if let Some(col) = self - .get(range.min + pos) - .ok() - .and_then(|vox| vox.get_color()) - { - let col = col.map(|e| e as f32 / 255.0); - - vol::push_vox_verts( - &mut mesh, - self, - range.min + pos, - offs, - col, - TerrainVertex::new, - false, - ); - } + vol::push_vox_verts(&mut mesh, self, pos, offs, col, TerrainVertex::new, false); } } } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index ea23ecf77a..0bf56fc129 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -4,7 +4,7 @@ use crate::{ }; use client::Client; use common::{terrain::TerrainMap, vol::SampleVol, volumes::vol_map_2d::VolMap2dErr}; -use std::{collections::HashMap, sync::mpsc, time::Duration}; +use std::{collections::HashMap, sync::mpsc, time::Duration, i32}; use vek::*; struct TerrainChunk { @@ -132,11 +132,6 @@ impl Terrain { .map2(TerrainMap::chunk_size(), |e, sz| (e + 1) * sz as i32 + 1), }; - let aabb = Aabb { - min: Vec3::from(aabr.min), - max: Vec3::from(aabr.max) + Vec3::unit_z() * 256, - }; - // Copy out the chunk data we need to perform the meshing. We do this by taking a // sample of the terrain that includes both the chunk we want and its neighbours. let volume = match client.state().terrain().sample(aabr) { @@ -147,6 +142,19 @@ impl Terrain { _ => panic!("Unhandled edge case"), }; + // The region to actually mesh + let z_min = volume + .iter() + .fold(i32::MAX, |min, (_, chunk)| chunk.get_z_min().min(min)); + let z_max = volume + .iter() + .fold(i32::MIN, |max, (_, chunk)| chunk.get_z_max().max(max)); + + let aabb = Aabb { + min: Vec3::from(aabr.min) + Vec3::unit_z() * z_min, + max: Vec3::from(aabr.max) + Vec3::unit_z() * z_max, + }; + // Clone various things so that they can be moved into the thread. let send = self.mesh_send_tmp.clone(); let pos = todo.pos; diff --git a/world/src/lib.rs b/world/src/lib.rs index ca03b18be6..c4239c80cd 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -29,18 +29,26 @@ impl World { let dirt = Block::new(3, Rgb::new(128, 90, 0)); let sand = Block::new(4, Rgb::new(180, 150, 50)); - let mut chunk = TerrainChunk::new(0, stone, air, TerrainChunkMeta::void()); - + let offset_nz = Perlin::new().set_seed(3); let perlin_nz = Perlin::new().set_seed(1); let temp_nz = Perlin::new().set_seed(2); let chaos_nz = Perlin::new().set_seed(3); + let get_offset = |pos: Vec2| { + ((offset_nz.get(pos.map(|e| e as f64 / 4000.0).into_array()) + 1.0) + * 1000.0) as i32 + }; + + let offset_z = get_offset(chunk_pos * Vec2::from(TerrainChunkSize::SIZE).map(|e: u32| e as i32)); + + let mut chunk = TerrainChunk::new(offset_z, stone, air, TerrainChunkMeta::void()); + for x in 0..TerrainChunkSize::SIZE.x as i32 { for y in 0..TerrainChunkSize::SIZE.y as i32 { - for z in 0..256 { + for z in offset_z..offset_z + 256 { let lpos = Vec3::new(x, y, z); - let wpos = - lpos + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32); + let wpos = lpos + + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32); let wposf = wpos.map(|e| e as f64); let chaos_freq = 1.0 / 100.0; @@ -48,7 +56,7 @@ impl World { let ampl = 75.0; let small_freq = 1.0 / 32.0; let small_ampl = 6.0; - let offs = 32.0; + let offs = 128.0; let chaos = chaos_nz .get(Vec2::from(wposf * chaos_freq).into_array()) @@ -61,7 +69,8 @@ impl World { * small_ampl * 3.0 * chaos.powf(2.0) - + offs; + + offs + + get_offset(Vec2::from(wpos)) as f64; let temp = (temp_nz.get(Vec2::from(wposf * (1.0 / 64.0)).into_array()) + 1.0) * 0.5;