Add WorldGenPlugin

main
copygirl 1 week ago
parent be55277a3f
commit d633ad58af
  1. 11
      src/bloxel/mod.rs
  2. 54
      src/bloxel/worldgen/mod.rs
  3. 10
      src/main.rs

@ -14,6 +14,7 @@ pub mod prelude {
chunk::*,
math::*,
storage::{BloxelView, BloxelViewMut},
worldgen::WorldGenPlugin,
BloxelPlugin,
};
}
@ -26,15 +27,13 @@ impl Plugin for BloxelPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
(
set_transform_on_chunkpos_changed,
worldgen::create_chunks_around_camera,
worldgen::generate_terrain,
mesh::generate_chunk_mesh,
),
(set_transform_on_chunkpos_changed, mesh::generate_chunk_mesh),
)
.add_observer(add_chunks_to_chunkmap)
.add_observer(remove_chunks_from_chunkmap);
// Spawn default `ChunkMap` entity which all `Chunk`s get added to.
app.world_mut().spawn(ChunkMap::default());
}
}

@ -2,53 +2,65 @@ use bevy::prelude::*;
use rand::prelude::*;
use crate::{
bloxel::{prelude::*, storage::ChunkedOctree},
bloxel::{
prelude::*,
storage::{ChunkedOctree, OctreeNode},
},
camera_controller::ControlledCamera,
TerrainBlocks,
};
pub fn create_chunks_around_camera(
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));
}
}
fn create_chunks_around_camera(
mut commands: Commands,
mut octree: Local<GeneratedChunks>,
mut octree: ResMut<ExistingChunks>,
camera: Single<&Transform, With<ControlledCamera>>,
chunk_map: Single<Entity, With<ChunkMap>>,
) {
let block_pos = camera.translation.as_ivec3().into();
let (chunk_pos, _) = ChunkPos::from_block_pos(block_pos);
let mut create_chunk = |octree: &mut GeneratedChunks, chunk_pos: ChunkPos| {
let mut create_chunk = |octree: &mut ExistingChunks, chunk_pos: ChunkPos| {
commands.entity(*chunk_map).with_child((Chunk, chunk_pos));
octree.update(chunk_pos, |_node, children, parent| {
octree.update(chunk_pos, |_, children, parent| {
let children = children.map(|a| a.as_slice()).unwrap_or_default();
*parent = if children.iter().all(|c| *c == Generated::All) {
Generated::All
*parent = if children.iter().all(|c| *c == Existing::All) {
Existing::All
} else {
Generated::Some
Existing::Some
}
});
};
// Create chunk at camera's position, if it's not already. This is necessary because we
// need to "seed" the octree with a region so we have something to begin the search from.
if octree.get(chunk_pos) == Generated::None {
if octree.get(chunk_pos) == Existing::None {
create_chunk(&mut octree, chunk_pos);
}
let to_generate = octree
.find(|node, generated| {
(generated != Generated::All).then(|| -node.region().distance_to_squared(chunk_pos))
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 > -(16 * 16))
.take_while(|(_, _, neg_sqr_distance)| *neg_sqr_distance > -(12 * 12))
.map(|(chunk_pos, _, _)| chunk_pos)
.take(12) // Generate up to 12 chunks per system iteration.
.take(12) // Create up to 12 chunks per system iteration.
.collect::<Vec<_>>();
for chunk_pos in to_generate {
for chunk_pos in to_create {
create_chunk(&mut octree, chunk_pos);
}
}
pub fn generate_terrain(
fn generate_terrain(
mut commands: Commands,
terrain_blocks: Option<Res<TerrainBlocks>>,
chunks_without_data: Query<(Entity, &ChunkPos), (With<Chunk>, Without<ChunkData>)>,
@ -80,12 +92,12 @@ pub fn generate_terrain(
}
}
#[derive(Deref, DerefMut)]
pub struct GeneratedChunks {
octree: ChunkedOctree<Generated>,
#[derive(Resource, Deref, DerefMut)]
pub struct ExistingChunks {
octree: ChunkedOctree<Existing>,
}
impl Default for GeneratedChunks {
impl Default for ExistingChunks {
fn default() -> Self {
let octree = ChunkedOctree::new(5);
Self { octree }
@ -93,7 +105,7 @@ impl Default for GeneratedChunks {
}
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum Generated {
pub enum Existing {
#[default]
None,
Some,

@ -35,6 +35,7 @@ fn main() {
DefaultPlugins.set(ImagePlugin::default_nearest()),
CameraControllerPlugin,
BloxelPlugin,
WorldGenPlugin,
))
.add_systems(
Startup,
@ -43,7 +44,6 @@ fn main() {
setup_camera,
setup_terrain_blocks,
load_terrain_textures,
generate_sample_chunks,
),
)
.add_systems(Update, check_terrain_textures)
@ -118,14 +118,6 @@ fn check_terrain_textures(
}
}
fn generate_sample_chunks(mut commands: Commands) {
commands.spawn(ChunkMap::default()).with_children(|map| {
// map.spawn((Chunk, ChunkPos::new(0, 0, 0)));
// map.spawn((Chunk, ChunkPos::new(1, 0, 0)));
// map.spawn((Chunk, ChunkPos::new(-1, 0, 0)));
});
}
fn setup_sunlight(mut commands: Commands) {
commands.spawn((
DirectionalLight {

Loading…
Cancel
Save