diff --git a/src/surface/triangle.rs b/src/surface/triangle.rs index 0a776eb..18da9f2 100644 --- a/src/surface/triangle.rs +++ b/src/surface/triangle.rs @@ -17,28 +17,19 @@ use ray::Ray; /// Intersection" by Woop et al. pub fn intersect_ray(ray: &Ray, tri: (Point, Point, Point)) -> Option<(f32, f32, f32, f32)> { // Calculate the permuted dimension indices for the new ray space. - let zi = { + let (xi, yi, zi) = { let xabs = ray.dir.x().abs(); let yabs = ray.dir.y().abs(); let zabs = ray.dir.z().abs(); if xabs > yabs && xabs > zabs { - 0 + (1, 2, 0) } else if yabs > zabs { - 1 + (2, 0, 1) } else { - 2 + (0, 1, 2) } }; - let (xi, yi) = if ray.dir.get_n(zi) >= 0.0 { - let xi = if zi == 2 { 0 } else { zi + 1 }; - let yi = if xi == 2 { 0 } else { xi + 1 }; - (xi, yi) - } else { - let xi = if zi == 2 { 0 } else { zi + 1 }; - let yi = if xi == 2 { 0 } else { xi + 1 }; - (yi, xi) - }; let dir_x = ray.dir.get_n(xi); let dir_y = ray.dir.get_n(yi); @@ -54,29 +45,23 @@ pub fn intersect_ray(ray: &Ray, tri: (Point, Point, Point)) -> Option<(f32, f32, let p1 = tri.1 - ray.orig; let p2 = tri.2 - ray.orig; - let p0x = p0.get_n(xi) - sx * p0.get_n(zi); - let p0y = p0.get_n(yi) - sy * p0.get_n(zi); - let p1x = p1.get_n(xi) - sx * p1.get_n(zi); - let p1y = p1.get_n(yi) - sy * p1.get_n(zi); - let p2x = p2.get_n(xi) - sx * p2.get_n(zi); - let p2y = p2.get_n(yi) - sy * p2.get_n(zi); + let p0x = p0.get_n(xi) - (sx * p0.get_n(zi)); + let p0y = p0.get_n(yi) - (sy * p0.get_n(zi)); + let p1x = p1.get_n(xi) - (sx * p1.get_n(zi)); + let p1y = p1.get_n(yi) - (sy * p1.get_n(zi)); + let p2x = p2.get_n(xi) - (sx * p2.get_n(zi)); + let p2y = p2.get_n(yi) - (sy * p2.get_n(zi)); // Calculate scaled barycentric coordinates. - let mut e0 = (p2x * p1y) - (p2y * p1x); - let mut e1 = (p0x * p2y) - (p0y * p2x); - let mut e2 = (p1x * p0y) - (p1y * p0x); + let mut e0 = (p1x * p2y) - (p1y * p2x); + let mut e1 = (p2x * p0y) - (p2y * p0x); + let mut e2 = (p0x * p1y) - (p0y * p1x); // Fallback to test against edges using double precision. if e0 == 0.0 || e1 == 0.0 || e2 == 0.0 { - let p2xp1y = p2x as f64 * p1y as f64; - let p2yp1x = p2y as f64 * p1x as f64; - e0 = (p2xp1y - p2yp1x) as f32; - let p0xp2y = p0x as f64 * p2y as f64; - let p0yp2x = p0y as f64 * p2x as f64; - e1 = (p0xp2y - p0yp2x) as f32; - let p1xp0y = p1x as f64 * p0y as f64; - let p1yp0x = p1y as f64 * p0x as f64; - e2 = (p1xp0y - p1yp0x) as f32; + e0 = ((p1x as f64 * p2y as f64) - (p1y as f64 * p2x as f64)) as f32; + e1 = ((p2x as f64 * p0y as f64) - (p2y as f64 * p0x as f64)) as f32; + e2 = ((p0x as f64 * p1y as f64) - (p0y as f64 * p1x as f64)) as f32; } // Check if the ray hit the triangle. @@ -97,14 +82,10 @@ pub fn intersect_ray(ray: &Ray, tri: (Point, Point, Point)) -> Option<(f32, f32, let t = (e0 * p0z) + (e1 * p1z) + (e2 * p2z); // Check if the hitpoint t is within ray min/max t. - if det >= 0.0 { - if t <= 0.0 || t > (ray.max_t * det) { - return None; - } - } else { - if -t <= 0.0 || -t > (ray.max_t * -det) { - return None; - } + if det > 0.0 && (t <= 0.0 || t > (ray.max_t * det)) { + return None; + } else if det < 0.0 && (t >= 0.0 || t < (ray.max_t * det)) { + return None; } // Return t and the hitpoint barycentric coordinates.