Skip to content

Commit 3979043

Browse files
author
Luc Forget
committed
Adding monostate in front of each variant
1 parent ee32c11 commit 3979043

7 files changed

Lines changed: 151 additions & 67 deletions

File tree

include/box.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,9 @@ class box {
3434
auto closest_so_far = max;
3535
// Checking if the ray hits any of the sides
3636
for (const auto& side : sides) {
37-
if (dev_visit(
38-
[&](auto&& arg) {
39-
return arg.hit(ctx, r, min, closest_so_far, temp_rec,
40-
temp_material_type);
41-
},
42-
side)) {
37+
if (dev_visit(hittable_hit_visitor(ctx, r, min, closest_so_far, temp_rec,
38+
temp_material_type),
39+
side)) {
4340
hit_anything = true;
4441
closest_so_far = temp_rec.t;
4542
rec = temp_rec;

include/constant_medium.hpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "texture.hpp"
88
#include "visit.hpp"
99

10-
using hittableVolume_t = std::variant<sphere, box>;
10+
using hittableVolume_t = std::variant<std::monostate, sphere, box>;
1111

1212
/**
1313
* A ray going through the volume can either make it all the way through
@@ -31,20 +31,14 @@ class constant_medium {
3131
hit_material_type = phase_function;
3232
material_t temp_material_type;
3333
hit_record rec1, rec2;
34-
if (!dev_visit(
35-
[&](auto&& arg) {
36-
return arg.hit(ctx, r, -infinity, infinity, rec1,
37-
temp_material_type);
38-
},
39-
boundary)) {
34+
if (!dev_visit(hittable_hit_visitor(ctx, r, -infinity, infinity, rec1,
35+
temp_material_type),
36+
boundary)) {
4037
return false;
4138
}
4239

43-
if (!dev_visit(
44-
[&](auto&& arg) {
45-
return arg.hit(ctx, r, rec1.t + 0.0001f, infinity, rec2,
46-
temp_material_type);
47-
},
40+
if (!dev_visit(hittable_hit_visitor(ctx, r, rec1.t + 0.0001f, infinity, rec2,
41+
temp_material_type),
4842
boundary)) {
4943
return false;
5044
}

include/hit_record.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef HIT_RECORD_HPP
2+
#define HIT_RECORD_HPP
3+
4+
#include "rtweekend.hpp"
5+
6+
class hit_record {
7+
public:
8+
real_t t; //
9+
point p; // hit point
10+
vec normal; // normal at hit point
11+
bool front_face; // to check if hit point is on the outer surface
12+
/*local coordinates for rectangles
13+
and mercator coordintes for spheres */
14+
real_t u;
15+
real_t v;
16+
17+
// To set if the hit point is on the front face
18+
void set_face_normal(const ray& r, const vec& outward_normal) {
19+
front_face = dot(r.direction(), outward_normal) < 0;
20+
normal = front_face ? outward_normal : vec {} - outward_normal;
21+
}
22+
};
23+
#endif

include/hitable.hpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,49 @@
11
#ifndef HITTABLE_H
22
#define HITTABLE_H
33

4-
#include "ray.hpp"
4+
#include <variant>
5+
6+
#include "hit_record.hpp"
7+
#include "material.hpp"
58
#include "rtweekend.hpp"
69
#include "vec.hpp"
710

8-
class hit_record {
11+
struct hittable_hit_visitor {
12+
private:
13+
task_context& ctx;
14+
const ray& r;
15+
real_t min;
16+
real_t max;
17+
hit_record& rec;
18+
material_t& hit_material_type;
19+
920
public:
10-
real_t t; //
11-
point p; // hit point
12-
vec normal; // normal at hit point
13-
bool front_face; // to check if hit point is on the outer surface
14-
/*local coordinates for rectangles
15-
and mercator coordintes for spheres */
16-
real_t u;
17-
real_t v;
18-
19-
// To set if the hit point is on the front face
20-
void set_face_normal(const ray& r, const vec& outward_normal) {
21-
front_face = dot(r.direction(), outward_normal) < 0;
22-
normal = front_face ? outward_normal : vec {} - outward_normal;
21+
hittable_hit_visitor(task_context& ctx, const ray& r, real_t min, real_t max,
22+
hit_record& rec, material_t& hit_material_type)
23+
: ctx { ctx }
24+
, r { r }
25+
, min { min }
26+
, max { max }
27+
, rec { rec }
28+
, hit_material_type { hit_material_type } {}
29+
30+
template <typename H> bool operator()(H&& hittable) {
31+
return hittable.hit(ctx, r, min, max, rec, hit_material_type);
32+
}
33+
34+
bool operator()(std::monostate) {
35+
assert(fase && "unreachable");
36+
return false;
2337
}
2438
};
2539

40+
#include "box.hpp"
41+
#include "constant_medium.hpp"
42+
#include "ray.hpp"
43+
#include "rectangle.hpp"
44+
#include "sphere.hpp"
45+
#include "triangle.hpp"
46+
47+
using hittable_t = std::variant<std::monostate, sphere, xy_rect, triangle, box,
48+
constant_medium>;
2649
#endif

include/material.hpp

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <iostream>
55

6-
#include "hitable.hpp"
6+
#include "hit_record.hpp"
77
#include "texture.hpp"
88
#include "vec.hpp"
99
#include "visit.hpp"
@@ -22,8 +22,7 @@ struct lambertian_material {
2222
scattered = ray(rec.p, scatter_direction, r_in.time());
2323
// Attenuation of the ray hitting the object is modified based on the color
2424
// at hit point
25-
attenuation *=
26-
dev_visit([&](auto&& arg) { return arg.value(ctx, rec); }, albedo);
25+
attenuation *= dev_visit(texture_value_visitor(ctx, rec), albedo);
2726
return true;
2827
}
2928
color emitted(auto&, const hit_record& rec) { return color(0, 0, 0); }
@@ -77,8 +76,7 @@ struct dielectric_material {
7776
real_t sin_theta = sycl::sqrt(1.0f - cos_theta * cos_theta);
7877
bool cannot_refract = refraction_ratio * sin_theta > 1.0f;
7978
vec direction;
80-
if (cannot_refract ||
81-
reflectance(cos_theta, refraction_ratio) > rng.real())
79+
if (cannot_refract || reflectance(cos_theta, refraction_ratio) > rng.real())
8280
direction = reflect(unit_direction, rec.normal);
8381
else
8482
direction = refract(unit_direction, rec.normal, refraction_ratio);
@@ -104,7 +102,7 @@ struct lightsource_material {
104102
template <typename... T> bool scatter(T&...) const { return false; }
105103

106104
color emitted(auto& ctx, const hit_record& rec) {
107-
return dev_visit([&](auto&& arg) { return arg.value(ctx, rec); }, emit);
105+
return dev_visit(texture_value_visitor(ctx, rec), emit);
108106
}
109107

110108
texture_t emit;
@@ -120,8 +118,7 @@ struct isotropic_material {
120118
color& attenuation, ray& scattered) const {
121119
auto& rng = ctx.rng;
122120
scattered = ray(rec.p, rng.in_unit_ball(), r_in.time());
123-
attenuation *=
124-
dev_visit([&](auto&& arg) { return arg.value(ctx, rec); }, albedo);
121+
attenuation *= dev_visit(texture_value_visitor(ctx, rec), albedo);
125122
return true;
126123
}
127124

@@ -131,7 +128,54 @@ struct isotropic_material {
131128
};
132129

133130
using material_t =
134-
std::variant<lambertian_material, metal_material, dielectric_material,
135-
lightsource_material, isotropic_material>;
131+
std::variant<std::monostate, lambertian_material, metal_material,
132+
dielectric_material, lightsource_material, isotropic_material>;
133+
134+
struct material_emitted_visitor {
135+
private:
136+
task_context& ctx;
137+
const hit_record& rec;
138+
139+
public:
140+
material_emitted_visitor(task_context& ctx, hit_record& rec)
141+
: ctx { ctx }
142+
, rec { rec } {}
143+
144+
template <typename M> color operator()(M&& material) {
145+
return material.emitted(ctx, rec);
146+
}
147+
148+
color operator()(std::monostate) {
149+
assert(false && "unreachable");
150+
return { 0.f, 0.f, 0.f };
151+
}
152+
};
153+
154+
struct material_scatter_visitor {
155+
private:
156+
task_context& ctx;
157+
const ray& r_in;
158+
const hit_record& rec;
159+
color& attenuation;
160+
ray& scattered;
161+
162+
public:
163+
material_scatter_visitor(auto& ctx, const ray& r_in, const hit_record& rec,
164+
color& attenuation, ray& scattered)
165+
: ctx { ctx }
166+
, r_in { r_in }
167+
, rec { rec }
168+
, attenuation { attenuation }
169+
, scattered { scattered } {}
170+
171+
template <typename M> bool operator()(M&& material) {
172+
return material.scatter(ctx, r_in, rec, attenuation, scattered);
173+
}
174+
175+
bool operator()(std::monostate) {
176+
assert(false && "unreachable");
177+
return false;
178+
}
179+
};
136180

137181
#endif

include/render.hpp

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,17 @@
33
#include <variant>
44
#include <vector>
55

6-
#include "box.hpp"
76
#include "build_parameters.hpp"
87
#include "camera.hpp"
9-
#include "constant_medium.hpp"
108
#include "hitable.hpp"
119
#include "material.hpp"
1210
#include "ray.hpp"
13-
#include "rectangle.hpp"
1411
#include "rtweekend.hpp"
15-
#include "sphere.hpp"
1612
#include "sycl.hpp"
1713
#include "texture.hpp"
18-
#include "triangle.hpp"
1914
#include "vec.hpp"
2015
#include "visit.hpp"
2116

22-
using hittable_t =
23-
std::variant<sphere, xy_rect, triangle, box, constant_medium>;
24-
2517
template <int width, int height, int samples, int depth>
2618
inline auto render_pixel(auto& ctx, int x_coord, int y_coord, camera const& cam,
2719
auto& hittable_acc, auto fb_acc) {
@@ -35,12 +27,9 @@ inline auto render_pixel(auto& ctx, int x_coord, int y_coord, camera const& cam,
3527
auto closest_so_far = infinity;
3628
// Checking if the ray hits any of the spheres
3729
for (auto i = 0; i < hittable_acc.get_count(); i++) {
38-
if (dev_visit(
39-
[&](auto&& arg) {
40-
return arg.hit(ctx, r, 0.001f, closest_so_far, temp_rec,
41-
temp_material_type);
42-
},
43-
hittable_acc[i])) {
30+
if (dev_visit(hittable_hit_visitor(ctx, r, 0.001f, closest_so_far,
31+
temp_rec, temp_material_type),
32+
hittable_acc[i])) {
4433
hit_anything = true;
4534
closest_so_far = temp_rec.t;
4635
rec = temp_rec;
@@ -58,14 +47,10 @@ inline auto render_pixel(auto& ctx, int x_coord, int y_coord, camera const& cam,
5847
for (auto i = 0; i < depth; i++) {
5948
hit_record rec;
6049
if (hit_world(cur_ray, rec, material_type)) {
61-
emitted = dev_visit([&](auto&& arg) { return arg.emitted(ctx, rec); },
62-
material_type);
63-
if (dev_visit(
64-
[&](auto&& arg) {
65-
return arg.scatter(ctx, cur_ray, rec, cur_attenuation,
66-
scattered);
67-
},
68-
material_type)) {
50+
emitted = dev_visit(material_emitted_visitor(ctx, rec), material_type);
51+
if (dev_visit(material_scatter_visitor(ctx, cur_ray, rec,
52+
cur_attenuation, scattered),
53+
material_type)) {
6954
// On hitting the object, the ray gets scattered
7055
cur_ray = scattered;
7156
} else {

include/texture.hpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#ifndef RT_SYCL_TEXTURE_HPP
22
#define RT_SYCL_TEXTURE_HPP
3-
#include "hitable.hpp"
3+
#include "hit_record.hpp"
44
#include "rtweekend.hpp"
55
#include "vec.hpp"
66
#include <array>
@@ -151,7 +151,25 @@ struct image_texture {
151151
}
152152
};
153153

154-
using texture_t = std::variant<checker_texture, solid_texture, image_texture>;
154+
using texture_t = std::variant<std::monostate, checker_texture, solid_texture, image_texture>;
155+
156+
struct texture_value_visitor {
157+
private:
158+
task_context& ctx;
159+
const hit_record& rec;
160+
161+
public:
162+
texture_value_visitor(task_context& ctx, const hit_record& rec):ctx{ctx}, rec{rec}{}
163+
template<typename T>
164+
color operator()(T&& texture) {
165+
return texture.value(ctx, rec);
166+
}
167+
168+
color operator()(std::monostate) {
169+
assert(false && "unreachable");
170+
return {0.f,0.f,0.f};
171+
}
172+
};
155173

156174
// Start filled with the fallback texture (solid blue) for texture load error
157175
std::vector<uint8_t> image_texture::texture_data { 0, 0, 1 };

0 commit comments

Comments
 (0)