ray-tracing2/ray-tracing-scene/src/util.rs

43 lines
1.1 KiB
Rust

use ray_tracing_core::prelude::*;
pub fn triangle_intersection(ray: Ray, v: [Pos3; 3]) -> Option<Float> {
let e1 = v[1] - v[0];
let e2 = v[2] - v[0];
let ray_cross_e2 = Dir3::cross(ray.dir(), e2);
let det = e1.dot(ray_cross_e2);
if det > -f32::EPSILON && det < f32::EPSILON {
return None; // This ray is parallel to this triangle.
}
let inv_det = 1.0 / det;
let s = ray.start() - v[0];
let u = inv_det * s.dot(ray_cross_e2);
if !(0.0..=1.0).contains(&u) {
return None;
}
let s_cross_e1 = s.cross(e1);
let v = inv_det * Dir3::dot(ray.dir(), s_cross_e1);
if v < 0.0 || u + v > 1.0 {
return None;
}
// At this stage we can compute t to find out where the intersection point is on the line.
let t = inv_det * e2.dot(s_cross_e1);
if t > Float::EPSILON {
// ray intersection
Some(t)
} else {
// This means that there is a line intersection but not a ray intersection.
None
}
}
pub fn triangle_normal(v: [Pos3; 3]) -> Dir3 {
let e1 = v[1] - v[0];
let e2 = v[2] - v[0];
Dir3::cross(e1, e2)
}