all but remove_voxel done for oct-tree structure handling. remaining: remove_voxel() and rendering code
This commit is contained in:
parent
8567b102a8
commit
463e41ac56
136
src/oct_tree.rs
136
src/oct_tree.rs
|
@ -20,7 +20,7 @@ struct OctTree<T> {
|
|||
root: TreeNode<T>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
struct Path {
|
||||
packed: u64,
|
||||
length: usize,
|
||||
|
@ -71,6 +71,8 @@ impl<T: Clone> OctTree<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove_voxel(&mut self, location: Vec3) {}
|
||||
|
||||
pub fn set_voxel_at_path(&mut self, path: &Path, value: T) -> bool {
|
||||
// return value is whether it was successful
|
||||
let mut iter = &mut self.root;
|
||||
|
@ -239,6 +241,95 @@ impl<T: Clone> OctTree<T> {
|
|||
return Default::default();
|
||||
}
|
||||
|
||||
pub fn collect_voxels(&self) -> Vec<(Path, Vec3, T)> {
|
||||
let mut result = Vec::new();
|
||||
Self::visitor(
|
||||
&self.root,
|
||||
self.center,
|
||||
self.size,
|
||||
&mut result,
|
||||
Default::default(),
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn bounding_box(&self) -> Option<(Vec3, Vec3)> {
|
||||
//center, size
|
||||
let contents = self.collect_voxels();
|
||||
let mut min: Option<Vec3> = None;
|
||||
let mut max: Option<Vec3> = None;
|
||||
for each in contents.iter() {
|
||||
if min.is_none() {
|
||||
min = Some(each.1);
|
||||
} else {
|
||||
let mut cont = min.unwrap();
|
||||
if cont.x > each.1.x {
|
||||
cont.x = each.1.x;
|
||||
min = Some(cont);
|
||||
}
|
||||
if cont.y > each.1.y {
|
||||
cont.y = each.1.y;
|
||||
min = Some(cont);
|
||||
}
|
||||
if cont.z > each.1.z {
|
||||
cont.z = each.1.z;
|
||||
min = Some(cont);
|
||||
}
|
||||
}
|
||||
if max.is_none() {
|
||||
max = Some(each.1);
|
||||
} else {
|
||||
let mut cont: Vec3 = max.unwrap();
|
||||
if cont.x < each.1.x {
|
||||
cont.x = each.1.x;
|
||||
max = Some(cont);
|
||||
}
|
||||
if cont.y < each.1.y {
|
||||
cont.y = each.1.y;
|
||||
max = Some(cont);
|
||||
}
|
||||
if cont.z < each.1.z {
|
||||
cont.z = each.1.z;
|
||||
max = Some(cont);
|
||||
}
|
||||
}
|
||||
}
|
||||
if max.is_none() && min.is_none() {
|
||||
return None;
|
||||
} else {
|
||||
let center = min.unwrap() + max.unwrap();
|
||||
let center = center / 2.;
|
||||
let size = max.unwrap() - min.unwrap() + Vec3::ONE; // + 1 accounts for size of voxels themself, one half a voxel on each side
|
||||
return Some((center, size));
|
||||
}
|
||||
}
|
||||
|
||||
fn visitor(
|
||||
subject: &TreeNode<T>,
|
||||
location: Vec3,
|
||||
size: usize,
|
||||
result: &mut Vec<(Path, Vec3, T)>,
|
||||
path: Path,
|
||||
) {
|
||||
match subject {
|
||||
TreeNode::Branch(branch) => {
|
||||
let branch = branch.as_ref();
|
||||
for (index, node) in branch.iter().enumerate() {
|
||||
let (subpos, subsize) = sub_region(location, size, index as i32);
|
||||
let mut path_next = path.clone();
|
||||
set_pindex(&mut path_next, path.length, index);
|
||||
Self::visitor(node, subpos, subsize, result, path_next);
|
||||
}
|
||||
}
|
||||
TreeNode::Leaf(value) => {
|
||||
result.push((path, location, value.clone()));
|
||||
}
|
||||
TreeNode::None => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn voxel_at_path(&self, path: &Path) -> Option<T> {
|
||||
// return value is whether it was successful
|
||||
let mut iter = &self.root;
|
||||
|
@ -321,8 +412,6 @@ impl<T: Clone> OctTree<T> {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn remove_voxel(&mut self, location: Vec3) {}
|
||||
}
|
||||
|
||||
pub fn bounds_contains(center: Vec3, size: usize, subject: Vec3) -> bool {
|
||||
|
@ -469,7 +558,7 @@ pub fn test_path_return() {
|
|||
}
|
||||
let res1 = octtwee.voxel_at_location(Vec3::new(190., 15., -100.));
|
||||
match res1.clone() {
|
||||
Some((b, c)) => {
|
||||
Some((_, c)) => {
|
||||
assert_eq!(res0.packed, res1.clone().unwrap().1.packed); //internal path consistency with both functions
|
||||
assert_eq!(
|
||||
Vec3::new(190., 15., -100.),
|
||||
|
@ -500,6 +589,45 @@ pub fn test_path_return() {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
pub fn test_bounding() {
|
||||
let mut octtree = OctTree::<()>::new(Vec3::ZERO, ());
|
||||
octtree.set_voxel_at_location(Vec3::splat(10.), ());
|
||||
assert_eq!(
|
||||
octtree.bounding_box().unwrap(),
|
||||
(Vec3::splat(5.), Vec3::splat(11.))
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
pub fn test_collect() {
|
||||
let zeropos = Vec3::ZERO;
|
||||
let otherpos = Vec3::new(10., -5., 1.);
|
||||
let mut octtree = OctTree::<usize>::new(zeropos, 0);
|
||||
octtree.set_voxel_at_location(otherpos, 27);
|
||||
let x = octtree.collect_voxels();
|
||||
assert_eq!(
|
||||
x[0],
|
||||
(
|
||||
Path {
|
||||
packed: 1170,
|
||||
length: 4,
|
||||
},
|
||||
Vec3::ZERO,
|
||||
0
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
x[1],
|
||||
(
|
||||
Path {
|
||||
packed: 902,
|
||||
length: 4,
|
||||
},
|
||||
otherpos,
|
||||
27
|
||||
)
|
||||
);
|
||||
}
|
||||
/*
|
||||
use rand::Rng;
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue