-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrect.h
124 lines (104 loc) · 3.64 KB
/
rect.h
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifndef RECT_H
#define RECT_H
#include "hittable.h"
#include "aabb.h"
class xy_rect : public Hittable {
public:
xy_rect() {}
xy_rect(double _x0, double _x1, double _y0, double _y1, double _k, std::shared_ptr<Material> mat)
: x0(_x0), x1(_x1), y0(_y0), y1(_y1), k(_k), mp(mat){};
virtual bool hit(const Ray& r, double t_min, double t_max, HitRecord& rec) const override;
virtual bool bounding_box(double time0, double time1, aabb& output_box) const override {
// The bounding box must have non-zero width in each dimension, so pad the Z
// dimension a small amount.
output_box = aabb(vec3(x0, y0, k - 0.0001), vec3(x1, y1, k + 0.0001));
return true;
}
public:
std::shared_ptr<Material> mp;
double x0, x1, y0, y1, k;
};
inline bool xy_rect::hit(const Ray& r, double t_min, double t_max, HitRecord& rec) const {
auto t = (k - r.origin().z) / r.direction().z;
if (t < t_min || t > t_max)
return false;
auto x = r.origin().x + t * r.direction().x;
auto y = r.origin().y + t * r.direction().y;
if (x < x0 || x > x1 || y < y0 || y > y1)
return false;
rec.u = (x - x0) / (x1 - x0);
rec.v = (y - y0) / (y1 - y0);
rec.t = t;
auto outward_normal = vec3(0, 0, 1);
rec.set_face_normal(r, outward_normal);
rec.mat = mp;
rec.p = r.at(t);
return true;
}
class xz_rect : public Hittable {
public:
xz_rect() {}
xz_rect(double _x0, double _x1, double _z0, double _z1, double _k, Material* mat)
: x0(_x0), x1(_x1), z0(_z0), z1(_z1), k(_k), mp(mat){};
virtual bool hit(const Ray& r, double t_min, double t_max, HitRecord& rec) const override;
virtual bool bounding_box(double time0, double time1, aabb& output_box) const override {
// The bounding box must have non-zero width in each dimension, so pad the Y
// dimension a small amount.
output_box = aabb(vec3(x0, k - 0.0001, z0), vec3(x1, k + 0.0001, z1));
return true;
}
public:
std::shared_ptr<Material> mp;
double x0, x1, z0, z1, k;
};
class yz_rect : public Hittable {
public:
yz_rect() {}
yz_rect(double _y0, double _y1, double _z0, double _z1, double _k, std::shared_ptr<Material> mat)
: y0(_y0), y1(_y1), z0(_z0), z1(_z1), k(_k), mp(mat){};
virtual bool hit(const Ray& r, double t_min, double t_max, HitRecord& rec) const override;
virtual bool bounding_box(double time0, double time1, aabb& output_box) const override {
// The bounding box must have non-zero width in each dimension, so pad the X
// dimension a small amount.
output_box = aabb(vec3(k - 0.0001, y0, z0), vec3(k + 0.0001, y1, z1));
return true;
}
public:
std::shared_ptr<Material> mp;
double y0, y1, z0, z1, k;
};
inline bool xz_rect::hit(const Ray& r, double t_min, double t_max, HitRecord& rec) const {
auto t = (k - r.origin().y) / r.direction().y;
if (t < t_min || t > t_max)
return false;
auto x = r.origin().x + t * r.direction().x;
auto z = r.origin().z + t * r.direction().z;
if (x < x0 || x > x1 || z < z0 || z > z1)
return false;
rec.u = (x - x0) / (x1 - x0);
rec.v = (z - z0) / (z1 - z0);
rec.t = t;
auto outward_normal = vec3(0, 1, 0);
rec.set_face_normal(r, outward_normal);
rec.mat = mp;
rec.p = r.at(t);
return true;
}
inline bool yz_rect::hit(const Ray& r, double t_min, double t_max, HitRecord& rec) const {
auto t = (k - r.origin().x) / r.direction().x;
if (t < t_min || t > t_max)
return false;
auto y = r.origin().y + t * r.direction().y;
auto z = r.origin().z + t * r.direction().z;
if (y < y0 || y > y1 || z < z0 || z > z1)
return false;
rec.u = (y - y0) / (y1 - y0);
rec.v = (z - z0) / (z1 - z0);
rec.t = t;
auto outward_normal = vec3(1, 0, 0);
rec.set_face_normal(r, outward_normal);
rec.mat = mp;
rec.p = r.at(t);
return true;
}
#endif