fewer octr tree checks when growing a volume

This commit is contained in:
zomseffen 2025-01-24 09:59:15 +01:00
parent 886f92470c
commit 1d4b31c142
2 changed files with 115 additions and 15 deletions

View file

@ -57,6 +57,7 @@ impl EmptyVolume {
let mut neighbors: OctTree<Rc<RefCell<EmptyVolume>>> = OctTree::create(tree.size).unwrap();
let start_time = Instant::now();
// iterate over all block positions in the oct tree
let mut check_its = 0;
for x_index in 0..tree.size {
for y_index in 0..tree.size {
for z_index in 0..tree.size {
@ -80,28 +81,102 @@ impl EmptyVolume {
println!("start growing volume x");
// MARK: Start new Volume
let mut x_size = 0;
let mut y_size = 0;
let mut z_size = 0;
if query_result.1 > 1 {
x_size = query_result.1 - 1 - (x_index - query_result.2.0);
y_size = query_result.1 - 1 - (y_index - query_result.2.1);
z_size = query_result.1 - 1 - (z_index - query_result.2.2);
println!("enhanced starting size: {}, {}, {}", x_size+1, y_size+1, z_size+1);
}
let mut grow = true;
while grow {
grow = tree.get_element(x_index + x_size + 1, y_index, z_index).is_none() && neighbors.get_element(x_index + x_size + 1, y_index, z_index).is_none();
grow &= (x_index + x_size + 1) < tree.size;
if grow {
let mut z = 0;
let mut y = 0;
while z < z_size.max(1) && y < y_size.max(1) {
let query_result = tree.test_element(x_index + x_size + 1, y_index + y, z_index + z);
check_its += 1;
grow &= !query_result.0 &&
neighbors.get_element(x_index + x_size + 1, y_index + y, z_index + z).is_none();
if query_result.1 > 1 {
let start_x = query_result.2.0;
let start_y = query_result.2.1;
let start_z = query_result.2.2;
let end_x = query_result.2.0 + query_result.1;
let end_y = query_result.2.1 + query_result.1;
let end_z = query_result.2.2 + query_result.1;
if start_z <= z && z_index + z_size <= end_z {
// we can skip iterating z
z = end_z;
if start_y <= y && y_index + y_size <= end_y {
// we can skip iterating y
y = end_y;
}
}
}
if !grow {
break;
}
z += 1;
if z >= z_size {
z = 0;
y += 1;
}
}
}
if grow {
x_size += 1;
}
}
println!("start growing volume y");
let mut y_size = 0;
grow = true;
while grow {
grow &= (y_index + y_size + 1) < tree.size;
if grow {
for x in 0..x_size {
grow &= tree.get_element(x_index + x, y_index + y_size + 1, z_index).is_none() &&
neighbors.get_element(x_index + x, y_index + y_size + 1, z_index).is_none();
if grow {
let mut z = 0;
let mut x = 0;
while z < z_size.max(1) && x < x_size.max(1) {
let query_result = tree.test_element(x_index + x, y_index + y_size + 1, z_index + z);
check_its += 1;
grow &= !query_result.0 &&
neighbors.get_element(x_index + x, y_index + y_size + 1, z_index + z).is_none();
if query_result.1 > 1 {
let start_x = query_result.2.0;
let start_y = query_result.2.1;
let start_z = query_result.2.2;
let end_x = query_result.2.0 + query_result.1;
let end_y = query_result.2.1 + query_result.1;
let end_z = query_result.2.2 + query_result.1;
if start_z <= z && z_index + z_size <= end_z {
// we can skip iterating z
z = end_z;
if start_x <= x && x_index + x_size <= end_x {
// we can skip iterating x
x = end_x;
}
}
}
if !grow {
break;
}
}
z += 1;
if z >= z_size {
z = 0;
x += 1;
}
}
}
if grow {
@ -109,22 +184,46 @@ impl EmptyVolume {
}
}
println!("start growing volume z");
let mut z_size = 0;
grow = true;
while grow {
grow &= (z_index + z_size + 1) < tree.size;
if grow {
for x in 0..x_size {
for y in 0..y_size {
grow &= tree.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none() &&
neighbors.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none();
if !grow {
break;
let mut y = 0;
let mut x = 0;
while y < y_size.max(1) && x < x_size.max(1) {
let query_result = tree.test_element(x_index + x, y_index + y, z_index + z_size + 1);
check_its += 1;
grow &= !query_result.0 &&
neighbors.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none();
if query_result.1 > 1 {
let start_x = query_result.2.0;
let start_y = query_result.2.1;
let start_z = query_result.2.2;
let end_x = query_result.2.0 + query_result.1;
let end_y = query_result.2.1 + query_result.1;
let end_z = query_result.2.2 + query_result.1;
if start_x <= x && x_index + x_size <= end_x {
// we can skip iterating x
x = end_x;
if start_y <= y && y_index + y_size <= end_y {
// we can skip iterating y
y = end_y;
}
}
}
if !grow {
break;
}
x += 1;
if x >= x_size {
x = 0;
y += 1;
}
}
}
if grow {
@ -368,6 +467,7 @@ impl EmptyVolume {
}
}
}
println!("Did {} oct tree checks!", check_its);
println!("add the neighbor linkage for all the volumes of the oct tree");
// MARK: Neighbor Linkage
for reference in volumes.iter_mut() {

View file

@ -7,7 +7,7 @@ use crate::primitives::cube::Cube;
extern crate rand;
pub const CHUNK_SIZE_EXPONENT: u32 = 4;
pub const CHUNK_SIZE_EXPONENT: u32 = 8;
pub const CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT);
pub const MAX_TREE_DEPTH: usize = CHUNK_SIZE_EXPONENT as usize - 2;
pub const MIN_CHUNK_SIZE: usize = CHUNK_SIZE / (2 as usize).pow(MAX_TREE_DEPTH as u32);