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 mut neighbors: OctTree<Rc<RefCell<EmptyVolume>>> = OctTree::create(tree.size).unwrap();
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
// iterate over all block positions in the oct tree
|
// iterate over all block positions in the oct tree
|
||||||
|
let mut check_its = 0;
|
||||||
for x_index in 0..tree.size {
|
for x_index in 0..tree.size {
|
||||||
for y_index in 0..tree.size {
|
for y_index in 0..tree.size {
|
||||||
for z_index in 0..tree.size {
|
for z_index in 0..tree.size {
|
||||||
|
@ -80,28 +81,102 @@ impl EmptyVolume {
|
||||||
println!("start growing volume x");
|
println!("start growing volume x");
|
||||||
// MARK: Start new Volume
|
// MARK: Start new Volume
|
||||||
let mut x_size = 0;
|
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;
|
let mut grow = true;
|
||||||
while grow {
|
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;
|
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 {
|
if grow {
|
||||||
x_size += 1;
|
x_size += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("start growing volume y");
|
println!("start growing volume y");
|
||||||
let mut y_size = 0;
|
|
||||||
grow = true;
|
grow = true;
|
||||||
while grow {
|
while grow {
|
||||||
grow &= (y_index + y_size + 1) < tree.size;
|
grow &= (y_index + y_size + 1) < tree.size;
|
||||||
if grow {
|
if grow {
|
||||||
for x in 0..x_size {
|
let mut z = 0;
|
||||||
grow &= tree.get_element(x_index + x, y_index + y_size + 1, z_index).is_none() &&
|
let mut x = 0;
|
||||||
neighbors.get_element(x_index + x, y_index + y_size + 1, z_index).is_none();
|
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 {
|
if !grow {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
z += 1;
|
||||||
|
if z >= z_size {
|
||||||
|
z = 0;
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if grow {
|
if grow {
|
||||||
|
@ -109,22 +184,46 @@ impl EmptyVolume {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("start growing volume z");
|
println!("start growing volume z");
|
||||||
let mut z_size = 0;
|
|
||||||
grow = true;
|
grow = true;
|
||||||
while grow {
|
while grow {
|
||||||
grow &= (z_index + z_size + 1) < tree.size;
|
grow &= (z_index + z_size + 1) < tree.size;
|
||||||
if grow {
|
if grow {
|
||||||
for x in 0..x_size {
|
let mut y = 0;
|
||||||
for y in 0..y_size {
|
let mut x = 0;
|
||||||
grow &= tree.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none() &&
|
while y < y_size.max(1) && x < x_size.max(1) {
|
||||||
neighbors.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none();
|
let query_result = tree.test_element(x_index + x, y_index + y, z_index + z_size + 1);
|
||||||
if !grow {
|
check_its += 1;
|
||||||
break;
|
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 {
|
if !grow {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x += 1;
|
||||||
|
if x >= x_size {
|
||||||
|
x = 0;
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if grow {
|
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");
|
println!("add the neighbor linkage for all the volumes of the oct tree");
|
||||||
// MARK: Neighbor Linkage
|
// MARK: Neighbor Linkage
|
||||||
for reference in volumes.iter_mut() {
|
for reference in volumes.iter_mut() {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::primitives::cube::Cube;
|
||||||
|
|
||||||
extern crate rand;
|
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 CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT);
|
||||||
pub const MAX_TREE_DEPTH: usize = CHUNK_SIZE_EXPONENT as usize - 2;
|
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);
|
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