rtiow: shrink BVHNode to 32 bytes.
This commit is contained in:
parent
a0b79ee2fa
commit
3c28466d68
@ -16,9 +16,10 @@ use crate::{
|
|||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct BVHNode {
|
struct BVHNode {
|
||||||
aabb: AABB,
|
aabb: AABB,
|
||||||
left_child: usize,
|
// When prim_count==0, left_first holds the left child's index in bvh_nodes. When >0 left_first
|
||||||
first_prim: usize,
|
// holds the index for the first triangle in triangles.
|
||||||
prim_count: usize,
|
left_first: u32,
|
||||||
|
prim_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BVHNode {
|
impl BVHNode {
|
||||||
@ -79,11 +80,11 @@ where
|
|||||||
}
|
}
|
||||||
let n = &self.bvh_nodes[i];
|
let n = &self.bvh_nodes[i];
|
||||||
if n.is_leaf() {
|
if n.is_leaf() {
|
||||||
for t_idx in n.first_prim..(n.first_prim + n.prim_count) {
|
for t_idx in n.left_first..(n.left_first + n.prim_count) {
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "\t")?;
|
write!(f, "\t")?;
|
||||||
}
|
}
|
||||||
write!(f, "{:?} ", self.triangles[t_idx])?;
|
write!(f, "{:?} ", self.triangles[t_idx as usize])?;
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
}
|
}
|
||||||
@ -100,6 +101,7 @@ where
|
|||||||
M: Material,
|
M: Material,
|
||||||
{
|
{
|
||||||
pub fn new(stl: &STL, material: M) -> BVHTriangles<M> {
|
pub fn new(stl: &STL, material: M) -> BVHTriangles<M> {
|
||||||
|
assert_eq!(std::mem::size_of::<BVHNode>(), 32);
|
||||||
let div3 = 1. / 3.;
|
let div3 = 1. / 3.;
|
||||||
let triangles: Vec<_> = stl
|
let triangles: Vec<_> = stl
|
||||||
.triangles
|
.triangles
|
||||||
@ -131,9 +133,8 @@ where
|
|||||||
// assign all triangles to root node
|
// assign all triangles to root node
|
||||||
let root = BVHNode {
|
let root = BVHNode {
|
||||||
aabb: AABB::default(),
|
aabb: AABB::default(),
|
||||||
left_child: 0,
|
left_first: 0,
|
||||||
first_prim: 0,
|
prim_count: self.triangles.len() as u32,
|
||||||
prim_count: self.triangles.len(),
|
|
||||||
};
|
};
|
||||||
self.bvh_nodes.push(root);
|
self.bvh_nodes.push(root);
|
||||||
self.update_node_bounds(ROOT_NODE_IDX);
|
self.update_node_bounds(ROOT_NODE_IDX);
|
||||||
@ -144,8 +145,8 @@ where
|
|||||||
let node = &mut self.bvh_nodes[node_idx];
|
let node = &mut self.bvh_nodes[node_idx];
|
||||||
let mut aabb_min: Vec3 = f32::MAX.into();
|
let mut aabb_min: Vec3 = f32::MAX.into();
|
||||||
let mut aabb_max: Vec3 = f32::MIN.into();
|
let mut aabb_max: Vec3 = f32::MIN.into();
|
||||||
for i in node.first_prim..(node.first_prim + node.prim_count) {
|
for i in node.left_first..(node.left_first + node.prim_count) {
|
||||||
let leaf_tri = &self.triangles[i];
|
let leaf_tri = &self.triangles[i as usize];
|
||||||
aabb_min = vec3::min(aabb_min, leaf_tri.verts[0]);
|
aabb_min = vec3::min(aabb_min, leaf_tri.verts[0]);
|
||||||
aabb_min = vec3::min(aabb_min, leaf_tri.verts[1]);
|
aabb_min = vec3::min(aabb_min, leaf_tri.verts[1]);
|
||||||
aabb_min = vec3::min(aabb_min, leaf_tri.verts[2]);
|
aabb_min = vec3::min(aabb_min, leaf_tri.verts[2]);
|
||||||
@ -160,7 +161,7 @@ where
|
|||||||
if self.bvh_nodes[idx].prim_count <= 2 {
|
if self.bvh_nodes[idx].prim_count <= 2 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (first_prim, prim_count, left_count, i) = {
|
let (left_first, prim_count, left_count, i) = {
|
||||||
let node = &self.bvh_nodes[idx];
|
let node = &self.bvh_nodes[idx];
|
||||||
|
|
||||||
// Compute split plane and position.
|
// Compute split plane and position.
|
||||||
@ -169,7 +170,7 @@ where
|
|||||||
let split_pos = node.aabb.min()[axis] + extent[axis] * 0.5;
|
let split_pos = node.aabb.min()[axis] + extent[axis] * 0.5;
|
||||||
|
|
||||||
// Split the group in two halves.
|
// Split the group in two halves.
|
||||||
let mut i = node.first_prim as isize;
|
let mut i = node.left_first as isize;
|
||||||
let mut j = i + node.prim_count as isize - 1;
|
let mut j = i + node.prim_count as isize - 1;
|
||||||
while i <= j {
|
while i <= j {
|
||||||
if self.triangles[i as usize].centroid[axis] < split_pos {
|
if self.triangles[i as usize].centroid[axis] < split_pos {
|
||||||
@ -181,43 +182,41 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create child nodes for each half.
|
// Create child nodes for each half.
|
||||||
let left_count = i as usize - node.first_prim;
|
let left_count = i as u32 - node.left_first;
|
||||||
if left_count == 0 || left_count == node.prim_count {
|
if left_count == 0 || left_count == node.prim_count {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(node.first_prim, node.prim_count, left_count, i)
|
(node.left_first, node.prim_count, left_count, i)
|
||||||
};
|
};
|
||||||
|
|
||||||
// create child nodes
|
// create child nodes
|
||||||
let left_child_idx = self.bvh_nodes.len();
|
let left_child_idx = self.bvh_nodes.len() as u32;
|
||||||
let right_child_idx = left_child_idx + 1;
|
let right_child_idx = left_child_idx + 1 as u32;
|
||||||
let left = BVHNode {
|
let left = BVHNode {
|
||||||
aabb: AABB::default(),
|
aabb: AABB::default(),
|
||||||
left_child: 0,
|
left_first,
|
||||||
first_prim: first_prim,
|
prim_count: left_count as u32,
|
||||||
prim_count: left_count,
|
|
||||||
};
|
};
|
||||||
let right = BVHNode {
|
let right = BVHNode {
|
||||||
aabb: AABB::default(),
|
aabb: AABB::default(),
|
||||||
left_child: 0,
|
left_first: i as u32,
|
||||||
first_prim: i as usize,
|
prim_count: (prim_count - left_count) as u32,
|
||||||
prim_count: prim_count - left_count,
|
|
||||||
};
|
};
|
||||||
self.bvh_nodes.push(left);
|
self.bvh_nodes.push(left);
|
||||||
self.bvh_nodes.push(right);
|
self.bvh_nodes.push(right);
|
||||||
let node = &mut self.bvh_nodes[idx];
|
let node = &mut self.bvh_nodes[idx];
|
||||||
node.left_child = left_child_idx;
|
node.left_first = left_child_idx;
|
||||||
node.prim_count = 0;
|
node.prim_count = 0;
|
||||||
|
|
||||||
// Recurse
|
// Recurse
|
||||||
self.update_node_bounds(left_child_idx);
|
self.update_node_bounds(left_child_idx as usize);
|
||||||
self.update_node_bounds(right_child_idx);
|
self.update_node_bounds(right_child_idx as usize);
|
||||||
self.subdivide(left_child_idx);
|
self.subdivide(left_child_idx as usize);
|
||||||
self.subdivide(right_child_idx);
|
self.subdivide(right_child_idx as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersect_bvh(&self, r: Ray, node_idx: usize, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
fn intersect_bvh(&self, r: Ray, node_idx: u32, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||||
let node = &self.bvh_nodes[node_idx];
|
let node = &self.bvh_nodes[node_idx as usize];
|
||||||
if !node.aabb.hit(r, t_min, t_max) {
|
if !node.aabb.hit(r, t_min, t_max) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -253,8 +252,8 @@ where
|
|||||||
.filter_map(|hr| hr)
|
.filter_map(|hr| hr)
|
||||||
.min_by(|a, b| a.t.partial_cmp(&b.t).unwrap());
|
.min_by(|a, b| a.t.partial_cmp(&b.t).unwrap());
|
||||||
} else {
|
} else {
|
||||||
let r1 = self.intersect_bvh(r, node.left_child, t_min, t_max);
|
let r1 = self.intersect_bvh(r, node.left_first, t_min, t_max);
|
||||||
let r2 = self.intersect_bvh(r, node.left_child + 1, t_min, t_max);
|
let r2 = self.intersect_bvh(r, node.left_first + 1, t_min, t_max);
|
||||||
// Merge results, if both hit, take the one closest to the ray origin (smallest t
|
// Merge results, if both hit, take the one closest to the ray origin (smallest t
|
||||||
// value).
|
// value).
|
||||||
match (&r1, &r2) {
|
match (&r1, &r2) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user