From 44e3ee8b4b81d0b3ab0b52dde5983577e511c0b6 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Fri, 14 Apr 2017 20:25:12 -0700 Subject: [PATCH] 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. --- src/accel/bvh4.rs | 55 ++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/accel/bvh4.rs b/src/accel/bvh4.rs index 9bee85a..5ffa003 100644 --- a/src/accel/bvh4.rs +++ b/src/accel/bvh4.rs @@ -241,34 +241,49 @@ impl<'a> BVH4<'a> { let bounds = { let bounds_len = children.iter() .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 { 0 }) .max() .unwrap(); + debug_assert!(bounds_len >= 1); let mut bounds = unsafe { arena.alloc_array_uninitialized_with_alignment(bounds_len, 32) }; - for (i, b) in bounds.iter_mut().enumerate() { - let time = i as f32 / (bounds_len - 1) as f32; + if bounds_len < 2 { + 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 (x, y) = c.bounds_range(); - lerp_slice(&base.bounds[x..y], time) - }); - let b2 = children[1].map_or(BBox::new(), |c| { - let (x, y) = c.bounds_range(); - lerp_slice(&base.bounds[x..y], time) - }); - let b3 = children[2].map_or(BBox::new(), |c| { - let (x, y) = c.bounds_range(); - lerp_slice(&base.bounds[x..y], time) - }); - let b4 = children[3].map_or(BBox::new(), |c| { - let (x, y) = c.bounds_range(); - lerp_slice(&base.bounds[x..y], time) - }); - *b = BBox4::from_bboxes(b1, b2, b3, b4); + let b1 = children[0].map_or(BBox::new(), |c| { + let (x, y) = c.bounds_range(); + lerp_slice(&base.bounds[x..y], time) + }); + let b2 = children[1].map_or(BBox::new(), |c| { + let (x, y) = c.bounds_range(); + lerp_slice(&base.bounds[x..y], time) + }); + let b3 = children[2].map_or(BBox::new(), |c| { + let (x, y) = c.bounds_range(); + lerp_slice(&base.bounds[x..y], time) + }); + let b4 = children[3].map_or(BBox::new(), |c| { + let (x, y) = c.bounds_range(); + lerp_slice(&base.bounds[x..y], time) + }); + *b = BBox4::from_bboxes(b1, b2, b3, b4); + } } bounds };