From 450342c3d4fe97ba97528c9bccfa3f4fac4a8dab Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sun, 12 Feb 2023 13:14:02 -0800 Subject: [PATCH] rtiow: BVHTriangles refactor part of subdivide into find_best_split_plane. --- rtiow/renderer/src/bvh_triangles.rs | 61 +++++++++++++++++------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/rtiow/renderer/src/bvh_triangles.rs b/rtiow/renderer/src/bvh_triangles.rs index 1a9441e..91b4f71 100644 --- a/rtiow/renderer/src/bvh_triangles.rs +++ b/rtiow/renderer/src/bvh_triangles.rs @@ -97,6 +97,12 @@ where } } +struct SplitCost { + pos: f32, + axis: usize, + cost: f32, +} + const ROOT_NODE_IDX: usize = 0; impl BVHTriangles where @@ -206,6 +212,30 @@ where } node.aabb = AABB::new(aabb_min, aabb_max); } + + fn find_best_split_plane(&self, node: &BVHNode) -> SplitCost { + let mut best_axis = usize::MAX; + let mut best_pos = 0.; + let mut best_cost = f32::MAX; + + for axis in 0..3 { + for i in 0..node.tri_count { + let triangle = &self.triangles[self.triangle_index[(node.left_first + i) as usize]]; + let candidate_pos = triangle.centroid[axis]; + let cost = self.evaluate_sah(node, axis, candidate_pos); + if cost <= best_cost { + best_pos = candidate_pos; + best_axis = axis; + best_cost = cost; + } + } + } + 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(); @@ -213,37 +243,18 @@ where let (left_first, tri_count, left_count, i) = { let node = &self.bvh_nodes[idx]; - - let mut best_axis = usize::MAX; - let mut best_pos = 0.; - let mut best_cost = f32::MAX; - - for axis in 0..3 { - for i in 0..node.tri_count { - let triangle = - &self.triangles[self.triangle_index[(node.left_first + i) as usize]]; - let candidate_pos = triangle.centroid[axis]; - let cost = self.evaluate_sah(node, axis, candidate_pos); - if cost <= best_cost { - best_pos = candidate_pos; - best_axis = axis; - best_cost = cost; - } - } - } + let split = self.find_best_split_plane(&node); // Stop subdividing if it isn't getting any better. - if best_cost >= parent_cost { + if split.cost >= parent_cost { return; } - let axis = best_axis; - let split_pos = best_pos; - // Split the group in two halves. let mut i = node.left_first as isize; let mut j = i + node.tri_count as isize - 1; 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; } else { self.triangles.swap( @@ -317,7 +328,7 @@ where } fn intersect_bvh(&self, r: Ray, t_min: f32, t_max: f32) -> Option { - 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 nearest = None; loop { @@ -458,7 +469,7 @@ where } fn bounding_box(&self, _t_min: f32, _t_max: f32) -> Option { - Some(self.bvh_nodes[0].aabb) + Some(self.bvh_nodes[ROOT_NODE_IDX].aabb) } }