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:
parent
c1b063411f
commit
655c16542d
22
src/lerp.rs
22
src/lerp.rs
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue
Block a user