pbrt_r3/core/geometry/
intersect.rs

1use crate::core::base::*;
2
3fn toa(v: &Vector3f) -> [Float; 3] {
4    [v.x, v.y, v.z]
5}
6
7pub fn intersect_box(
8    min: &Vector3f,
9    max: &Vector3f,
10    org: &Vector3f,
11    dir: &Vector3f,
12    t0: Float,
13    t1: Float,
14) -> (bool, Float, Float) {
15    return intersect_box_array(&toa(min), &toa(max), &toa(org), &toa(dir), t0, t1);
16}
17
18pub fn intersect_box_array(
19    min: &[Float; 3],
20    max: &[Float; 3],
21    org: &[Float; 3],
22    dir: &[Float; 3],
23    t0: Float,
24    t1: Float,
25) -> (bool, Float, Float) {
26    let idir = [
27        //1.0 / dir[0],
28        //1.0 / dir[1],
29        //1.0 / dir[2],
30        Float::recip(dir[0]),
31        Float::recip(dir[1]),
32        Float::recip(dir[2]),
33    ];
34    let sign = [
35        if dir[0].is_sign_negative() { 1 } else { 0 },
36        if dir[1].is_sign_negative() { 1 } else { 0 },
37        if dir[2].is_sign_negative() { 1 } else { 0 },
38    ];
39    if let Some((t0, t1)) = intersect_box_array_i(min, max, org, &idir, &sign, t0, t1) {
40        return (true, t0, t1);
41    } else {
42        return (false, t0, t1);
43    }
44}
45
46pub fn intersect_box_array_i(
47    min: &[Float; 3],
48    max: &[Float; 3],
49    org: &[Float; 3],
50    idir: &[Float; 3],
51    sign: &[usize; 3],
52    mut t0: Float,
53    mut t1: Float,
54) -> Option<(Float, Float)> {
55    let bounds = [min, max];
56    for i in 0..3 {
57        t0 = Float::max(t0, (bounds[sign[i]][i] - org[i]) * idir[i]);
58        t1 = Float::min(t1, (bounds[1 - sign[i]][i] - org[i]) * idir[i]);
59    }
60    if t0 <= t1 {
61        return Some((t0, t1));
62    } else {
63        return None;
64    }
65}