Got BVH4 working. Woo hoo!
This commit is contained in:
parent
53a14996c9
commit
573c5da5ab
|
@ -98,47 +98,41 @@ impl<'a> BVH4<'a> {
|
|||
TRAVERSAL_TABLE[ray_code as usize][traversal_code as usize]
|
||||
};
|
||||
|
||||
let mut all_hits = 0; // Accumulate
|
||||
// Ray testing
|
||||
let part = partition(&mut rays[..ray_i_stack[stack_ptr]], |r| {
|
||||
if (!r.is_done()) && (first_loop || r.trav_stack.pop()) {
|
||||
let hits = lerp_slice(bounds, r.time)
|
||||
.intersect_accel_ray(r)
|
||||
.to_bitmask();
|
||||
all_hits |= hits;
|
||||
|
||||
if hits != 0 {
|
||||
// Push hit bits onto ray's traversal stack
|
||||
let mut shuffled_hits = 0;
|
||||
for i in 0..3 {
|
||||
for i in 0..children.len() {
|
||||
let ii = (node_order_code >> (i * 2)) & 3;
|
||||
shuffled_hits |= ((hits >> ii) & 1) << i;
|
||||
}
|
||||
r.trav_stack.push_3(shuffled_hits);
|
||||
r.trav_stack.push_n(shuffled_hits, children.len() as u8);
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
if part > 0 {
|
||||
node_stack[stack_ptr] = {
|
||||
Some(&children[(node_order_code & 3) as usize])
|
||||
};
|
||||
node_stack[stack_ptr + 1] = {
|
||||
Some(&children[((node_order_code >> 2) & 3) as usize])
|
||||
};
|
||||
node_stack[stack_ptr + 2] = if children.len() > 2 {
|
||||
Some(&children[((node_order_code >> 4) & 3) as usize])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
node_stack[stack_ptr + 3] = if children.len() > 3 {
|
||||
Some(&children[((node_order_code >> 6) & 3) as usize])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
ray_i_stack[stack_ptr] = part;
|
||||
ray_i_stack[stack_ptr + 1] = part;
|
||||
// Update stack based on ray testing results
|
||||
if part > 0 {
|
||||
for i in 0..children.len() {
|
||||
let inv_i = (children.len() - 1) - i;
|
||||
node_stack[stack_ptr + i] =
|
||||
Some(&children[((node_order_code >> (inv_i * 2)) & 3) as
|
||||
usize]);
|
||||
ray_i_stack[stack_ptr + i] = part;
|
||||
}
|
||||
|
||||
stack_ptr += children.len() - 1;
|
||||
} else {
|
||||
stack_ptr -= 1;
|
||||
|
@ -298,7 +292,11 @@ impl<'a> BVH4<'a> {
|
|||
};
|
||||
calc_traversal_code(split_axis,
|
||||
split_axis_l.unwrap_or(split_axis_r.unwrap_or(0)),
|
||||
split_axis_r.unwrap_or(0),
|
||||
if child_count == 4 {
|
||||
split_axis_r.unwrap()
|
||||
} else {
|
||||
0
|
||||
},
|
||||
topology_code)
|
||||
};
|
||||
*fill_node = BVH4Node::Internal {
|
||||
|
|
|
@ -24,20 +24,24 @@ impl BitStack128 {
|
|||
self.data.0 |= value as u64;
|
||||
}
|
||||
|
||||
/// Push 3 bits onto the top of the stack. The input
|
||||
/// Push n bits onto the top of the stack. The input
|
||||
/// bits are passed as an integer, with the bit that
|
||||
/// will be on top in the least significant digit, and
|
||||
/// the rest following in order from there.
|
||||
///
|
||||
/// Note that unless you are running a debug build, no
|
||||
/// effort is made to verify that only the first three
|
||||
/// effort is made to verify that only the first n
|
||||
/// bits of the passed value are used. So if other
|
||||
/// bits are non-zero this will produce incorrect results.
|
||||
pub fn push_3(&mut self, value: u8) {
|
||||
debug_assert!((self.data.1 >> (size_of::<u64>() - 3)) == 0); // Verify no stack overflow
|
||||
debug_assert!(value & (!((1 << 3) - 1)) == 0); // Verify no bits outside of the 3-bit range
|
||||
self.data.1 = (self.data.1 << 3) | (self.data.0 >> (size_of::<u64>() - 3));
|
||||
self.data.0 <<= 3;
|
||||
pub fn push_n(&mut self, value: u8, count: u8) {
|
||||
// Verify no bitstack overflow
|
||||
debug_assert!((self.data.1 >> (size_of::<u64>() - count as usize)) == 0);
|
||||
// Verify no bits outside of the n-bit range
|
||||
debug_assert!(value & (!((1 << count) - 1)) == 0);
|
||||
|
||||
self.data.1 = (self.data.1 << count as usize) |
|
||||
(self.data.0 >> (size_of::<u64>() - count as usize));
|
||||
self.data.0 <<= count as u64;
|
||||
self.data.0 |= value as u64;
|
||||
}
|
||||
|
||||
|
@ -61,16 +65,6 @@ impl BitStack128 {
|
|||
return b;
|
||||
}
|
||||
|
||||
/// Pop the top n bits off the stack, returning only the first
|
||||
/// one.
|
||||
pub fn pop_1_remove_n(&mut self, n: usize) -> bool {
|
||||
debug_assert!(n < size_of::<BitStack128>()); // Can't pop more than we have
|
||||
let b = (self.data.0 & 1) != 0;
|
||||
self.data.0 = (self.data.0 >> n) | (self.data.1 << (size_of::<u64>() - n));
|
||||
self.data.1 >>= n;
|
||||
return b;
|
||||
}
|
||||
|
||||
/// Read the top bit of the stack without popping it.
|
||||
pub fn peek(&self) -> bool {
|
||||
(self.data.0 & 1) != 0
|
||||
|
|
|
@ -520,7 +520,7 @@ impl Bool4 {
|
|||
}
|
||||
|
||||
pub fn to_bitmask(&self) -> u8 {
|
||||
(self.get_0() as u8) & ((self.get_1() as u8) << 1) & ((self.get_2() as u8) << 2) &
|
||||
(self.get_0() as u8) | ((self.get_1() as u8) << 1) | ((self.get_2() as u8) << 2) |
|
||||
((self.get_3() as u8) << 3)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||
use mem_arena::MemArena;
|
||||
|
||||
use accel::{LightAccel, LightTree};
|
||||
use accel::BVH;
|
||||
use accel::BVH4;
|
||||
use bbox::{BBox, transform_bbox_slice_from};
|
||||
use boundable::Boundable;
|
||||
use color::SpectralSample;
|
||||
|
@ -28,7 +28,7 @@ pub struct Assembly<'a> {
|
|||
pub assemblies: &'a [Assembly<'a>],
|
||||
|
||||
// Object accel
|
||||
pub object_accel: BVH<'a>,
|
||||
pub object_accel: BVH4<'a>,
|
||||
|
||||
// Light accel
|
||||
pub light_accel: LightTree<'a>,
|
||||
|
@ -231,7 +231,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
let (bis, bbs) = self.instance_bounds();
|
||||
|
||||
// Build object accel
|
||||
let object_accel = BVH::from_objects(self.arena,
|
||||
let object_accel = BVH4::from_objects(self.arena,
|
||||
&mut self.instances[..],
|
||||
1,
|
||||
|inst| &bbs[bis[inst.id]..bis[inst.id + 1]]);
|
||||
|
@ -288,7 +288,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
|
||||
|
||||
/// Returns a pair of vectors with the bounds of all instances.
|
||||
/// This is used for building the assembly's BVH.
|
||||
/// This is used for building the assembly's BVH4.
|
||||
fn instance_bounds(&self) -> (Vec<usize>, Vec<BBox>) {
|
||||
let mut indices = vec![0];
|
||||
let mut bounds = Vec::new();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use mem_arena::MemArena;
|
||||
|
||||
use accel::BVH;
|
||||
use accel::BVH4;
|
||||
use bbox::BBox;
|
||||
use boundable::Boundable;
|
||||
use color::XYZ;
|
||||
|
@ -20,7 +20,7 @@ pub struct TriangleMesh<'a> {
|
|||
time_samples: usize,
|
||||
geo: &'a [(Point, Point, Point)],
|
||||
indices: &'a [usize],
|
||||
accel: BVH<'a>,
|
||||
accel: BVH4<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TriangleMesh<'a> {
|
||||
|
@ -44,7 +44,7 @@ impl<'a> TriangleMesh<'a> {
|
|||
bounds
|
||||
};
|
||||
|
||||
let accel = BVH::from_objects(arena,
|
||||
let accel = BVH4::from_objects(arena,
|
||||
&mut indices[..],
|
||||
3,
|
||||
|tri_i| &bounds[*tri_i..(*tri_i + time_samples)]);
|
||||
|
|
Loading…
Reference in New Issue
Block a user