mirror of
https://github.com/eliasstepanik/voxel-simulation.git
synced 2026-01-11 13:58:30 +00:00
Load and Unload System working
This commit is contained in:
parent
e406ac15cb
commit
85699338a9
@ -71,7 +71,3 @@ fn should_visualize_octree(octree_query: Query<&SparseVoxelOctree>,) -> bool {
|
|||||||
fn should_draw_grid(octree_query: Query<&SparseVoxelOctree>,) -> bool {
|
fn should_draw_grid(octree_query: Query<&SparseVoxelOctree>,) -> bool {
|
||||||
octree_query.single().show_world_grid
|
octree_query.single().show_world_grid
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_visualize_chunks(octree_query: Query<&SparseVoxelOctree>,) -> bool {
|
|
||||||
octree_query.single().show_chunks
|
|
||||||
}
|
|
||||||
@ -1,32 +1,106 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
use rayon::prelude::*;
|
||||||
use crate::plugins::big_space::big_space_plugin::RootGrid;
|
use crate::plugins::big_space::big_space_plugin::RootGrid;
|
||||||
use crate::plugins::environment::systems::voxels::structure::*;
|
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};
|
||||||
|
|
||||||
pub fn setup(
|
pub fn setup(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
root: Res<RootGrid>,
|
root: Res<RootGrid>,
|
||||||
) {
|
) {
|
||||||
|
// Octree parameters
|
||||||
let unit_size = 1.0_f32;
|
let unit_size = 1.0_f32;
|
||||||
let octree_base_size = 64.0 * unit_size;
|
let octree_base_size = 64.0 * unit_size;
|
||||||
let octree_depth = 10;
|
let octree_depth = 10;
|
||||||
|
|
||||||
// 1. Create octree and wrap in Arc<Mutex<>> for thread-safe generation
|
let path = Path::new("octree.bin");
|
||||||
let mut octree = SparseVoxelOctree::new(octree_depth, octree_base_size, false, false, false);
|
|
||||||
|
|
||||||
// 2. Generate sphere in parallel, dropping the cloned Arc inside the function
|
|
||||||
|
let mut octree = if path.exists() {
|
||||||
|
match SparseVoxelOctree::load_from_file(path) {
|
||||||
|
Ok(tree) => tree,
|
||||||
|
Err(err) => {
|
||||||
|
error!("failed to load octree: {err}");
|
||||||
|
SparseVoxelOctree::new(octree_depth, octree_base_size, false, false, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut tree = SparseVoxelOctree::new(octree_depth, octree_base_size, false, false, false);
|
||||||
let color = Color::rgb(0.2, 0.8, 0.2);
|
let color = Color::rgb(0.2, 0.8, 0.2);
|
||||||
|
// How many random spheres?
|
||||||
|
/*const NUM_SPHERES: usize = 5;
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
generate_voxel_sphere(&mut octree, 110, color);
|
for _ in 0..NUM_SPHERES {
|
||||||
|
let center = Vec3::new(
|
||||||
|
rng.gen_range(-1000.0..1000.0),
|
||||||
|
rng.gen_range(-1000.0..1000.0),
|
||||||
|
rng.gen_range(-1000.0..1000.0),
|
||||||
|
);
|
||||||
|
|
||||||
// 4. Spawn entity with both Transform and the real octree component
|
let radius = rng.gen_range(20..=150); // voxels
|
||||||
|
|
||||||
|
generate_voxel_sphere_parallel(&mut tree, center, radius, color);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
generate_voxel_sphere(&mut tree, 200, color);
|
||||||
|
tree
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Attach octree to the scene graph
|
||||||
commands.entity(root.0).with_children(|parent| {
|
commands.entity(root.0).with_children(|parent| {
|
||||||
parent.spawn((Transform::default(), octree));
|
parent.spawn((Transform::default(), octree));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_voxel_sphere_parallel(
|
||||||
|
octree: &mut SparseVoxelOctree,
|
||||||
|
center: Vec3,
|
||||||
|
radius: i32,
|
||||||
|
color: Color,
|
||||||
|
) {
|
||||||
|
let step = octree.get_spacing_at_depth(octree.max_depth);
|
||||||
|
let radius_sq = radius * radius;
|
||||||
|
|
||||||
|
// 1. Collect voxel positions in parallel
|
||||||
|
let voxels: Vec<(Vec3, Voxel)> = (-radius..=radius)
|
||||||
|
.into_par_iter()
|
||||||
|
.flat_map_iter(|ix| {
|
||||||
|
let dx2 = ix * ix;
|
||||||
|
(-radius..=radius).flat_map(move |iy| {
|
||||||
|
let dy2 = iy * iy;
|
||||||
|
let r2_xy = dx2 + dy2;
|
||||||
|
|
||||||
|
if r2_xy > radius_sq {
|
||||||
|
return Vec::new(); // this (x,y) column is outside
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_z = ((radius_sq - r2_xy) as f32).sqrt() as i32;
|
||||||
|
(-max_z..=max_z).map(move |iz| {
|
||||||
|
let pos = Vec3::new(
|
||||||
|
center.x + ix as f32 * step,
|
||||||
|
center.y + iy as f32 * step,
|
||||||
|
center.z + iz as f32 * step,
|
||||||
|
);
|
||||||
|
(pos, Voxel { color })
|
||||||
|
}).collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// 2. Single-threaded insert (keeps `SparseVoxelOctree` API unchanged)
|
||||||
|
for (pos, voxel) in voxels {
|
||||||
|
octree.insert(pos, voxel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn generate_voxel_sphere(
|
fn generate_voxel_sphere(
|
||||||
octree: &mut SparseVoxelOctree,
|
octree: &mut SparseVoxelOctree,
|
||||||
|
|||||||
@ -14,8 +14,8 @@ pub fn update_chunk_lods(
|
|||||||
|
|
||||||
// Borrow the octree only once to avoid repeated query lookups
|
// Borrow the octree only once to avoid repeated query lookups
|
||||||
let mut tree = tree_q.single_mut();
|
let mut tree = tree_q.single_mut();
|
||||||
let max_depth = tree.max_depth;
|
let max_depth = tree.max_depth - 1;
|
||||||
let range_step = cfg.view_distance_chunks as f32 / max_depth as f32;
|
let range_step = cfg.view_distance_chunks as f32 / (max_depth as f32 - 1.0);
|
||||||
let chunk_size = CHUNK_SIZE as f32 * tree.get_spacing_at_depth(max_depth);
|
let chunk_size = CHUNK_SIZE as f32 * tree.get_spacing_at_depth(max_depth);
|
||||||
|
|
||||||
let mut changed = Vec::new();
|
let mut changed = Vec::new();
|
||||||
|
|||||||
@ -20,7 +20,6 @@ impl SparseVoxelOctree {
|
|||||||
size,
|
size,
|
||||||
show_wireframe,
|
show_wireframe,
|
||||||
show_world_grid,
|
show_world_grid,
|
||||||
show_chunks,
|
|
||||||
dirty: Vec::new(),
|
dirty: Vec::new(),
|
||||||
dirty_chunks: Default::default(),
|
dirty_chunks: Default::default(),
|
||||||
occupied_chunks: Default::default(),
|
occupied_chunks: Default::default(),
|
||||||
@ -482,6 +481,7 @@ impl SparseVoxelOctree {
|
|||||||
self.dirty.clear();
|
self.dirty.clear();
|
||||||
self.dirty_chunks.clear();
|
self.dirty_chunks.clear();
|
||||||
self.occupied_chunks.clear();
|
self.occupied_chunks.clear();
|
||||||
|
|
||||||
let voxels = Self::collect_voxels_from_node(&self.root, self.size);
|
let voxels = Self::collect_voxels_from_node(&self.root, self.size);
|
||||||
for (pos, _voxel, _depth) in voxels {
|
for (pos, _voxel, _depth) in voxels {
|
||||||
let key = chunk_key_from_world(self, pos);
|
let key = chunk_key_from_world(self, pos);
|
||||||
|
|||||||
@ -42,7 +42,7 @@ pub struct OctreeNode {
|
|||||||
}
|
}
|
||||||
/// Represents the root of the sparse voxel octree.
|
/// Represents the root of the sparse voxel octree.
|
||||||
/// Represents the root of the sparse voxel octree.
|
/// Represents the root of the sparse voxel octree.
|
||||||
#[derive(Debug, Component, Serialize, Deserialize)]
|
#[derive(Debug, Component, Serialize, Deserialize, Clone)]
|
||||||
pub struct SparseVoxelOctree {
|
pub struct SparseVoxelOctree {
|
||||||
|
|
||||||
pub root: OctreeNode,
|
pub root: OctreeNode,
|
||||||
@ -50,7 +50,6 @@ pub struct SparseVoxelOctree {
|
|||||||
pub size: f32,
|
pub size: f32,
|
||||||
pub show_wireframe: bool,
|
pub show_wireframe: bool,
|
||||||
pub show_world_grid: bool,
|
pub show_world_grid: bool,
|
||||||
pub show_chunks: bool,
|
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub dirty: Vec<DirtyVoxel>,
|
pub dirty: Vec<DirtyVoxel>,
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
use std::path::Path;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use crate::plugins::environment::systems::camera_system::CameraController;
|
use crate::plugins::environment::systems::camera_system::CameraController;
|
||||||
|
use crate::plugins::environment::systems::voxels::octree;
|
||||||
use crate::plugins::environment::systems::voxels::structure::*;
|
use crate::plugins::environment::systems::voxels::structure::*;
|
||||||
|
|
||||||
///TODO
|
///TODO
|
||||||
@ -28,16 +30,37 @@ pub fn voxel_system(
|
|||||||
octree.show_world_grid = !octree.show_world_grid;
|
octree.show_world_grid = !octree.show_world_grid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if keyboard_input.just_pressed(KeyCode::F4){
|
|
||||||
for mut octree in octree_query.iter_mut() {
|
|
||||||
octree.show_chunks = !octree.show_chunks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if keyboard_input.just_pressed(KeyCode::KeyQ) && window.cursor_options.visible == false{
|
if keyboard_input.just_pressed(KeyCode::KeyQ) && window.cursor_options.visible == false{
|
||||||
for mut octree in octree_query.iter_mut() {
|
for mut octree in octree_query.iter_mut() {
|
||||||
octree.insert(transform.translation, Voxel::new(Color::srgb(1.0, 0.0, 0.0)));
|
octree.insert(transform.translation, Voxel::new(Color::srgb(1.0, 0.0, 0.0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if keyboard_input.just_pressed(KeyCode::F4){
|
||||||
|
let path = Path::new("octree.bin");
|
||||||
|
for octree in octree_query.iter() {
|
||||||
|
if let Err(e) = octree.save_to_file(path) {
|
||||||
|
error!("failed to save octree: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* if keyboard_input.just_pressed(KeyCode::F5){
|
||||||
|
let path = Path::new("octree.bin");
|
||||||
|
if path.exists() {
|
||||||
|
let path = Path::new("octree.bin");
|
||||||
|
|
||||||
|
let mut octree = if path.exists() {
|
||||||
|
match SparseVoxelOctree::load_from_file(path) {
|
||||||
|
Ok(tree) => tree,
|
||||||
|
Err(err) => {
|
||||||
|
error!("failed to load octree: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
// =======================
|
// =======================
|
||||||
// 6) Building
|
// 6) Building
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user