From 97286085ab6975dac32e91fcafa16f498ae6e698 Mon Sep 17 00:00:00 2001 From: numzero Date: Sat, 14 Sep 2024 15:55:01 +0300 Subject: [PATCH] Allow getting all ray-mesh intersections (useful for translucent objects) --- src/mesh_tracer.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/mesh_tracer.rs b/src/mesh_tracer.rs index bb9bbc4..e6fb308 100644 --- a/src/mesh_tracer.rs +++ b/src/mesh_tracer.rs @@ -8,13 +8,15 @@ pub struct TraceResult { pub normal: Vec3, } -pub fn trace_to_mesh(mesh: &Mesh, base: Vec3, ray: Vec3) -> Option { - let mut ret: Option = None; - let mut dist = f32::INFINITY; - for f in mesh { +pub fn trace_to_mesh_all( + mesh: &Mesh, + base: Vec3, + ray: Vec3, +) -> impl Iterator + '_ { + mesh.iter().filter_map(move |f| { let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray)); if fs.into_iter().any(|f| f < 0.0) { - continue; + return None; } let m = mat3( f.vertices[1] - f.vertices[0], @@ -23,16 +25,17 @@ pub fn trace_to_mesh(mesh: &Mesh, base: Vec3, ray: Vec3) -> Option ); let m = m.inverse(); let rel = m * (base - f.vertices[0]); - if rel.z > dist { - continue; - } - dist = rel.z; - ret = Some(TraceResult { + Some(TraceResult { distance: rel.z, normal: f.normal, - }); - } - ret + }) + }) +} + +pub fn trace_to_mesh(mesh: &Mesh, base: Vec3, ray: Vec3) -> Option { + trace_to_mesh_all(mesh, base, ray) + .filter(|tr| tr.distance >= 0.0) + .min_by(|a, b| a.distance.total_cmp(&b.distance)) } fn edge_dist(a: Vec3, b: Vec3, base: Vec3, dir: Vec3) -> f32 {