-
Notifications
You must be signed in to change notification settings - Fork 0
/
aabb.hpp
59 lines (48 loc) · 1.39 KB
/
aabb.hpp
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
// Axis Aligned Bounding Box
#pragma once
#include "interval.hpp"
#include "ray.hpp"
#include "vec3.hpp"
class aabb {
public:
interval x, y, z;
aabb() {}
aabb(const interval& x, const interval& y, const interval& z)
: x(x),
y(y),
z(z) {}
aabb(const point3& a, const point3& b)
: x(fmin(a.x(), b.x()), fmax(a.x(), b.x())),
y(fmin(a.y(), b.y()), fmax(a.y(), b.y())),
z(fmin(a.z(), b.z()), fmax(a.z(), b.z())) {}
aabb(const aabb& a, const aabb& b): x(a.x, b.x), y(a.y, b.y), z(a.z, b.z) {}
const interval& axis(int n) const {
switch (n) {
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
throw std::runtime_error("Invalid axis");
}
}
bool hit(const ray& r, interval ray_t) const {
for (int a = 0; a < 3; a++) {
auto invD = 1.0 / r.direction()[a];
auto origin = r.origin()[a];
auto t0 = (axis(a).min - origin) * invD;
auto t1 = (axis(a).max - origin) * invD;
if (invD < 0.0)
std::swap(t0, t1);
if (t0 > ray_t.min)
ray_t.min = t0;
if (t1 < ray_t.max)
ray_t.max = t1;
if (ray_t.max <= ray_t.min)
return false;
}
return true;
}
};