Cleaned up implementation of ray/triangle intersection test.
This commit is contained in:
parent
f371e0643a
commit
a1840ec408
|
@ -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,15 +82,11 @@ 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) {
|
||||
if det > 0.0 && (t <= 0.0 || t > (ray.max_t * det)) {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
if -t <= 0.0 || -t > (ray.max_t * -det) {
|
||||
} else if det < 0.0 && (t >= 0.0 || t < (ray.max_t * det)) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
// Return t and the hitpoint barycentric coordinates.
|
||||
let inv_det = 1.0 / det;
|
||||
|
|
Loading…
Reference in New Issue
Block a user