mirror of
https://github.com/eliasstepanik/voxel-simulation.git
synced 2026-01-10 21:38:29 +00:00
Merge pull request #12 from eliasstepanik/codex/fix-rogue-faces-rendering-on-lod-change
Fix chunk boundary updates
This commit is contained in:
commit
84b2f8f420
@ -19,7 +19,7 @@ pub fn setup(
|
||||
// 2. Generate sphere in parallel, dropping the cloned Arc inside the function
|
||||
let color = Color::rgb(0.2, 0.8, 0.2);
|
||||
|
||||
generate_voxel_sphere(&mut octree, 100, color);
|
||||
generate_voxel_sphere(&mut octree, 110, color);
|
||||
|
||||
// 4. Spawn entity with both Transform and the real octree component
|
||||
commands.entity(root.0).with_children(|parent| {
|
||||
|
||||
@ -6,7 +6,7 @@ use bevy::prelude::*;
|
||||
use bevy::render::mesh::{Indices, PrimitiveTopology, VertexAttributeValues};
|
||||
use bevy::render::render_asset::RenderAssetUsages;
|
||||
use crate::plugins::environment::systems::voxels::helper::chunk_key_from_world;
|
||||
use crate::plugins::environment::systems::voxels::structure::{DirtyVoxel, OctreeNode, Ray, SparseVoxelOctree, Voxel, AABB, NEIGHBOR_OFFSETS};
|
||||
use crate::plugins::environment::systems::voxels::structure::{DirtyVoxel, OctreeNode, Ray, SparseVoxelOctree, Voxel, AABB, NEIGHBOR_OFFSETS, CHUNK_SIZE, ChunkKey};
|
||||
|
||||
impl SparseVoxelOctree {
|
||||
/// Creates a new octree with the specified max depth, size, and wireframe visibility.
|
||||
@ -43,6 +43,7 @@ impl SparseVoxelOctree {
|
||||
self.dirty.push(dirty_voxel);
|
||||
let key = chunk_key_from_world(self, position);
|
||||
self.dirty_chunks.insert(key);
|
||||
self.mark_neighbor_chunks_dirty(position);
|
||||
self.occupied_chunks.insert(key);
|
||||
|
||||
|
||||
@ -92,6 +93,7 @@ impl SparseVoxelOctree {
|
||||
// mark the chunk
|
||||
let key = chunk_key_from_world(self, position);
|
||||
self.dirty_chunks.insert(key);
|
||||
self.mark_neighbor_chunks_dirty(position);
|
||||
|
||||
Self::remove_recursive(
|
||||
&mut self.root,
|
||||
@ -111,6 +113,50 @@ impl SparseVoxelOctree {
|
||||
self.dirty_chunks.clear();
|
||||
}
|
||||
|
||||
fn mark_neighbor_chunks_dirty(&mut self, position: Vec3) {
|
||||
let key = chunk_key_from_world(self, position);
|
||||
let step = self.get_spacing_at_depth(self.max_depth);
|
||||
let half = self.size * 0.5;
|
||||
|
||||
let gx = ((position.x + half) / step).floor() as i32;
|
||||
let gy = ((position.y + half) / step).floor() as i32;
|
||||
let gz = ((position.z + half) / step).floor() as i32;
|
||||
|
||||
let lx = gx - key.0 * CHUNK_SIZE;
|
||||
let ly = gy - key.1 * CHUNK_SIZE;
|
||||
let lz = gz - key.2 * CHUNK_SIZE;
|
||||
|
||||
let mut neighbors = [
|
||||
(lx == 0, ChunkKey(key.0 - 1, key.1, key.2)),
|
||||
(lx == CHUNK_SIZE - 1, ChunkKey(key.0 + 1, key.1, key.2)),
|
||||
(ly == 0, ChunkKey(key.0, key.1 - 1, key.2)),
|
||||
(ly == CHUNK_SIZE - 1, ChunkKey(key.0, key.1 + 1, key.2)),
|
||||
(lz == 0, ChunkKey(key.0, key.1, key.2 - 1)),
|
||||
(lz == CHUNK_SIZE - 1, ChunkKey(key.0, key.1, key.2 + 1)),
|
||||
];
|
||||
|
||||
for (cond, n) in neighbors.iter() {
|
||||
if *cond && self.occupied_chunks.contains(n) {
|
||||
self.dirty_chunks.insert(*n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark all six neighbor chunks of the given key as dirty if they exist.
|
||||
pub fn mark_neighbors_dirty_from_key(&mut self, key: ChunkKey) {
|
||||
let offsets = [
|
||||
(-1, 0, 0), (1, 0, 0),
|
||||
(0, -1, 0), (0, 1, 0),
|
||||
(0, 0, -1), (0, 0, 1),
|
||||
];
|
||||
for (dx, dy, dz) in offsets {
|
||||
let neighbor = ChunkKey(key.0 + dx, key.1 + dy, key.2 + dz);
|
||||
if self.occupied_chunks.contains(&neighbor) {
|
||||
self.dirty_chunks.insert(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_recursive(
|
||||
node: &mut OctreeNode,
|
||||
x: f32,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user