Compare commits

...

2 Commits

  1. 2
      src/bloxel/storage/bloxel_array.rs
  2. 2
      src/bloxel/storage/bloxel_store.rs
  3. 16
      src/bloxel/worldgen/mod.rs

@ -23,7 +23,7 @@ impl<T: Copy> BloxelArray<T> {
Self { size, data }
}
pub fn from_fn(size: USize3, f: impl Fn(IVec3) -> T) -> Self {
pub fn from_fn(size: USize3, mut f: impl FnMut(IVec3) -> T) -> Self {
let f = |(x, y, z)| f(IVec3::new(x as i32, y as i32, z as i32));
let data = Array3::from_shape_fn(size, f);
Self { size, data }

@ -12,7 +12,7 @@ pub trait BloxelStore<T: Copy> {
pub trait BloxelStoreMut<T: Copy>: BloxelStore<T> {
fn set(&mut self, pos: IVec3, value: T) -> Result<T, ()>;
fn update(&mut self, f: impl Fn(IVec3, T) -> T) {
fn update(&mut self, mut f: impl FnMut(IVec3, T) -> T) {
let (w, h, d) = self.size().into();
for prod in Hom3FCartProd::new(0..w, 0..h, 0..d) {
let pos = UVec3::from(prod).as_ivec3();

@ -10,6 +10,10 @@ use crate::{
TerrainBlocks,
};
const LOAD_DISTANCE: usize = 12;
const UNLOAD_DISTANCE: usize = 16;
const CHUNKS_PER_ITERATION: usize = 12;
pub struct WorldGenPlugin;
impl Plugin for WorldGenPlugin {
@ -52,13 +56,14 @@ fn create_chunks_around_camera(
create_chunk(&mut octree, chunk_pos);
}
let sqr_load_distance = (LOAD_DISTANCE * LOAD_DISTANCE) as i32;
let to_create = octree
.find(|node, exist| {
(exist != Existing::All).then(|| -node.region().distance_to_squared(chunk_pos))
})
.take_while(|(_, _, neg_sqr_distance)| *neg_sqr_distance > -(12 * 12))
.take_while(|(_, _, neg_sqr_distance)| *neg_sqr_distance > -sqr_load_distance)
.map(|(chunk_pos, _, _)| chunk_pos)
.take(12) // Create up to 12 chunks per system iteration.
.take(CHUNKS_PER_ITERATION) // Create up to this many chunks per system iteration.
.collect::<Vec<_>>();
for chunk_pos in to_create {
@ -82,9 +87,10 @@ fn destroy_chunks_away_from_camera(
a.max(b)
};
let sqr_unload_distance = (UNLOAD_DISTANCE * UNLOAD_DISTANCE) as i32;
let to_destroy = octree
.find(|node, exist| (exist != Existing::None).then(|| distance(node)))
.take_while(|(_, _, neg_sqr_distance)| *neg_sqr_distance > 16 * 16)
.take_while(|(_, _, sqr_distance)| *sqr_distance > sqr_unload_distance)
.map(|(chunk_pos, _, _)| chunk_pos)
.collect::<Vec<_>>();
@ -111,6 +117,8 @@ fn generate_terrain(
return;
};
let slices = [terrain.rock, terrain.dirt, terrain.grass, terrain.sand];
for (entity, chunk_pos) in chunks_without_data.iter() {
let mut data = ChunkData::new(terrain.air);
data.update(|relative, _| {
@ -125,7 +133,7 @@ fn generate_terrain(
.sample3(float_pos);
if sample > bias {
terrain.rock
slices[relative.y as usize % slices.len()]
} else {
terrain.air
}

Loading…
Cancel
Save