-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaabb.h
More file actions
95 lines (77 loc) · 2.94 KB
/
Copy pathaabb.h
File metadata and controls
95 lines (77 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//
// Created by 13240 on 2025/10/19.
//
#ifndef SIMPLE_SOFTRT_AABB_H
#define SIMPLE_SOFTRT_AABB_H
class aabb {
public:
interval x, y, z;
static const aabb empty, universe;
aabb() {}
aabb(const interval &x, const interval &y, const interval &z)
: x(x), y(y), z(z)
{
pad_to_minimums();
}
aabb(const point3 &a, const point3 &b) { // ab是坐标极值,类似2d的左下角和左上角位置
x = a.e[0] <= b.e[0] ? interval(a.e[0], b.e[0]) : interval(b.e[0], a.e[0]);
y = a.e[1] <= b.e[1] ? interval(a.e[1], b.e[1]) : interval(b.e[1], a.e[1]);
z = a.e[2] <= b.e[2] ? interval(a.e[2], b.e[2]) : interval(b.e[2], a.e[2]);
pad_to_minimums();
}
aabb(const aabb& box0, const aabb& box1) {
x = interval(box0.x, box1.x);
y = interval(box0.y, box1.y);
z = interval(box0.z, box1.z);
}
const interval &axis_interval(int n) const { // 获取对应轴的interval
if (n == 1) return y;
if (n == 2) return z;
return x;
}
int longest_axis() const {
if (x.size() > y.size())
return x.size() > z.size() ? 0 : 2;
else
return y.size() > z.size() ? 1 : 2;
}
// 判断光线是否和aabb相交
// 光可能沿着 -axis 方向
// 解 t0,t1 时,公式的分子分母可能是 0
bool hit(const ray &r, interval ray_t) const {
const point3 &ray_orig = r.origin();
const vec3 &ray_dir = r.direction();
for (int axis = 0; axis < 3; ++axis) {
const interval &ax = axis_interval(axis);
const double adinv = 1.0 / ray_dir[axis]; // 按照公式,求交点的步长t
// ray intersect with one axis of aadd
// 此处 ax.min 仅表示位置,大小可能反转
auto t0 = (ax.min - ray_orig[axis]) * adinv;
auto t1 = (ax.max - ray_orig[axis]) * adinv;
// check overlap
// ray_t will be transfered to next
if (t0 < t1) { // case: [t0, t1]
if(t0 > ray_t.min) ray_t.min = t0;
if(t1 < ray_t.max) ray_t.max = t1;
} else { // case: [t1, t0], 处理光线沿着 -axis 方向
if(t1 > ray_t.min) ray_t.min = t1;
if(t0 < ray_t.max) ray_t.max = t0;
}
if(ray_t.min >= ray_t.max)
return false;
}
return true;
}
private:
private:
void pad_to_minimums() {
// Adjust the AABB so that no side is narrower than some delta, padding if necessary.
double delta = 0.0001;
if (x.size() < delta) x = x.expand(delta);
if (y.size() < delta) y = y.expand(delta);
if (z.size() < delta) z = z.expand(delta);
}
};
const aabb aabb::empty = aabb(interval::empty, interval::empty, interval::empty);
const aabb aabb::universe = aabb(interval::universe, interval::universe, interval::universe);
#endif //SIMPLE_SOFTRT_AABB_H