-
Notifications
You must be signed in to change notification settings - Fork 0
/
cube_operations.cc
78 lines (63 loc) · 2.43 KB
/
cube_operations.cc
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
#include "cube_operations.hh"
#include "cube.hh"
#include "intersection.hh"
#include "pnt3.hh"
#include "ray.hh"
#include <spdlog/spdlog.h>
#include <algorithm> // min, max, abs
namespace {
struct ts {
float tmin;
float tmax;
};
ts check_axis(float origin, float direction) noexcept {
float const tmin_numerator = -1 - origin;
float const tmax_numerator = 1 - origin;
float const tmin = tmin_numerator / direction;
float const tmax = tmax_numerator / direction;
if (tmin > tmax) {
return {tmax, tmin};
}
return {tmin, tmax};
}
} // namespace
namespace wt {
tform4& tform(cube& c) noexcept { return c.tform; }
tform4 const& tform(cube const& c) noexcept { return c.tform; }
tform4& inv_tform(cube& c) noexcept { return c.inv_tform; }
tform4 const& inv_tform(cube const& c) noexcept { return c.inv_tform; }
struct material& mater(cube& c) noexcept { return c.material; }
struct material const& mater(cube const& c) noexcept { return c.material; }
bool& cast_shadow(cube& c) noexcept { return c.cast_shadow; }
bool const& cast_shadow(cube const& c) noexcept { return c.cast_shadow; }
void intersect(cube const& /*unused*/, ray const& object_ray, unsigned shape_id,
std::vector<intersection>& world_isecs) noexcept {
ts const x = check_axis(object_ray.origin.x, object_ray.direction.x);
ts const y = check_axis(object_ray.origin.y, object_ray.direction.y);
ts const z = check_axis(object_ray.origin.z, object_ray.direction.z);
float const tmin = std::max({x.tmin, y.tmin, z.tmin});
float const tmax = std::min({x.tmax, y.tmax, z.tmax});
if (tmin < tmax) {
world_isecs.emplace_back(shape_id, tmin);
world_isecs.emplace_back(shape_id, tmax);
}
}
vec3 normal_at(cube const& /*unused*/, pnt3 const& world_point, tform4 const& inv_tform) noexcept {
pnt3 const object_point = inv_tform * world_point;
float const abs_x = std::abs(object_point.x);
float const abs_y = std::abs(object_point.y);
float const abs_z = std::abs(object_point.z);
float const abs_max = std::max({abs_x, abs_y, abs_z});
if (abs_max == abs_x) {
return normalize(vec3{object_point.x, 0, 0} * inv_tform);
}
if (abs_max == abs_y) {
return normalize(vec3{0, object_point.y, 0} * inv_tform);
}
if (abs_max == abs_z) {
return normalize(vec3{0, 0, object_point.z} * inv_tform);
}
SPDLOG_TRACE("impossibru");
std::exit(1);
}
} // namespace wt