Implemented basic deformation motion blur for triangles.

Not 100% happy with the interface of the BVH building yet, and
there are still some missing features as well.  But it's a start!
This commit is contained in:
Nathan Vegdahl 2016-01-05 07:44:37 -08:00
parent c1b063411f
commit 655c16542d
3 changed files with 47 additions and 15 deletions

View File

@ -23,7 +23,7 @@ pub fn lerp_slice<T: Lerp + Copy>(s: &[T], alpha: f32) -> T {
debug_assert!(alpha >= 0.0);
debug_assert!(alpha <= 1.0);
if alpha == 1.0 || s.len() == 1 {
if s.len() == 1 || alpha == 1.0 {
return *s.last().unwrap();
} else {
let tmp = alpha * ((s.len() - 1) as f32);
@ -35,6 +35,26 @@ pub fn lerp_slice<T: Lerp + Copy>(s: &[T], alpha: f32) -> T {
}
}
pub fn lerp_slice_with<T, F>(s: &[T], alpha: f32, f: F) -> T
where T: Copy,
F: Fn(T, T, f32) -> T
{
debug_assert!(s.len() > 0);
debug_assert!(alpha >= 0.0);
debug_assert!(alpha <= 1.0);
if s.len() == 1 || alpha == 1.0 {
return *s.last().unwrap();
} else {
let tmp = alpha * ((s.len() - 1) as f32);
let i1 = tmp as usize;
let i2 = i1 + 1;
let alpha2 = tmp - (i1 as f32);
return f(s[i1], s[i2], alpha2);
}
}
impl Lerp for f32 {
fn lerp(self, other: f32, alpha: f32) -> f32 {

View File

@ -74,7 +74,7 @@ fn main() {
println!("Ray size: {} bytes", mem::size_of::<Ray>());
// Generate a scene of triangles
let mesh = TriangleMesh::from_triangles(1, {
let mesh = TriangleMesh::from_triangles(2, {
let mut triangles = Vec::new();
let xres = 32;
let yres = 32;
@ -92,9 +92,9 @@ fn main() {
triangles.push((Point::new(cx, cy, cz + 1.0),
Point::new(cx + xinc, cy, cz + 1.1),
Point::new(cx, cy + yinc, cz + 1.2)));
triangles.push((Point::new(cx + xinc, cy + yinc, cz + 1.0),
Point::new(cx, cy + yinc, cz + 1.1),
Point::new(cx + xinc, cy, cz + 1.2)));
triangles.push((Point::new(cx + 25.0, cy, cz + 1.0),
Point::new(cx + 25.0 + xinc, cy, cz + 1.1),
Point::new(cx + 25.0, cy + yinc, cz + 1.2)));
}
}
triangles

View File

@ -1,5 +1,6 @@
#![allow(dead_code)]
use lerp::{lerp, lerp_slice_with};
use math::{Point, Normal, Matrix4x4};
use ray::Ray;
use triangle;
@ -11,27 +12,31 @@ use super::{Surface, SurfaceIntersection};
pub struct TriangleMesh {
time_samples: usize,
geo: Vec<(Point, Point, Point)>,
indices: Vec<usize>,
accel: BVH,
}
impl TriangleMesh {
pub fn from_triangles(time_samples: usize,
mut triangles: Vec<(Point, Point, Point)>)
triangles: Vec<(Point, Point, Point)>)
-> TriangleMesh {
assert!(triangles.len() % time_samples == 0);
// let mut indices: Vec<usize> = (0 .. (triangles.len() / time_samples)).collect();
let mut indices: Vec<usize> = (0..(triangles.len() / time_samples))
.map(|n| n * time_samples)
.collect();
let accel = BVH::from_objects(&mut triangles[..], 3, |tri, bounds| {
// for tri in &triangles[i..(i+time_samples)] {
let minimum = tri.0.min(tri.1.min(tri.2));
let maximum = tri.0.max(tri.1.max(tri.2));
bounds.push(BBox::from_points(minimum, maximum));
// }
let accel = BVH::from_objects(&mut indices[..], 3, |tri_i, bounds| {
for tri in &triangles[*tri_i..(*tri_i + time_samples)] {
let minimum = tri.0.min(tri.1.min(tri.2));
let maximum = tri.0.max(tri.1.max(tri.2));
bounds.push(BBox::from_points(minimum, maximum));
}
});
TriangleMesh {
time_samples: time_samples,
geo: triangles,
indices: indices,
accel: accel,
}
}
@ -40,9 +45,16 @@ impl TriangleMesh {
impl Surface for TriangleMesh {
fn intersect_rays(&self, rays: &mut [Ray], isects: &mut [SurfaceIntersection]) {
self.accel.traverse(&mut rays[..], &self.geo, |tri, rs| {
self.accel.traverse(&mut rays[..], &self.indices, |tri_i, rs| {
for r in rs {
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, *tri) {
let tri = lerp_slice_with(&self.geo[*tri_i..(*tri_i + self.time_samples)],
r.time,
|a, b, t| {
(lerp(a.0, b.0, t),
lerp(a.1, b.1, t),
lerp(a.2, b.2, t))
});
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(r, tri) {
if t < r.max_t {
isects[r.id as usize] = SurfaceIntersection::Hit {
t: t,