Add generic BinaryTree struct and use in BoundingVolumeHierarchy
No change in runtime, as expected.
This commit is contained in:
parent
5aad1242b3
commit
231be6a1a5
|
|
@ -2,6 +2,7 @@ use super::{
|
||||||
Aggregate, BoundingBox, HasBoundingBox, Intersect, IntersectP, IntersectionInfo, Primitive, Ray,
|
Aggregate, BoundingBox, HasBoundingBox, Intersect, IntersectP, IntersectionInfo, Primitive, Ray,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::util::binary_tree::BinaryTree;
|
||||||
use crate::util::morton::morton_order_value_3d;
|
use crate::util::morton::morton_order_value_3d;
|
||||||
use crate::util::normalizer::Point3Normalizer;
|
use crate::util::normalizer::Point3Normalizer;
|
||||||
use crate::Real;
|
use crate::Real;
|
||||||
|
|
@ -18,18 +19,8 @@ use std::mem::swap;
|
||||||
/// Each node knows the overall bounds of all it's children, which means that a ray that
|
/// Each node knows the overall bounds of all it's children, which means that a ray that
|
||||||
/// doesn't intersect the [BoundingBox](BoundingBox) of the node doesn't intersect any of
|
/// doesn't intersect the [BoundingBox](BoundingBox) of the node doesn't intersect any of
|
||||||
/// the primitives stored in it's children.
|
/// the primitives stored in it's children.
|
||||||
pub enum BoundingVolumeHierarchy<T: Real> {
|
pub type BoundingVolumeHierarchy<T: Real> =
|
||||||
Node {
|
BinaryTree<BoundingBox<T>, (BoundingBox<T>, Box<dyn Primitive<T>>)>;
|
||||||
bounds: BoundingBox<T>,
|
|
||||||
left: Box<BoundingVolumeHierarchy<T>>,
|
|
||||||
right: Box<BoundingVolumeHierarchy<T>>,
|
|
||||||
},
|
|
||||||
Leaf {
|
|
||||||
bounds: BoundingBox<T>,
|
|
||||||
primitive: Box<dyn Primitive<T>>,
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn centre<T: Real>(bounds: &BoundingBox<T>) -> Point3<T> {
|
fn centre<T: Real>(bounds: &BoundingBox<T>) -> Point3<T> {
|
||||||
let two = convert(2.0);
|
let two = convert(2.0);
|
||||||
|
|
@ -74,8 +65,8 @@ impl<T: Real> BoundingVolumeHierarchy<T> {
|
||||||
let left = Box::new(Self::from_sorted_nodes(&mut nodes[..midpoint]));
|
let left = Box::new(Self::from_sorted_nodes(&mut nodes[..midpoint]));
|
||||||
let right = Box::new(Self::from_sorted_nodes(&mut nodes[midpoint..]));
|
let right = Box::new(Self::from_sorted_nodes(&mut nodes[midpoint..]));
|
||||||
let bounds = left.get_bounds().union(&right.get_bounds());
|
let bounds = left.get_bounds().union(&right.get_bounds());
|
||||||
BoundingVolumeHierarchy::Node {
|
BoundingVolumeHierarchy::Branch {
|
||||||
bounds,
|
value: bounds,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +75,9 @@ impl<T: Real> BoundingVolumeHierarchy<T> {
|
||||||
let mut primitive = None;
|
let mut primitive = None;
|
||||||
swap(primitive_src, &mut primitive);
|
swap(primitive_src, &mut primitive);
|
||||||
let primitive = primitive.unwrap();
|
let primitive = primitive.unwrap();
|
||||||
BoundingVolumeHierarchy::Leaf { bounds, primitive }
|
BoundingVolumeHierarchy::Leaf {
|
||||||
|
value: (bounds, primitive),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
BoundingVolumeHierarchy::None
|
BoundingVolumeHierarchy::None
|
||||||
}
|
}
|
||||||
|
|
@ -92,30 +85,24 @@ impl<T: Real> BoundingVolumeHierarchy<T> {
|
||||||
|
|
||||||
pub fn get_bounds(&self) -> BoundingBox<T> {
|
pub fn get_bounds(&self) -> BoundingBox<T> {
|
||||||
match self {
|
match self {
|
||||||
BoundingVolumeHierarchy::Node {
|
BoundingVolumeHierarchy::Branch {
|
||||||
bounds,
|
value,
|
||||||
left: _,
|
left: _,
|
||||||
right: _,
|
right: _,
|
||||||
} => *bounds,
|
} => *value,
|
||||||
BoundingVolumeHierarchy::Leaf {
|
BoundingVolumeHierarchy::Leaf { value: (bounds, _) } => *bounds,
|
||||||
bounds,
|
|
||||||
primitive: _,
|
|
||||||
} => *bounds,
|
|
||||||
BoundingVolumeHierarchy::None => BoundingBox::empty(),
|
BoundingVolumeHierarchy::None => BoundingBox::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn count_leaves(&self) -> usize {
|
pub fn count_leaves(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Self::Node {
|
Self::Branch {
|
||||||
bounds: _,
|
value: _,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
} => right.count_leaves() + left.count_leaves(),
|
} => right.count_leaves() + left.count_leaves(),
|
||||||
Self::Leaf {
|
Self::Leaf { value: _ } => 1,
|
||||||
bounds: _,
|
|
||||||
primitive: _,
|
|
||||||
} => 1,
|
|
||||||
Self::None => 0,
|
Self::None => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -142,8 +129,8 @@ fn closest_intersection<T: Real>(
|
||||||
impl<T: Real> Intersect<T> for BoundingVolumeHierarchy<T> {
|
impl<T: Real> Intersect<T> for BoundingVolumeHierarchy<T> {
|
||||||
fn intersect<'a>(&'a self, ray: &Ray<T>) -> Option<IntersectionInfo<T>> {
|
fn intersect<'a>(&'a self, ray: &Ray<T>) -> Option<IntersectionInfo<T>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Node {
|
Self::Branch {
|
||||||
bounds,
|
value: bounds,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
} => {
|
} => {
|
||||||
|
|
@ -154,8 +141,7 @@ impl<T: Real> Intersect<T> for BoundingVolumeHierarchy<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Leaf {
|
Self::Leaf {
|
||||||
bounds: _,
|
value: (_, primitive),
|
||||||
primitive,
|
|
||||||
} => primitive.intersect(ray),
|
} => primitive.intersect(ray),
|
||||||
Self::None => None,
|
Self::None => None,
|
||||||
}
|
}
|
||||||
|
|
@ -194,8 +180,8 @@ impl<'a, T: Real> Iterator for FilterIterator<'a, T> {
|
||||||
//let mut result = Option::None;
|
//let mut result = Option::None;
|
||||||
while let Some(next_subtree) = self.unsearched_subtrees.pop() {
|
while let Some(next_subtree) = self.unsearched_subtrees.pop() {
|
||||||
match next_subtree {
|
match next_subtree {
|
||||||
BoundingVolumeHierarchy::Node {
|
BoundingVolumeHierarchy::Branch {
|
||||||
bounds,
|
value: bounds,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
} => {
|
} => {
|
||||||
|
|
@ -205,8 +191,7 @@ impl<'a, T: Real> Iterator for FilterIterator<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BoundingVolumeHierarchy::Leaf {
|
BoundingVolumeHierarchy::Leaf {
|
||||||
bounds,
|
value: (bounds, ref primitive),
|
||||||
ref primitive,
|
|
||||||
} => {
|
} => {
|
||||||
if (self.predicate)(bounds) {
|
if (self.predicate)(bounds) {
|
||||||
return Some(&**primitive);
|
return Some(&**primitive);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
pub enum BinaryTree<BranchValue, LeafValue> {
|
||||||
|
Branch {
|
||||||
|
value: BranchValue,
|
||||||
|
left: Box<Self>,
|
||||||
|
right: Box<Self>,
|
||||||
|
},
|
||||||
|
Leaf {
|
||||||
|
value: LeafValue,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ pub use interval::Interval;
|
||||||
|
|
||||||
pub mod algebra_utils;
|
pub mod algebra_utils;
|
||||||
pub mod axis_aligned_bounding_box;
|
pub mod axis_aligned_bounding_box;
|
||||||
|
pub mod binary_tree;
|
||||||
pub mod morton;
|
pub mod morton;
|
||||||
pub mod normalizer;
|
pub mod normalizer;
|
||||||
mod tile_iterator;
|
mod tile_iterator;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue