diff --git a/src/main.rs b/src/main.rs index f13beb1..bef1f0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,6 +54,36 @@ fn ypr_to_mat(ypr: Vec3) -> Mat3 { m_roll * m_pitch * m_yaw } +struct TraceResult { + distance: f32, + normal: Vec3, +} + +fn trace_to_mesh(mesh: &[Face], base: Vec3, ray: Vec3) -> Option { + let mut ret: Option = None; + let mut dist = f32::INFINITY; + for f in mesh { + let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray)); + if fs.into_iter().all(|f| f >= 0.0) { + let m = Mat3 { c0: f.vertices[1] - f.vertices[0], c1: f.vertices[2] - f.vertices[0], c2: -ray }; + if let Some(m) = m.inverse() { + let rel = m * (base - f.vertices[0]); + if rel.z > dist { + continue; + } + dist = rel.z; + ret = Some(TraceResult { + distance: rel.z, + normal: f.normal, + }); + } else { + continue; + } + } + } + ret +} + fn render(mesh: &[Face], camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image { let mut img = Image { w: W, @@ -66,23 +96,9 @@ fn render(mesh: &[Face], camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image { let img_coords = vec2(x as f32, y as f32); let off = (img_coords - img_size * 0.5) / img_size.y; let (base, ray) = camera(off); - let mut dist = f32::INFINITY; - for f in mesh { - let color = clamp(to_ivec3(f.normal * 120.0 + 128.0), ivec3(0, 0, 0), ivec3(255, 255, 255)); - let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray)); - if fs.into_iter().all(|f| f >= 0.0) { - let m = Mat3 { c0: f.vertices[1] - f.vertices[0], c1: f.vertices[2] - f.vertices[0], c2: -ray }; - if let Some(m) = m.inverse() { - let rel = m * (base - f.vertices[0]); - if rel.z > dist { - continue; - } - dist = rel.z; - } else { - continue; - } - img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8)); - } + if let Some(r) = trace_to_mesh(mesh, base, ray) { + let color = clamp(to_ivec3(r.normal * 120.0 + 128.0), ivec3(0, 0, 0), ivec3(255, 255, 255)); + img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8)); } } }