rtiow: BVHTriangles refactor part of subdivide into find_best_split_plane.

This commit is contained in:
Bill Thiede 2023-02-12 13:14:02 -08:00
parent 41f9fa2742
commit 450342c3d4

View File

@ -97,6 +97,12 @@ where
} }
} }
struct SplitCost {
pos: f32,
axis: usize,
cost: f32,
}
const ROOT_NODE_IDX: usize = 0; const ROOT_NODE_IDX: usize = 0;
impl<M> BVHTriangles<M> impl<M> BVHTriangles<M>
where where
@ -206,22 +212,15 @@ where
} }
node.aabb = AABB::new(aabb_min, aabb_max); node.aabb = AABB::new(aabb_min, aabb_max);
} }
fn subdivide(&mut self, idx: usize) {
let node = &self.bvh_nodes[idx];
let parent_area = node.aabb.area();
let parent_cost = node.tri_count as f32 * parent_area;
let (left_first, tri_count, left_count, i) = {
let node = &self.bvh_nodes[idx];
fn find_best_split_plane(&self, node: &BVHNode) -> SplitCost {
let mut best_axis = usize::MAX; let mut best_axis = usize::MAX;
let mut best_pos = 0.; let mut best_pos = 0.;
let mut best_cost = f32::MAX; let mut best_cost = f32::MAX;
for axis in 0..3 { for axis in 0..3 {
for i in 0..node.tri_count { for i in 0..node.tri_count {
let triangle = let triangle = &self.triangles[self.triangle_index[(node.left_first + i) as usize]];
&self.triangles[self.triangle_index[(node.left_first + i) as usize]];
let candidate_pos = triangle.centroid[axis]; let candidate_pos = triangle.centroid[axis];
let cost = self.evaluate_sah(node, axis, candidate_pos); let cost = self.evaluate_sah(node, axis, candidate_pos);
if cost <= best_cost { if cost <= best_cost {
@ -231,19 +230,31 @@ where
} }
} }
} }
SplitCost {
pos: best_pos,
cost: best_cost,
axis: best_axis,
}
}
fn subdivide(&mut self, idx: usize) {
let node = &self.bvh_nodes[idx];
let parent_area = node.aabb.area();
let parent_cost = node.tri_count as f32 * parent_area;
let (left_first, tri_count, left_count, i) = {
let node = &self.bvh_nodes[idx];
let split = self.find_best_split_plane(&node);
// Stop subdividing if it isn't getting any better. // Stop subdividing if it isn't getting any better.
if best_cost >= parent_cost { if split.cost >= parent_cost {
return; return;
} }
let axis = best_axis;
let split_pos = best_pos;
// Split the group in two halves. // Split the group in two halves.
let mut i = node.left_first as isize; let mut i = node.left_first as isize;
let mut j = i + node.tri_count as isize - 1; let mut j = i + node.tri_count as isize - 1;
while i <= j { while i <= j {
if self.triangles[self.triangle_index[i as usize]].centroid[axis] < split_pos { if self.triangles[self.triangle_index[i as usize]].centroid[split.axis] < split.pos
{
i += 1; i += 1;
} else { } else {
self.triangles.swap( self.triangles.swap(
@ -317,7 +328,7 @@ where
} }
fn intersect_bvh(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> { fn intersect_bvh(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
let mut node = &self.bvh_nodes[0]; let mut node = &self.bvh_nodes[ROOT_NODE_IDX];
let mut stack = Vec::with_capacity(2); let mut stack = Vec::with_capacity(2);
let mut nearest = None; let mut nearest = None;
loop { loop {
@ -458,7 +469,7 @@ where
} }
fn bounding_box(&self, _t_min: f32, _t_max: f32) -> Option<AABB> { fn bounding_box(&self, _t_min: f32, _t_max: f32) -> Option<AABB> {
Some(self.bvh_nodes[0].aabb) Some(self.bvh_nodes[ROOT_NODE_IDX].aabb)
} }
} }