Parallelize chunk systems

This commit is contained in:
Elias Stepanik 2025-06-15 02:54:30 +02:00
parent 2bdffe4083
commit 20622a7c09
2 changed files with 77 additions and 57 deletions

View File

@ -1,8 +1,7 @@
use bevy::prelude::*;
use crate::plugins::environment::systems::voxels::helper::world_to_chunk;
use crate::plugins::environment::systems::voxels::structure::*;
use bevy::prelude::*;
use rayon::prelude::*;
/// enqueue chunks that *should* be visible but are not yet spawned
/// enqueue chunks that *should* be visible but are not yet spawned
@ -14,8 +13,12 @@ pub fn enqueue_visible_chunks(
cam_q: Query<&GlobalTransform, With<Camera>>,
tree_q: Query<&SparseVoxelOctree>,
) {
let Ok(tree) = tree_q.get_single() else { return };
let Ok(cam_tf) = cam_q.get_single() else { return };
let Ok(tree) = tree_q.get_single() else {
return;
};
let Ok(cam_tf) = cam_q.get_single() else {
return;
};
let cam_pos = cam_tf.translation();
let centre = world_to_chunk(tree, cam_pos);
@ -28,13 +31,17 @@ pub fn enqueue_visible_chunks(
let mut keys: Vec<(ChunkKey, i32)> = tree
.occupied_chunks
.iter()
.par_iter()
.filter_map(|key| {
let dx = key.0 - centre.0;
let dy = key.1 - centre.1;
let dz = key.2 - centre.2;
if dx.abs() > r || dy.abs() > r || dz.abs() > r { return None; }
if spawned.0.contains_key(key) { return None; }
if dx.abs() > r || dy.abs() > r || dz.abs() > r {
return None;
}
if spawned.0.contains_key(key) {
return None;
}
Some((*key, dx * dx + dy * dy + dz * dz))
})
.collect();
@ -55,11 +62,15 @@ pub fn process_chunk_queue(
budget: Res<ChunkBudget>,
mut tree_q: Query<&mut SparseVoxelOctree>,
) {
let Ok(mut tree) = tree_q.get_single_mut() else { return };
let Ok(mut tree) = tree_q.get_single_mut() else {
return;
};
for _ in 0..budget.per_frame {
if let Some(key) = queue.keys.pop_front() {
queue.set.remove(&key);
tree.dirty_chunks.insert(key);
} else { break; }
} else {
break;
}
}
}

View File

@ -1,12 +1,13 @@
use crate::plugins::big_space::big_space_plugin::RootGrid;
use crate::plugins::environment::systems::voxels::atlas::VoxelTextureAtlas;
use crate::plugins::environment::systems::voxels::meshing::mesh_chunk;
use crate::plugins::environment::systems::voxels::structure::*;
use crate::plugins::environment::systems::voxels::atlas::VoxelTextureAtlas;
use bevy::pbr::wireframe::Wireframe;
use bevy::prelude::*;
use bevy::render::mesh::Mesh;
use big_space::prelude::GridCell;
use itertools::Itertools;
use rayon::prelude::*;
use std::collections::HashMap;
use std::fmt::format;
@ -41,13 +42,18 @@ pub fn rebuild_dirty_chunks(
}
//------------------------------------------------ collect voxel data
let mut bufs = Vec::new();
for key in tree.dirty_chunks.iter().copied() {
let tree_ref = &*tree;
let bufs: Vec<_> = tree
.dirty_chunks
.par_iter()
.copied()
.map(|key| {
let lod = existing.get(&key).map(|v| v.3).unwrap_or(0);
let mut buf = [[[None; CHUNK_SIZE as usize]; CHUNK_SIZE as usize]; CHUNK_SIZE as usize];
let mut buf =
[[[None; CHUNK_SIZE as usize]; CHUNK_SIZE as usize]; CHUNK_SIZE as usize];
let half = tree.size * 0.5;
let step = tree.get_spacing_at_depth(tree.max_depth);
let half = tree_ref.size * 0.5;
let step = tree_ref.get_spacing_at_depth(tree_ref.max_depth);
let origin = Vec3::new(
key.0 as f32 * CHUNK_SIZE as f32 * step - half,
key.1 as f32 * CHUNK_SIZE as f32 * step - half,
@ -64,15 +70,17 @@ pub fn rebuild_dirty_chunks(
(gy + mult / 2) as f32 * step,
(gz + mult / 2) as f32 * step,
);
if let Some(v) = tree.get_voxel_at_world_coords(center) {
if let Some(v) = tree_ref.get_voxel_at_world_coords(center) {
for lx in 0..mult {
for ly in 0..mult {
for lz in 0..mult {
let ix = gx + lx;
let iy = gy + ly;
let iz = gz + lz;
if ix < CHUNK_SIZE && iy < CHUNK_SIZE && iz < CHUNK_SIZE {
buf[ix as usize][iy as usize][iz as usize] = Some(*v);
if ix < CHUNK_SIZE && iy < CHUNK_SIZE && iz < CHUNK_SIZE
{
buf[ix as usize][iy as usize][iz as usize] =
Some(*v);
}
}
}
@ -82,8 +90,9 @@ pub fn rebuild_dirty_chunks(
}
}
bufs.push((key, buf, origin, step, lod));
}
(key, buf, origin, step, lod)
})
.collect();
//------------------------------------------------ create / update
for (key, buf, origin, step, lod) in bufs {