Skip to content

Commit 26cc35c

Browse files
committed
hitvec nextWeek: hittable_list to std::vector
1 parent 2108dec commit 26cc35c

File tree

4 files changed

+379
-339
lines changed

4 files changed

+379
-339
lines changed

src/TheNextWeek/box.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,35 @@
1919
class box: public hittable {
2020
public:
2121
box() {}
22-
2322
box(const vec3& p0, const vec3& p1, material *ptr);
2423

2524
virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const;
2625

2726
virtual bool bounding_box(double t0, double t1, aabb& output_box) const {
28-
output_box = aabb(pmin, pmax);
27+
output_box = aabb(box_min, box_max);
2928
return true;
3029
}
3130

32-
vec3 pmin, pmax;
33-
hittable *list_ptr;
31+
vec3 box_min;
32+
vec3 box_max;
33+
hittable_list sides;
3434
};
3535

3636
box::box(const vec3& p0, const vec3& p1, material *ptr) {
37-
pmin = p0;
38-
pmax = p1;
39-
hittable **list = new hittable*[6];
40-
list[0] = new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p1.z(), ptr);
41-
list[1] = new flip_normals(new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p0.z(), ptr));
42-
list[2] = new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p1.y(), ptr);
43-
list[3] = new flip_normals(new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p0.y(), ptr));
44-
list[4] = new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p1.x(), ptr);
45-
list[5] = new flip_normals(new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p0.x(), ptr));
46-
list_ptr = new hittable_list(list,6);
37+
box_min = p0;
38+
box_max = p1;
39+
40+
sides.add(new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p1.z(), ptr));
41+
sides.add(new flip_normals(new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p0.z(), ptr)));
42+
sides.add(new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p1.y(), ptr));
43+
sides.add(new flip_normals(new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p0.y(), ptr)));
44+
sides.add(new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p1.x(), ptr));
45+
sides.add(new flip_normals(new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p0.x(), ptr)));
4746
}
4847

4948
bool box::hit(const ray& r, double t0, double t1, hit_record& rec) const {
50-
return list_ptr->hit(r, t0, t1, rec);
49+
return sides.hit(r, t0, t1, rec);
5150
}
5251

52+
5353
#endif

src/TheNextWeek/bvh.h

Lines changed: 62 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,20 @@
1313

1414
#include "common/rtweekend.h"
1515
#include "hittable.h"
16+
#include <algorithm>
1617

1718

1819
class bvh_node : public hittable {
1920
public:
20-
bvh_node() {}
21-
bvh_node(hittable **l, int n, double time0, double time1);
21+
bvh_node() = delete;
22+
23+
bvh_node::bvh_node(hittable_list& list, double time0, double time1)
24+
: bvh_node(list.objects, 0, list.objects.size(), time0, time1)
25+
{}
26+
27+
bvh_node(
28+
std::vector<hittable*>& objects,
29+
size_t start, size_t end, double time0, double time1);
2230

2331
virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const;
2432
virtual bool bounding_box(double t0, double t1, aabb& output_box) const;
@@ -28,95 +36,77 @@ class bvh_node : public hittable {
2836
aabb box;
2937
};
3038

31-
bool bvh_node::bounding_box(double t0, double t1, aabb& output_box) const {
32-
output_box = box;
33-
return true;
34-
}
3539

36-
bool bvh_node::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
37-
if (!box.hit(r, t_min, t_max))
38-
return false;
40+
bool box_compare(const hittable* a, const hittable* b, int axis) {
41+
aabb box_a;
42+
aabb box_b;
3943

40-
bool hit_left = left->hit(r, t_min, t_max, rec);
41-
bool hit_right = right->hit(r, t_min, hit_left ? rec.t : t_max, rec);
44+
if (!a->bounding_box(0,0, box_a) || !b->bounding_box(0,0, box_b))
45+
std::cerr << "No bounding box in bvh_node constructor.\n";
4246

43-
return hit_left || hit_right;
47+
return box_a.min().e[axis] < box_b.min().e[axis];
4448
}
4549

46-
int box_x_compare (const void * a, const void * b) {
47-
aabb box_left, box_right;
48-
hittable *ah = *(hittable**)a;
49-
hittable *bh = *(hittable**)b;
50-
51-
if (!ah->bounding_box(0,0, box_left) || !bh->bounding_box(0,0, box_right))
52-
std::cerr << "no bounding box in bvh_node constructor\n";
5350

54-
if (box_left.min().x() - box_right.min().x() < 0.0)
55-
return -1;
56-
else
57-
return 1;
58-
}
59-
60-
int box_y_compare (const void * a, const void * b)
61-
{
62-
aabb box_left, box_right;
63-
hittable *ah = *(hittable**)a;
64-
hittable *bh = *(hittable**)b;
51+
bool box_x_compare (const hittable* a, const hittable* b) { return box_compare(a, b, 0); }
52+
bool box_y_compare (const hittable* a, const hittable* b) { return box_compare(a, b, 1); }
53+
bool box_z_compare (const hittable* a, const hittable* b) { return box_compare(a, b, 2); }
6554

66-
if (!ah->bounding_box(0,0, box_left) || !bh->bounding_box(0,0, box_right))
67-
std::cerr << "no bounding box in bvh_node constructor\n";
6855

69-
if (box_left.min().y() - box_right.min().y() < 0.0)
70-
return -1;
71-
else
72-
return 1;
73-
}
56+
bvh_node::bvh_node(
57+
std::vector<hittable*>& objects, size_t start, size_t end, double time0, double time1
58+
) {
59+
int axis = random_int(0,2);
60+
auto comparator = (axis == 0) ? box_x_compare
61+
: (axis == 1) ? box_y_compare
62+
: box_z_compare;
63+
64+
size_t object_span = end - start;
65+
66+
if (object_span == 1) {
67+
left = right = objects[start];
68+
} else if (object_span == 2) {
69+
if (comparator(objects[start], objects[start+1])) {
70+
left = objects[start];
71+
right = objects[start+1];
72+
} else {
73+
left = objects[start+1];
74+
right = objects[start];
75+
}
76+
} else {
77+
std::sort(objects.begin() + start, objects.begin() + end, comparator);
78+
79+
auto mid = start + object_span/2;
80+
left = new bvh_node(objects, start, mid, time0, time1);
81+
right = new bvh_node(objects, mid, end, time0, time1);
82+
}
7483

75-
int box_z_compare (const void * a, const void * b)
76-
{
7784
aabb box_left, box_right;
78-
hittable *ah = *(hittable**)a;
79-
hittable *bh = *(hittable**)b;
8085

81-
if (!ah->bounding_box(0,0, box_left) || !bh->bounding_box(0,0, box_right))
82-
std::cerr << "no bounding box in bvh_node constructor\n";
86+
if ( !left->bounding_box (time0, time1, box_left)
87+
|| !right->bounding_box(time0, time1, box_right)
88+
)
89+
std::cerr << "No bounding box in bvh_node constructor.\n";
8390

84-
if (box_left.min().z() - box_right.min().z() < 0.0)
85-
return -1;
86-
else
87-
return 1;
91+
box = surrounding_box(box_left, box_right);
8892
}
8993

90-
bvh_node::bvh_node(hittable **l, int n, double time0, double time1) {
91-
int axis = random_int(0,2);
9294

93-
if (axis == 0)
94-
qsort(l, n, sizeof(hittable *), box_x_compare);
95-
else if (axis == 1)
96-
qsort(l, n, sizeof(hittable *), box_y_compare);
97-
else
98-
qsort(l, n, sizeof(hittable *), box_z_compare);
95+
bool bvh_node::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
96+
if (!box.hit(r, t_min, t_max))
97+
return false;
9998

100-
if (n == 1) {
101-
left = right = l[0];
102-
}
103-
else if (n == 2) {
104-
left = l[0];
105-
right = l[1];
106-
}
107-
else {
108-
left = new bvh_node(l, n/2, time0, time1);
109-
right = new bvh_node(l + n/2, n - n/2, time0, time1);
110-
}
99+
bool hit_left = left->hit(r, t_min, t_max, rec);
100+
bool hit_right = right->hit(r, t_min, hit_left ? rec.t : t_max, rec);
111101

112-
aabb box_left, box_right;
102+
return hit_left || hit_right;
103+
}
113104

114-
if ( !left->bounding_box (time0, time1, box_left)
115-
|| !right->bounding_box(time0, time1, box_right)
116-
)
117-
std::cerr << "no bounding box in bvh_node constructor\n";
118105

119-
box = surrounding_box(box_left, box_right);
106+
bool bvh_node::bounding_box(double t0, double t1, aabb& output_box) const {
107+
output_box = box;
108+
return true;
120109
}
121110

111+
122112
#endif

src/TheNextWeek/hittable_list.h

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,56 @@
1111
// along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
1212
//==============================================================================================
1313

14-
#include "common/rtweekend.h"
1514
#include "hittable.h"
15+
#include <vector>
1616

1717

1818
class hittable_list: public hittable {
1919
public:
2020
hittable_list() {}
21-
hittable_list(hittable **l, int n) {list = l; list_size = n; }
21+
hittable_list(hittable* object) { add(object); }
22+
23+
void clear() { objects.clear(); }
24+
void add(hittable* object) { objects.push_back(object); }
25+
2226
virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const;
2327
virtual bool bounding_box(double t0, double t1, aabb& output_box) const;
2428

25-
hittable **list;
26-
int list_size;
29+
public:
30+
std::vector<hittable*> objects;
2731
};
2832

33+
34+
bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
35+
hit_record temp_rec;
36+
auto hit_anything = false;
37+
auto closest_so_far = t_max;
38+
39+
for (auto object : objects) {
40+
if (object->hit(r, t_min, closest_so_far, temp_rec)) {
41+
hit_anything = true;
42+
closest_so_far = temp_rec.t;
43+
rec = temp_rec;
44+
}
45+
}
46+
47+
return hit_anything;
48+
}
49+
50+
2951
bool hittable_list::bounding_box(double t0, double t1, aabb& output_box) const {
30-
if (list_size < 1) return false;
52+
if (objects.empty()) return false;
3153

3254
aabb temp_box;
33-
bool first_true = list[0]->bounding_box(t0, t1, temp_box);
55+
bool first_true = objects[0]->bounding_box(t0, t1, temp_box);
3456

3557
if (!first_true)
3658
return false;
3759
else
3860
output_box = temp_box;
3961

40-
for (int i = 1; i < list_size; i++) {
41-
if (list[i]->bounding_box(t0, t1, temp_box))
62+
for (auto object : objects) {
63+
if (object->bounding_box(t0, t1, temp_box))
4264
output_box = surrounding_box(output_box, temp_box);
4365
else
4466
return false;
@@ -47,19 +69,5 @@ bool hittable_list::bounding_box(double t0, double t1, aabb& output_box) const {
4769
return true;
4870
}
4971

50-
bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
51-
hit_record temp_rec;
52-
bool hit_anything = false;
53-
double closest_so_far = t_max;
54-
55-
for (int i = 0; i < list_size; i++) {
56-
if (list[i]->hit(r, t_min, closest_so_far, temp_rec)) {
57-
hit_anything = true;
58-
closest_so_far = temp_rec.t;
59-
rec = temp_rec;
60-
}
61-
}
62-
return hit_anything;
63-
}
6472

6573
#endif

0 commit comments

Comments
 (0)