Add destroy_chunks_away_from_camera system

main
copygirl 1 week ago
parent d633ad58af
commit aaab14f0f4
  1. 46
      src/bloxel/worldgen/mod.rs

@ -14,8 +14,14 @@ pub struct WorldGenPlugin;
impl Plugin for WorldGenPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<ExistingChunks>()
.add_systems(Update, (create_chunks_around_camera, generate_terrain));
app.init_resource::<ExistingChunks>().add_systems(
Update,
(
create_chunks_around_camera,
destroy_chunks_away_from_camera,
generate_terrain,
),
);
}
}
@ -60,6 +66,42 @@ fn create_chunks_around_camera(
}
}
fn destroy_chunks_away_from_camera(
mut commands: Commands,
mut octree: ResMut<ExistingChunks>,
camera: Single<&Transform, With<ControlledCamera>>,
chunk_map: Single<&ChunkMap>,
) {
let block_pos = camera.translation.as_ivec3().into();
let (chunk_pos, _) = ChunkPos::from_block_pos(block_pos);
let distance = |node: OctreeNode| -> i32 {
let (min, max) = node.region().into();
let a = (chunk_pos - min).length_squared();
let b = (chunk_pos - max).length_squared();
a.max(b)
};
let to_destroy = octree
.find(|node, exist| (exist != Existing::None).then(|| distance(node)))
.take_while(|(_, _, neg_sqr_distance)| *neg_sqr_distance > 16 * 16)
.map(|(chunk_pos, _, _)| chunk_pos)
.collect::<Vec<_>>();
for chunk_pos in to_destroy {
let chunk = *chunk_map.get(&chunk_pos).unwrap();
commands.entity(chunk).despawn_recursive();
octree.update(chunk_pos, |_, children, parent| {
let children = children.map(|a| a.as_slice()).unwrap_or_default();
*parent = if children.iter().all(|c| *c == Existing::None) {
Existing::None
} else {
Existing::Some
}
});
}
}
fn generate_terrain(
mut commands: Commands,
terrain_blocks: Option<Res<TerrainBlocks>>,

Loading…
Cancel
Save