rtiow: precache some things in Triangles.

This commit is contained in:
Bill Thiede 2023-01-15 15:29:52 -08:00
parent a0fb4637b5
commit a8756debb8
2 changed files with 31 additions and 23 deletions

View File

@ -16,7 +16,7 @@ use crate::{
};
pub fn new(opt: &Opt) -> Scene {
let lookfrom = Vec3::new(200., 200., 200.);
let lookfrom = Vec3::new(100., 200., 200.);
let lookat = Vec3::new(0., 1., 0.);
let dist_to_focus = 10.0;
let aperture = 0.0;
@ -48,9 +48,10 @@ pub fn new(opt: &Opt) -> Scene {
let light_height = 200.;
let tri_mesh = Triangles::new(
&stl_cube,
Lambertian::new(ConstantTexture::new(Vec3::new(1., 0., 0.))),
Lambertian::new(ConstantTexture::new(Vec3::new(1., 0.1, 0.1))),
1.,
);
dbg!(&tri_mesh);
dbg!(tri_mesh.triangles.len(), tri_mesh.bbox);
let objects: Vec<Box<dyn Hit>> = vec![
// Light from above
Box::new(XZRect::new(

View File

@ -10,9 +10,14 @@ use crate::{
#[derive(Debug)]
pub struct Triangle {
pub normal: Vec3,
normal: Vec3,
verts: [Vec3; 3],
// Precomputed data
// TODO(wathiede): precompute `d` on load.
pub verts: [Vec3; 3],
d: f32,
edge0: Vec3,
edge1: Vec3,
edge2: Vec3,
}
#[derive(Debug)]
@ -20,8 +25,8 @@ pub struct Triangles<M>
where
M: Material,
{
triangles: Vec<Triangle>,
bbox: AABB,
pub triangles: Vec<Triangle>,
pub bbox: AABB,
material: M,
}
@ -29,13 +34,22 @@ impl<M> Triangles<M>
where
M: Material,
{
pub fn new(stl: &STL, material: M) -> Triangles<M> {
pub fn new(stl: &STL, material: M, scale_factor: f32) -> Triangles<M> {
let triangles: Vec<_> = stl
.triangles
.iter()
.map(|t| Triangle {
normal: t.normal,
verts: t.verts,
.map(|t| {
let v0 = t.verts[0] * scale_factor;
let v1 = t.verts[1] * scale_factor;
let v2 = t.verts[2] * scale_factor;
Triangle {
normal: t.normal,
verts: [v0, v1, v2],
d: -dot(t.normal, t.verts[0]),
edge0: v1 - v0,
edge1: v2 - v1,
edge2: v0 - v2,
}
})
.collect();
let (min, max) = triangles.iter().fold(
@ -68,11 +82,8 @@ where
M: Material,
{
// Based on https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/ray-triangle-intersection-geometric-solution.html
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
fn hit(&self, r: Ray, _t_min: f32, _t_max: f32) -> Option<HitRecord> {
for tri in &self.triangles {
let v0 = tri.verts[0];
let v1 = tri.verts[1];
let v2 = tri.verts[2];
let n = tri.normal;
// close enough to parallel, won't hit
@ -83,8 +94,7 @@ where
continue;
}
let d = -dot(n, tri.verts[0]);
let t = -(dot(n, r.origin) + d) / n_dot_dir;
let t = -(dot(n, r.origin) + tri.d) / n_dot_dir;
// check if the triangle is behind the ray
if t < 0. {
continue;
@ -95,23 +105,20 @@ where
let v1 = tri.verts[1];
let v2 = tri.verts[2];
let edge0 = v1 - v0;
let vp0 = p - v0;
let c = cross(edge0, vp0);
let c = cross(tri.edge0, vp0);
if dot(n, c) < 0. {
continue;
}
let edge1 = v2 - v1;
let vp1 = p - v1;
let c = cross(edge1, vp1);
let c = cross(tri.edge1, vp1);
if dot(n, c) < 0. {
continue;
}
let edge2 = v0 - v2;
let vp2 = p - v2;
let c = cross(edge2, vp2);
let c = cross(tri.edge2, vp2);
if dot(n, c) < 0. {
continue;
}