Adjusted the API of the BVH builder.
The bounder closure now returns slices of BBoxes instead of filling in a given Vec.
This commit is contained in:
parent
655c16542d
commit
a569586455
48
src/bvh.rs
48
src/bvh.rs
|
@ -11,7 +11,6 @@ pub struct BVH {
|
||||||
bounds: Vec<BBox>,
|
bounds: Vec<BBox>,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
bounds_cache: Vec<BBox>,
|
bounds_cache: Vec<BBox>,
|
||||||
bounds_temp: Vec<BBox>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -30,65 +29,50 @@ enum BVHNode {
|
||||||
|
|
||||||
impl BVH {
|
impl BVH {
|
||||||
pub fn from_objects<'a, T, F>(objects: &mut [T], objects_per_leaf: usize, bounder: F) -> BVH
|
pub fn from_objects<'a, T, F>(objects: &mut [T], objects_per_leaf: usize, bounder: F) -> BVH
|
||||||
where F: Fn(&T, &mut Vec<BBox>)
|
where F: 'a + Fn(&T) -> &'a [BBox]
|
||||||
{
|
{
|
||||||
let mut bvh = BVH {
|
let mut bvh = BVH {
|
||||||
nodes: Vec::new(),
|
nodes: Vec::new(),
|
||||||
bounds: Vec::new(),
|
bounds: Vec::new(),
|
||||||
depth: 0,
|
depth: 0,
|
||||||
bounds_cache: Vec::new(),
|
bounds_cache: Vec::new(),
|
||||||
bounds_temp: Vec::new(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bvh.recursive_build(0, 0, objects_per_leaf, objects, &bounder);
|
bvh.recursive_build(0, 0, objects_per_leaf, objects, &bounder);
|
||||||
bvh.bounds_cache.clear();
|
bvh.bounds_cache.clear();
|
||||||
bvh.bounds_temp.clear();
|
|
||||||
bvh.bounds_cache.shrink_to_fit();
|
bvh.bounds_cache.shrink_to_fit();
|
||||||
bvh.bounds_temp.shrink_to_fit();
|
|
||||||
|
|
||||||
println!("BVH Depth: {}", bvh.depth);
|
println!("BVH Depth: {}", bvh.depth);
|
||||||
|
|
||||||
bvh
|
bvh
|
||||||
}
|
}
|
||||||
|
|
||||||
fn acc_bounds<T, F>(&mut self, objects1: &mut [T], bounder: F)
|
fn acc_bounds<'a, T, F>(&mut self, objects1: &mut [T], bounder: &F)
|
||||||
where F: Fn(&T, &mut Vec<BBox>)
|
where F: 'a + Fn(&T) -> &'a [BBox]
|
||||||
{
|
{
|
||||||
// TODO: merging of different length bounds
|
// TODO: merging of different length bounds
|
||||||
self.bounds_cache.clear();
|
self.bounds_cache.clear();
|
||||||
bounder(&objects1[0], &mut self.bounds_cache);
|
for bb in bounder(&objects1[0]).iter() {
|
||||||
|
self.bounds_cache.push(*bb);
|
||||||
|
}
|
||||||
for obj in &objects1[1..] {
|
for obj in &objects1[1..] {
|
||||||
self.bounds_temp.clear();
|
let bounds = bounder(obj);
|
||||||
bounder(obj, &mut self.bounds_temp);
|
debug_assert!(self.bounds_cache.len() == bounds.len());
|
||||||
debug_assert!(self.bounds_cache.len() == self.bounds_temp.len());
|
for i in 0..bounds.len() {
|
||||||
for i in 0..self.bounds_cache.len() {
|
self.bounds_cache[i] = self.bounds_cache[i] | bounds[i];
|
||||||
self.bounds_cache[i] = self.bounds_cache[i] | self.bounds_temp[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recursive_build<T, F>(&mut self,
|
fn recursive_build<'a, T, F>(&mut self,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
objects_per_leaf: usize,
|
objects_per_leaf: usize,
|
||||||
objects: &mut [T],
|
objects: &mut [T],
|
||||||
bounder: &F)
|
bounder: &F)
|
||||||
-> (usize, (usize, usize))
|
-> (usize, (usize, usize))
|
||||||
where F: Fn(&T, &mut Vec<BBox>)
|
where F: 'a + Fn(&T) -> &'a [BBox]
|
||||||
{
|
{
|
||||||
// fn acc_bounds2(objects2: &mut [T]) {
|
|
||||||
// self.bounds_cache2.clear();
|
|
||||||
// bounder(&objects2[0], &mut self.bounds_cache2);
|
|
||||||
// for obj in &objects2[1..] {
|
|
||||||
// self.bounds_temp.clear();
|
|
||||||
// bounder(obj, &mut self.bounds_temp);
|
|
||||||
// debug_assert!(self.bounds_cache2.len() == self.bounds_temp.len());
|
|
||||||
// for i in 0..self.bounds_cache2.len() {
|
|
||||||
// self.bounds_cache2[i] = self.bounds_cache2[i] | self.bounds_temp[i];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
let me = self.nodes.len();
|
let me = self.nodes.len();
|
||||||
|
|
||||||
if objects.len() == 0 {
|
if objects.len() == 0 {
|
||||||
|
@ -122,9 +106,7 @@ impl BVH {
|
||||||
let bounds = {
|
let bounds = {
|
||||||
let mut bb = BBox::new();
|
let mut bb = BBox::new();
|
||||||
for obj in &objects[..] {
|
for obj in &objects[..] {
|
||||||
self.bounds_cache.clear();
|
bb = bb | lerp_slice(bounder(obj), 0.5);
|
||||||
bounder(obj, &mut self.bounds_cache);
|
|
||||||
bb = bb | lerp_slice(&self.bounds_cache[..], 0.5);
|
|
||||||
}
|
}
|
||||||
bb
|
bb
|
||||||
};
|
};
|
||||||
|
@ -145,9 +127,7 @@ impl BVH {
|
||||||
// Partition objects based on split
|
// Partition objects based on split
|
||||||
let split_index = {
|
let split_index = {
|
||||||
let mut split_i = partition(&mut objects[..], |obj| {
|
let mut split_i = partition(&mut objects[..], |obj| {
|
||||||
self.bounds_cache.clear();
|
let tb = lerp_slice(bounder(obj), 0.5);
|
||||||
bounder(obj, &mut self.bounds_cache);
|
|
||||||
let tb = lerp_slice(&self.bounds_cache[..], 0.5);
|
|
||||||
let centroid = (tb.min[split_axis] + tb.max[split_axis]) * 0.5;
|
let centroid = (tb.min[split_axis] + tb.max[split_axis]) * 0.5;
|
||||||
centroid < split_pos
|
centroid < split_pos
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,17 +21,24 @@ impl TriangleMesh {
|
||||||
triangles: Vec<(Point, Point, Point)>)
|
triangles: Vec<(Point, Point, Point)>)
|
||||||
-> TriangleMesh {
|
-> TriangleMesh {
|
||||||
assert!(triangles.len() % time_samples == 0);
|
assert!(triangles.len() % time_samples == 0);
|
||||||
|
|
||||||
let mut indices: Vec<usize> = (0..(triangles.len() / time_samples))
|
let mut indices: Vec<usize> = (0..(triangles.len() / time_samples))
|
||||||
.map(|n| n * time_samples)
|
.map(|n| n * time_samples)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let accel = BVH::from_objects(&mut indices[..], 3, |tri_i, bounds| {
|
let bounds = {
|
||||||
for tri in &triangles[*tri_i..(*tri_i + time_samples)] {
|
let mut bounds = Vec::new();
|
||||||
|
for tri in triangles.iter() {
|
||||||
let minimum = tri.0.min(tri.1.min(tri.2));
|
let minimum = tri.0.min(tri.1.min(tri.2));
|
||||||
let maximum = tri.0.max(tri.1.max(tri.2));
|
let maximum = tri.0.max(tri.1.max(tri.2));
|
||||||
bounds.push(BBox::from_points(minimum, maximum));
|
bounds.push(BBox::from_points(minimum, maximum));
|
||||||
}
|
}
|
||||||
});
|
bounds
|
||||||
|
};
|
||||||
|
|
||||||
|
let accel = BVH::from_objects(&mut indices[..],
|
||||||
|
3,
|
||||||
|
|tri_i| &bounds[*tri_i..(*tri_i + time_samples)]);
|
||||||
|
|
||||||
TriangleMesh {
|
TriangleMesh {
|
||||||
time_samples: time_samples,
|
time_samples: time_samples,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user