Reduce memory usage by avoiding massive voxel vector

This commit is contained in:
Elias Stepanik 2025-06-18 20:18:28 +02:00
parent 7994eb72fe
commit 39aa0b0a56

View File

@ -3,14 +3,11 @@ use crate::plugins::environment::systems::voxels::structure::*;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::mesh::*; use bevy::render::mesh::*;
use noise::{NoiseFn, Perlin}; use noise::{NoiseFn, Perlin};
use rand::{thread_rng, Rng}; use rand::{Rng, thread_rng};
use rayon::prelude::*; use rayon::prelude::*;
use std::path::Path; use std::path::Path;
use std::thread; use std::thread;
pub fn setup(mut commands: Commands, root: Res<RootGrid>) { pub fn setup(mut commands: Commands, root: Res<RootGrid>) {
let builder = thread::Builder::new() let builder = thread::Builder::new()
.name("octree-build".into()) .name("octree-build".into())
@ -70,42 +67,31 @@ pub fn setup(mut commands: Commands, root: Res<RootGrid>) {
}); });
} }
pub fn generate_voxel_sphere_parallel(octree: &mut SparseVoxelOctree, center: Vec3, radius: i32) { pub fn generate_voxel_sphere_parallel(octree: &mut SparseVoxelOctree, center: Vec3, radius: i32) {
let step = octree.get_spacing_at_depth(octree.max_depth); let step = octree.get_spacing_at_depth(octree.max_depth);
let radius_sq = radius * radius; let radius_sq = radius * radius;
// 1. Collect voxel positions in parallel // Directly iterate over voxel positions to avoid building a large Vec.
let voxels: Vec<(Vec3, Voxel)> = (-radius..=radius) for ix in -radius..=radius {
.into_par_iter() let dx2 = ix * ix;
.flat_map_iter(|ix| { for iy in -radius..=radius {
let dx2 = ix * ix; let dy2 = iy * iy;
(-radius..=radius).flat_map(move |iy| { let r2_xy = dx2 + dy2;
let dy2 = iy * iy;
let r2_xy = dx2 + dy2;
if r2_xy > radius_sq { if r2_xy > radius_sq {
return Vec::new(); // this (x,y) column is outside continue;
} }
let max_z = ((radius_sq - r2_xy) as f32).sqrt() as i32; let max_z = ((radius_sq - r2_xy) as f32).sqrt() as i32;
(-max_z..=max_z) for iz in -max_z..=max_z {
.map(move |iz| { let pos = Vec3::new(
let pos = Vec3::new( center.x + ix as f32 * step,
center.x + ix as f32 * step, center.y + iy as f32 * step,
center.y + iy as f32 * step, center.z + iz as f32 * step,
center.z + iz as f32 * step, );
); octree.insert(pos, Voxel::random_sides());
(pos, Voxel::random_sides()) }
}) }
.collect::<Vec<_>>()
})
})
.collect();
// 2. Single-threaded insert (keeps `SparseVoxelOctree` API unchanged)
for (pos, voxel) in voxels {
octree.insert(pos, voxel);
} }
} }