BVH can now have multiple objects per leaf.
This commit is contained in:
parent
cb8db6a0b6
commit
5278675fb7
41
src/bvh.rs
41
src/bvh.rs
|
@ -23,12 +23,12 @@ enum BVHNode {
|
||||||
|
|
||||||
Leaf {
|
Leaf {
|
||||||
bounds: BBox,
|
bounds: BBox,
|
||||||
object_index: usize,
|
object_range: (usize, usize),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> BVH<'a, T> {
|
impl<'a, T> BVH<'a, T> {
|
||||||
pub fn from_objects<F>(objects: &'a mut [T], bounder: F) -> BVH<'a, T>
|
pub fn from_objects<F>(objects: &'a mut [T], objects_per_leaf: usize, bounder: F) -> BVH<'a, T>
|
||||||
where F: Fn(&T) -> BBox
|
where F: Fn(&T) -> BBox
|
||||||
{
|
{
|
||||||
let mut bvh = BVH {
|
let mut bvh = BVH {
|
||||||
|
@ -37,7 +37,7 @@ impl<'a, T> BVH<'a, T> {
|
||||||
depth: 0,
|
depth: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
bvh.recursive_build(0, 0, objects, &bounder);
|
bvh.recursive_build(0, 0, objects_per_leaf, objects, &bounder);
|
||||||
bvh.objects = objects;
|
bvh.objects = objects;
|
||||||
|
|
||||||
println!("BVH Depth: {}", bvh.depth);
|
println!("BVH Depth: {}", bvh.depth);
|
||||||
|
@ -49,6 +49,7 @@ impl<'a, T> BVH<'a, T> {
|
||||||
fn recursive_build<F>(&mut self,
|
fn recursive_build<F>(&mut self,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
|
objects_per_leaf: usize,
|
||||||
objects: &mut [T],
|
objects: &mut [T],
|
||||||
bounder: &F)
|
bounder: &F)
|
||||||
-> usize
|
-> usize
|
||||||
|
@ -58,11 +59,17 @@ impl<'a, T> BVH<'a, T> {
|
||||||
|
|
||||||
if objects.len() == 0 {
|
if objects.len() == 0 {
|
||||||
return 0;
|
return 0;
|
||||||
} else if objects.len() == 1 {
|
} else if objects.len() <= objects_per_leaf {
|
||||||
// Leaf node
|
// Leaf node
|
||||||
self.nodes.push(BVHNode::Leaf {
|
self.nodes.push(BVHNode::Leaf {
|
||||||
bounds: bounder(&objects[0]),
|
bounds: {
|
||||||
object_index: offset,
|
let mut bounds = bounder(&objects[0]);
|
||||||
|
for obj in &objects[1..] {
|
||||||
|
bounds = bounds | bounder(obj);
|
||||||
|
}
|
||||||
|
bounds
|
||||||
|
},
|
||||||
|
object_range: (offset, offset + objects.len()),
|
||||||
});
|
});
|
||||||
|
|
||||||
if self.depth < depth {
|
if self.depth < depth {
|
||||||
|
@ -112,9 +119,14 @@ impl<'a, T> BVH<'a, T> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create child nodes
|
// Create child nodes
|
||||||
self.recursive_build(offset, depth + 1, &mut objects[..split_index], bounder);
|
self.recursive_build(offset,
|
||||||
|
depth + 1,
|
||||||
|
objects_per_leaf,
|
||||||
|
&mut objects[..split_index],
|
||||||
|
bounder);
|
||||||
let child2_index = self.recursive_build(offset + split_index,
|
let child2_index = self.recursive_build(offset + split_index,
|
||||||
depth + 1,
|
depth + 1,
|
||||||
|
objects_per_leaf,
|
||||||
&mut objects[split_index..],
|
&mut objects[split_index..],
|
||||||
bounder);
|
bounder);
|
||||||
|
|
||||||
|
@ -153,8 +165,8 @@ impl<'a, T> BVHTraverser<'a, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Iterator for BVHTraverser<'a, T> {
|
impl<'a, T> Iterator for BVHTraverser<'a, T> {
|
||||||
type Item = (&'a T, &'a mut [Ray]);
|
type Item = (&'a [T], &'a mut [Ray]);
|
||||||
fn next(&mut self) -> Option<(&'a T, &'a mut [Ray])> {
|
fn next(&mut self) -> Option<(&'a [T], &'a mut [Ray])> {
|
||||||
let rays = unsafe { slice::from_raw_parts_mut(self.rays.0, self.rays.1) };
|
let rays = unsafe { slice::from_raw_parts_mut(self.rays.0, self.rays.1) };
|
||||||
while self.stack_ptr > 0 {
|
while self.stack_ptr > 0 {
|
||||||
match self.bvh.nodes[self.i_stack[self.stack_ptr]] {
|
match self.bvh.nodes[self.i_stack[self.stack_ptr]] {
|
||||||
|
@ -172,10 +184,15 @@ impl<'a, T> Iterator for BVHTraverser<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BVHNode::Leaf { bounds: _, object_index } => {
|
BVHNode::Leaf { bounds, object_range } => {
|
||||||
|
// let part = self.ray_i_stack[self.stack_ptr];
|
||||||
|
let part = partition(&mut rays[..self.ray_i_stack[self.stack_ptr]],
|
||||||
|
|r| bounds.intersect_ray(r));
|
||||||
self.stack_ptr -= 1;
|
self.stack_ptr -= 1;
|
||||||
return Some((&self.bvh.objects[object_index],
|
if part > 0 {
|
||||||
&mut rays[..self.ray_i_stack[self.stack_ptr + 1]]));
|
return Some((&self.bvh.objects[object_range.0..object_range.1],
|
||||||
|
&mut rays[..part]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -105,7 +105,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
triangles
|
triangles
|
||||||
};
|
};
|
||||||
let scene = bvh::BVH::from_objects(&mut triangles[..], |tri| {
|
let scene = bvh::BVH::from_objects(&mut triangles[..], 3, |tri| {
|
||||||
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));
|
||||||
BBox {
|
BBox {
|
||||||
|
@ -144,12 +144,14 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test ray against scene
|
// Test ray against scene
|
||||||
for (tri, rs) in bvh::BVHTraverser::from_bvh_and_ray(&scene, &mut rays[..]) {
|
for (tris, rs) in bvh::BVHTraverser::from_bvh_and_ray(&scene, &mut rays[..]) {
|
||||||
for r in rs.iter_mut() {
|
for r in rs.iter_mut() {
|
||||||
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, *tri) {
|
for tri in tris.iter() {
|
||||||
if t < r.max_t {
|
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, *tri) {
|
||||||
isects[r.id as usize] = (true, tri_u, tri_v);
|
if t < r.max_t {
|
||||||
r.max_t = t;
|
isects[r.id as usize] = (true, tri_u, tri_v);
|
||||||
|
r.max_t = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user