Generate voxels asynchronously

This commit is contained in:
Elias Stepanik 2025-06-17 23:36:00 +02:00
parent a8408dae38
commit 5d5334d621
3 changed files with 35 additions and 24 deletions

View File

@ -23,4 +23,5 @@ rayon = "1.10.0"
bincode = "1.3"
bevy_app_compute = "0.16"
bytemuck = { version = "1.14", features = ["derive"] }
futures-lite = "2"

View File

@ -1,4 +1,3 @@
use std::path::Path;
use crate::plugins::environment::systems::voxels::debug::{draw_grid, visualize_octree_system};
use crate::plugins::environment::systems::voxels::lod::update_chunk_lods;
use crate::plugins::environment::systems::voxels::meshing_gpu::{
@ -11,6 +10,7 @@ use crate::plugins::environment::systems::voxels::queue_systems::{
};
use crate::plugins::environment::systems::voxels::render_chunks::rebuild_dirty_chunks;
use crate::plugins::environment::systems::voxels::atlas::{VoxelTextureAtlas};
use crate::plugins::environment::systems::voxel_system::attach_octree_from_task;
use crate::plugins::environment::systems::voxels::structure::{
ChunkBudget, ChunkCullingCfg, ChunkQueue, MeshBufferPool, PrevCameraChunk, SparseVoxelOctree,
SpawnedChunks,
@ -54,6 +54,7 @@ impl Plugin for EnvironmentPlugin {
.add_systems(
Update,
(
attach_octree_from_task,
/* ---------- culling & streaming ---------- */
enqueue_visible_chunks,
process_chunk_queue.after(enqueue_visible_chunks),

View File

@ -6,23 +6,22 @@ use noise::{NoiseFn, Perlin};
use rand::{thread_rng, Rng};
use rayon::prelude::*;
use std::path::Path;
use std::thread;
use bevy::tasks::{AsyncComputeTaskPool, Task};
use futures_lite::future;
#[derive(Resource)]
pub struct OctreeTask(pub Task<SparseVoxelOctree>);
pub fn setup(mut commands: Commands, root: Res<RootGrid>) {
let builder = thread::Builder::new()
.name("octree-build".into())
// Reduced stack size now that octree operations are iterative
.stack_size(8 * 1024 * 1024);
let handle = builder
.spawn(move || {
// Octree parameters
let unit_size = 1.0_f32;
let octree_base_size = 64.0 * unit_size;
let octree_depth = 10;
pub fn setup(mut commands: Commands) {
let pool = AsyncComputeTaskPool::get();
let task: Task<SparseVoxelOctree> = pool.spawn(async move {
// Octree parameters
let unit_size = 1.0_f32;
let octree_base_size = 64.0 * unit_size;
let octree_depth = 10;
let path = Path::new("octree.bin");
@ -57,17 +56,10 @@ pub fn setup(mut commands: Commands, root: Res<RootGrid>) {
tree
};
octree
})
.expect("failed to spawn octree build thread")
.join();
let octree = handle.expect("Failed to join octree build thread");
// Attach octree to the scene graph
commands.entity(root.0).with_children(|parent| {
parent.spawn((Transform::default(), octree));
octree
});
commands.insert_resource(OctreeTask(task));
}
@ -239,3 +231,20 @@ pub fn generate_solid_plane_with_noise(
}
}
}
pub fn attach_octree_from_task(
mut commands: Commands,
mut task: Option<ResMut<OctreeTask>>,
root: Res<RootGrid>,
) {
let Some(mut task) = task else {
return;
};
if let Some(octree) = future::block_on(future::poll_once(&mut task.0)) {
commands.entity(root.0).with_children(|parent| {
parent.spawn((Transform::default(), octree));
});
commands.remove_resource::<OctreeTask>();
}
}