Fixed nasty bug in BVH4 building.

In practice it worked fine, but only by accident.  NaN's were
being passed to the lerp_slice function, which led to the
correct result in this case but is icky and dependant
on how lerp_slice is implemented.
This commit is contained in:
Nathan Vegdahl 2017-04-14 20:25:12 -07:00
parent f8d47dc24a
commit 44e3ee8b4b

View File

@ -241,34 +241,49 @@ impl<'a> BVH4<'a> {
let bounds = { let bounds = {
let bounds_len = children.iter() let bounds_len = children.iter()
.map(|c| if let &Some(n) = c { .map(|c| if let &Some(n) = c {
n.bounds_range().1 - n.bounds_range().0 let len = n.bounds_range().1 - n.bounds_range().0;
debug_assert!(len >= 1);
len
} else { } else {
0 0
}) })
.max() .max()
.unwrap(); .unwrap();
debug_assert!(bounds_len >= 1);
let mut bounds = let mut bounds =
unsafe { arena.alloc_array_uninitialized_with_alignment(bounds_len, 32) }; unsafe { arena.alloc_array_uninitialized_with_alignment(bounds_len, 32) };
for (i, b) in bounds.iter_mut().enumerate() { if bounds_len < 2 {
let time = i as f32 / (bounds_len - 1) as f32; let b1 = children[0]
.map_or(BBox::new(), |c| base.bounds[c.bounds_range().0]);
let b2 = children[1]
.map_or(BBox::new(), |c| base.bounds[c.bounds_range().0]);
let b3 = children[2]
.map_or(BBox::new(), |c| base.bounds[c.bounds_range().0]);
let b4 = children[3]
.map_or(BBox::new(), |c| base.bounds[c.bounds_range().0]);
bounds[0] = BBox4::from_bboxes(b1, b2, b3, b4);
} else {
for (i, b) in bounds.iter_mut().enumerate() {
let time = i as f32 / (bounds_len - 1) as f32;
let b1 = children[0].map_or(BBox::new(), |c| { let b1 = children[0].map_or(BBox::new(), |c| {
let (x, y) = c.bounds_range(); let (x, y) = c.bounds_range();
lerp_slice(&base.bounds[x..y], time) lerp_slice(&base.bounds[x..y], time)
}); });
let b2 = children[1].map_or(BBox::new(), |c| { let b2 = children[1].map_or(BBox::new(), |c| {
let (x, y) = c.bounds_range(); let (x, y) = c.bounds_range();
lerp_slice(&base.bounds[x..y], time) lerp_slice(&base.bounds[x..y], time)
}); });
let b3 = children[2].map_or(BBox::new(), |c| { let b3 = children[2].map_or(BBox::new(), |c| {
let (x, y) = c.bounds_range(); let (x, y) = c.bounds_range();
lerp_slice(&base.bounds[x..y], time) lerp_slice(&base.bounds[x..y], time)
}); });
let b4 = children[3].map_or(BBox::new(), |c| { let b4 = children[3].map_or(BBox::new(), |c| {
let (x, y) = c.bounds_range(); let (x, y) = c.bounds_range();
lerp_slice(&base.bounds[x..y], time) lerp_slice(&base.bounds[x..y], time)
}); });
*b = BBox4::from_bboxes(b1, b2, b3, b4); *b = BBox4::from_bboxes(b1, b2, b3, b4);
}
} }
bounds bounds
}; };