fewer octr tree checks when growing a volume
This commit is contained in:
parent
886f92470c
commit
1d4b31c142
2 changed files with 115 additions and 15 deletions
src/scene
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue