use cgmath::{InnerSpace, Vector3}; use super::ray::Ray; pub struct Triangle { pub points: [Vector3; 3], } impl Triangle { pub fn new(v0: Vector3, v1: Vector3, v2: Vector3) -> Triangle { Triangle { points: [v0, v1, v2], } } // source: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/moller-trumbore-ray-triangle-intersection pub fn intersect_mt(&self, ray: &Ray, t: &mut f32) -> bool { let v0v1 = self.points[1] - self.points[0]; let v0v2 = self.points[2] - self.points[0]; let pvec = ray.direction.cross(v0v2); let det = v0v1.dot(pvec); // ray and triangle are parallel if det is close to 0 if det.abs() < 0.001 { return false; } let inv_det = 1.0 / det; let tvec = ray.origin - self.points[0]; let u = tvec.dot(pvec) * inv_det; if u < 0.0 || u > 1.0 { return false; } let qvec = tvec.cross(v0v1); let v = ray.direction.dot(qvec) * inv_det; if v < 0.0 || u + v > 1.0 { return false; } *t = v0v2.dot(qvec) * inv_det; true } }