forked from netolcc06/BabyRayTracer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Box.hpp
97 lines (79 loc) · 2.45 KB
/
Box.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
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
#ifndef BOX_
#define BOX_
#include <stdlib.h>
#include "Vec3.hpp"
#include "Ray.hpp"
#include "Hitable.hpp"
#include "Material.hpp"
class Box : public Hitable
{
public:
Box() {}
Box(Vec3<float> min, Vec3<float> max, Material * m) {
bounds[0] = min;
bounds[1] = max;
material = m;
}
virtual bool hit(Ray<float> & r, float t_min, float t_max, hit_record & rec) const;
Vec3<float> bounds[2];
Material * material;
};
bool Box::hit(Ray<float> & r, float t_min, float t_max, hit_record & rec) const {
float tmin, tmax, tymin, tymax, tzmin, tzmax;
if (r.direction().x() >= 0) {
tmin = (bounds[0].x() - r.origin().x()) / r.direction().x();
tmax = (bounds[1].x() - r.origin().x()) / r.direction().x();
}
else {
tmin = (bounds[1].x() - r.origin().x()) / r.direction().x();
tmax = (bounds[0].x() - r.origin().x()) / r.direction().x();
}
if (r.direction().y() >= 0) {
tymin = (bounds[0].y() - r.origin().y()) / r.direction().y();
tymax = (bounds[1].y() - r.origin().y()) / r.direction().y();
}
else {
tymin = (bounds[1].y() - r.origin().y()) / r.direction().y();
tymax = (bounds[0].y() - r.origin().y()) / r.direction().y();
}
if ((tmin > tymax) || (tymin > tmax))
return false;
if (tymin > tmin)
tmin = tymin;
if (tymax < tmax)
tmax = tymax;
if (r.direction().z() >= 0) {
tzmin = (bounds[0].z() - r.origin().z()) / r.direction().z();
tzmax = (bounds[1].z() - r.origin().z()) / r.direction().z();
}
else {
tzmin = (bounds[1].z() - r.origin().z()) / r.direction().z();
tzmax = (bounds[0].z() - r.origin().z()) / r.direction().z();
}
if ((tmin > tzmax) || (tzmin > tmax))
return false;
if (tzmin > tmin)
tmin = tzmin;
if (tzmax < tmax)
tmax = tzmax;
Vec3<float> normal;
rec.t = tmin;
rec.p = r.point_at_parameter(tmin);
float EPSI = 0.01;
if (abs(rec.p.z() - bounds[0].z()) <= EPSI)
normal = Vec3<float>(0, 0, -1);
else if (abs(rec.p.z() - bounds[1].z()) <= EPSI)
normal = Vec3<float>(0, 0, 1);
else if (abs(rec.p.x() - bounds[1].x()) <= EPSI)
normal = Vec3<float>(1, 0, 0);
else if (abs(rec.p.x() - bounds[0].x()) <= EPSI)
normal = Vec3<float>(-1, 0, 0);
else if (abs(rec.p.y() - bounds[1].y()) <= EPSI)
normal = Vec3<float>(0, 1, 0);
else if (abs(rec.p.y() - bounds[0].y()) <= EPSI)
normal = Vec3<float>(0, -1, 0);
rec.normal = normal;
rec.mat_ptr = material;
return ((tmin < t_max) && (tmax > t_min));
}
#endif