rtiow: BVHTriangles refactor part of subdivide into find_best_split_plane.
This commit is contained in:
parent
41f9fa2742
commit
450342c3d4
@ -97,6 +97,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
struct SplitCost {
|
||||
pos: f32,
|
||||
axis: usize,
|
||||
cost: f32,
|
||||
}
|
||||
|
||||
const ROOT_NODE_IDX: usize = 0;
|
||||
impl<M> BVHTriangles<M>
|
||||
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<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 nearest = None;
|
||||
loop {
|
||||
@ -458,7 +469,7 @@ where
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user