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]
|
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| {
|
let part = partition(&mut rays[..ray_i_stack[stack_ptr]], |r| {
|
||||||
if (!r.is_done()) && (first_loop || r.trav_stack.pop()) {
|
if (!r.is_done()) && (first_loop || r.trav_stack.pop()) {
|
||||||
let hits = lerp_slice(bounds, r.time)
|
let hits = lerp_slice(bounds, r.time)
|
||||||
.intersect_accel_ray(r)
|
.intersect_accel_ray(r)
|
||||||
.to_bitmask();
|
.to_bitmask();
|
||||||
all_hits |= hits;
|
|
||||||
|
|
||||||
|
if hits != 0 {
|
||||||
// Push hit bits onto ray's traversal stack
|
// Push hit bits onto ray's traversal stack
|
||||||
let mut shuffled_hits = 0;
|
let mut shuffled_hits = 0;
|
||||||
for i in 0..3 {
|
for i in 0..children.len() {
|
||||||
let ii = (node_order_code >> (i * 2)) & 3;
|
let ii = (node_order_code >> (i * 2)) & 3;
|
||||||
shuffled_hits |= ((hits >> ii) & 1) << i;
|
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
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
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;
|
// Update stack based on ray testing results
|
||||||
ray_i_stack[stack_ptr + 1] = part;
|
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;
|
stack_ptr += children.len() - 1;
|
||||||
} else {
|
} else {
|
||||||
stack_ptr -= 1;
|
stack_ptr -= 1;
|
||||||
|
@ -298,7 +292,11 @@ impl<'a> BVH4<'a> {
|
||||||
};
|
};
|
||||||
calc_traversal_code(split_axis,
|
calc_traversal_code(split_axis,
|
||||||
split_axis_l.unwrap_or(split_axis_r.unwrap_or(0)),
|
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)
|
topology_code)
|
||||||
};
|
};
|
||||||
*fill_node = BVH4Node::Internal {
|
*fill_node = BVH4Node::Internal {
|
||||||
|
|
|
@ -24,20 +24,24 @@ impl BitStack128 {
|
||||||
self.data.0 |= value as u64;
|
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
|
/// bits are passed as an integer, with the bit that
|
||||||
/// will be on top in the least significant digit, and
|
/// will be on top in the least significant digit, and
|
||||||
/// the rest following in order from there.
|
/// the rest following in order from there.
|
||||||
///
|
///
|
||||||
/// Note that unless you are running a debug build, no
|
/// 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 of the passed value are used. So if other
|
||||||
/// bits are non-zero this will produce incorrect results.
|
/// bits are non-zero this will produce incorrect results.
|
||||||
pub fn push_3(&mut self, value: u8) {
|
pub fn push_n(&mut self, value: u8, count: u8) {
|
||||||
debug_assert!((self.data.1 >> (size_of::<u64>() - 3)) == 0); // Verify no stack overflow
|
// Verify no bitstack overflow
|
||||||
debug_assert!(value & (!((1 << 3) - 1)) == 0); // Verify no bits outside of the 3-bit range
|
debug_assert!((self.data.1 >> (size_of::<u64>() - count as usize)) == 0);
|
||||||
self.data.1 = (self.data.1 << 3) | (self.data.0 >> (size_of::<u64>() - 3));
|
// Verify no bits outside of the n-bit range
|
||||||
self.data.0 <<= 3;
|
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;
|
self.data.0 |= value as u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,16 +65,6 @@ impl BitStack128 {
|
||||||
return b;
|
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.
|
/// Read the top bit of the stack without popping it.
|
||||||
pub fn peek(&self) -> bool {
|
pub fn peek(&self) -> bool {
|
||||||
(self.data.0 & 1) != 0
|
(self.data.0 & 1) != 0
|
||||||
|
|
|
@ -520,7 +520,7 @@ impl Bool4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_bitmask(&self) -> u8 {
|
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)
|
((self.get_3() as u8) << 3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||||
use mem_arena::MemArena;
|
use mem_arena::MemArena;
|
||||||
|
|
||||||
use accel::{LightAccel, LightTree};
|
use accel::{LightAccel, LightTree};
|
||||||
use accel::BVH;
|
use accel::BVH4;
|
||||||
use bbox::{BBox, transform_bbox_slice_from};
|
use bbox::{BBox, transform_bbox_slice_from};
|
||||||
use boundable::Boundable;
|
use boundable::Boundable;
|
||||||
use color::SpectralSample;
|
use color::SpectralSample;
|
||||||
|
@ -28,7 +28,7 @@ pub struct Assembly<'a> {
|
||||||
pub assemblies: &'a [Assembly<'a>],
|
pub assemblies: &'a [Assembly<'a>],
|
||||||
|
|
||||||
// Object accel
|
// Object accel
|
||||||
pub object_accel: BVH<'a>,
|
pub object_accel: BVH4<'a>,
|
||||||
|
|
||||||
// Light accel
|
// Light accel
|
||||||
pub light_accel: LightTree<'a>,
|
pub light_accel: LightTree<'a>,
|
||||||
|
@ -231,7 +231,7 @@ impl<'a> AssemblyBuilder<'a> {
|
||||||
let (bis, bbs) = self.instance_bounds();
|
let (bis, bbs) = self.instance_bounds();
|
||||||
|
|
||||||
// Build object accel
|
// Build object accel
|
||||||
let object_accel = BVH::from_objects(self.arena,
|
let object_accel = BVH4::from_objects(self.arena,
|
||||||
&mut self.instances[..],
|
&mut self.instances[..],
|
||||||
1,
|
1,
|
||||||
|inst| &bbs[bis[inst.id]..bis[inst.id + 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.
|
/// 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>) {
|
fn instance_bounds(&self) -> (Vec<usize>, Vec<BBox>) {
|
||||||
let mut indices = vec![0];
|
let mut indices = vec![0];
|
||||||
let mut bounds = Vec::new();
|
let mut bounds = Vec::new();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use mem_arena::MemArena;
|
use mem_arena::MemArena;
|
||||||
|
|
||||||
use accel::BVH;
|
use accel::BVH4;
|
||||||
use bbox::BBox;
|
use bbox::BBox;
|
||||||
use boundable::Boundable;
|
use boundable::Boundable;
|
||||||
use color::XYZ;
|
use color::XYZ;
|
||||||
|
@ -20,7 +20,7 @@ pub struct TriangleMesh<'a> {
|
||||||
time_samples: usize,
|
time_samples: usize,
|
||||||
geo: &'a [(Point, Point, Point)],
|
geo: &'a [(Point, Point, Point)],
|
||||||
indices: &'a [usize],
|
indices: &'a [usize],
|
||||||
accel: BVH<'a>,
|
accel: BVH4<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TriangleMesh<'a> {
|
impl<'a> TriangleMesh<'a> {
|
||||||
|
@ -44,7 +44,7 @@ impl<'a> TriangleMesh<'a> {
|
||||||
bounds
|
bounds
|
||||||
};
|
};
|
||||||
|
|
||||||
let accel = BVH::from_objects(arena,
|
let accel = BVH4::from_objects(arena,
|
||||||
&mut indices[..],
|
&mut indices[..],
|
||||||
3,
|
3,
|
||||||
|tri_i| &bounds[*tri_i..(*tri_i + time_samples)]);
|
|tri_i| &bounds[*tri_i..(*tri_i + time_samples)]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user