BVH now no longer directly references the objects it indexes.

Everything is done with indices anyway, so there was no reason
for it to store an internal reference to the object data.  This
gets rid of the type parameter and lifetime parameter on the BVH
struct itself, which will also make it easier to bundle it with
the data it indexes, which will be important later on.
This commit is contained in:
Nathan Vegdahl 2016-01-02 22:55:20 -08:00
parent 470618fa6a
commit a14a93f5a1
3 changed files with 18 additions and 21 deletions

View File

@ -5,9 +5,8 @@ use ray::Ray;
use algorithm::partition; use algorithm::partition;
#[derive(Debug)] #[derive(Debug)]
pub struct BVH<'a, T: 'a> { pub struct BVH {
nodes: Vec<BVHNode>, nodes: Vec<BVHNode>,
objects: &'a [T],
depth: usize, depth: usize,
} }
@ -25,18 +24,16 @@ enum BVHNode {
}, },
} }
impl<'a, T> BVH<'a, T> { impl BVH {
pub fn from_objects<F>(objects: &'a mut [T], objects_per_leaf: usize, bounder: F) -> BVH<'a, T> pub fn from_objects<T, F>(objects: &mut [T], objects_per_leaf: usize, bounder: F) -> BVH
where F: Fn(&T) -> BBox where F: Fn(&T) -> BBox
{ {
let mut bvh = BVH { let mut bvh = BVH {
nodes: Vec::new(), nodes: Vec::new(),
objects: &[],
depth: 0, depth: 0,
}; };
bvh.recursive_build(0, 0, objects_per_leaf, objects, &bounder); bvh.recursive_build(0, 0, objects_per_leaf, objects, &bounder);
bvh.objects = objects;
println!("BVH Depth: {}", bvh.depth); println!("BVH Depth: {}", bvh.depth);
@ -44,13 +41,13 @@ impl<'a, T> BVH<'a, T> {
} }
fn recursive_build<F>(&mut self, fn recursive_build<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
where F: Fn(&T) -> BBox where F: Fn(&T) -> BBox
{ {
let me = self.nodes.len(); let me = self.nodes.len();
@ -141,7 +138,7 @@ impl<'a, T> BVH<'a, T> {
} }
pub fn traverse<F>(&self, rays: &mut [Ray], mut obj_ray_test: F) pub fn traverse<T, F>(&self, rays: &mut [Ray], objects: &[T], mut obj_ray_test: F)
where F: FnMut(&T, &mut [Ray]) where F: FnMut(&T, &mut [Ray])
{ {
let mut i_stack = [0; 65]; let mut i_stack = [0; 65];
@ -171,7 +168,7 @@ impl<'a, T> BVH<'a, T> {
let part = partition(&mut rays[..ray_i_stack[stack_ptr]], let part = partition(&mut rays[..ray_i_stack[stack_ptr]],
|r| bounds.intersect_ray(r)); |r| bounds.intersect_ray(r));
if part > 0 { if part > 0 {
for obj in &self.objects[object_range.0..object_range.1] { for obj in &objects[object_range.0..object_range.1] {
obj_ray_test(obj, &mut rays[..part]); obj_ray_test(obj, &mut rays[..part]);
} }
} }

View File

@ -98,7 +98,7 @@ fn main() {
} }
triangles triangles
}; };
let scene = bvh::BVH::from_objects(&mut triangles[..], 3, |tri| { let accel = 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 {
@ -118,7 +118,7 @@ fn main() {
resolution: (512, 512), resolution: (512, 512),
spp: samples_per_pixel as usize, spp: samples_per_pixel as usize,
camera: cam, camera: cam,
scene: scene, scene: (triangles, accel),
}; };
r.render(); r.render();

View File

@ -7,15 +7,15 @@ use image::Image;
use bvh::BVH; use bvh::BVH;
use triangle; use triangle;
pub struct Renderer<'a> { pub struct Renderer {
pub output_file: String, pub output_file: String,
pub resolution: (usize, usize), pub resolution: (usize, usize),
pub spp: usize, pub spp: usize,
pub camera: Camera, pub camera: Camera,
pub scene: BVH<'a, (Point, Point, Point)>, pub scene: (Vec<(Point, Point, Point)>, BVH),
} }
impl<'a> Renderer<'a> { impl Renderer {
pub fn render(&self) { pub fn render(&self) {
let mut rays = Vec::new(); let mut rays = Vec::new();
let mut isects = Vec::new(); let mut isects = Vec::new();
@ -48,7 +48,7 @@ impl<'a> Renderer<'a> {
} }
// Test rays against scene // Test rays against scene
self.scene.traverse(&mut rays, |tri, rs| { self.scene.1.traverse(&mut rays, &self.scene.0, |tri, rs| {
for r in rs { for r in rs {
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, *tri) { if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, *tri) {
if t < r.max_t { if t < r.max_t {