diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs index a97e19c..db02694 100644 --- a/src/scene/empty_volume.rs +++ b/src/scene/empty_volume.rs @@ -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() { diff --git a/src/scene/oct_tree.rs b/src/scene/oct_tree.rs index 53cfd70..bdab4db 100644 --- a/src/scene/oct_tree.rs +++ b/src/scene/oct_tree.rs @@ -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);