summaryrefslogtreecommitdiff
path: root/main_simple_scanner.cpp
diff options
context:
space:
mode:
authorKeuin <[email protected]>2022-04-12 14:52:34 +0800
committerKeuin <[email protected]>2022-04-12 14:52:34 +0800
commitc30f3650287c95742b3674299f4c3e3549db6f5e (patch)
tree342abb2cb515528c5c65807f4621f4a56e1be071 /main_simple_scanner.cpp
parentf626744aa7145c5f2ea406089636428607405f5f (diff)
Refactor: Separate hitlist out from viewport.
Diffstat (limited to 'main_simple_scanner.cpp')
-rw-r--r--main_simple_scanner.cpp46
1 files changed, 29 insertions, 17 deletions
diff --git a/main_simple_scanner.cpp b/main_simple_scanner.cpp
index 2cbe08b..7769c0f 100644
--- a/main_simple_scanner.cpp
+++ b/main_simple_scanner.cpp
@@ -95,13 +95,22 @@ public:
}
};
-class viewport {
- double half_width, half_height; // viewport size
- vec3d center; // coordinate of the viewport center point
- std::vector<std::shared_ptr<object>> objects; // TODO move to world class
+// A world
+class hitlist {
+ std::vector<std::shared_ptr<object>> objects;
+
+public:
+ hitlist() = default;
+
+ hitlist(hitlist &other) = delete; // do not copy the world
- // Given a ray from the camera, generate a color the camera seen on the viewport.
- pixel8b color(const ray3d &r) {
+ // Add an object to the world.
+ void add_object(std::shared_ptr<object> &&obj) {
+ objects.push_back(std::move(obj));
+ }
+
+ // Given a ray, compute the color.
+ pixel8b color(const ray3d &r) const {
// Detect hits
bool hit = false;
double hit_t = std::numeric_limits<double>::infinity();
@@ -134,19 +143,21 @@ class viewport {
);
}
+
+};
+
+class viewport {
+ double half_width, half_height; // viewport size
+ vec3d center; // coordinate of the viewport center point
+
public:
viewport() = delete;
viewport(double width, double height, vec3d viewport_center) :
half_width(width / 2.0), half_height(height / 2.0), center(viewport_center) {}
- // Add an object to the world.
- void add_object(std::shared_ptr<object> &&obj) {
- objects.push_back(std::move(obj));
- }
-
// Generate the image seen on given viewpoint.
- bitmap8b render(vec3d viewpoint, uint16_t image_width, uint16_t image_height) {
+ bitmap8b render(const hitlist &world, vec3d viewpoint, uint16_t image_width, uint16_t image_height) const {
bitmap8b image{image_width, image_height};
const auto r = center - viewpoint;
const int img_hw = image_width / 2, img_hh = image_height / 2;
@@ -160,7 +171,7 @@ public:
}; // offset on screen plane
const auto dir = r + off; // direction vector from camera to current pixel on screen
const ray3d ray{viewpoint, dir}; // from camera to pixel (on the viewport)
- const auto pixel = color(ray);
+ const auto pixel = world.color(ray);
image.set(i + img_hw, -j + img_hh, pixel);
}
}
@@ -172,13 +183,14 @@ void generate_image(uint16_t image_width, uint16_t image_height, double viewport
double sphere_z, double sphere_r, const std::string &caption = "", unsigned caption_scale = 1) {
double r = 1.0 * image_width / image_height;
viewport vp{viewport_width, viewport_width / r, vec3d{0, 0, -focal_length}};
- vp.add_object(std::make_shared<sphere>(
+ hitlist world;
+ world.add_object(std::make_shared<sphere>(
vec3d{0, -100.5, -1},
100)); // the earth
- vp.add_object(std::make_shared<sphere>(vec3d{0, 0, sphere_z}, sphere_r));
+ world.add_object(std::make_shared<sphere>(vec3d{0, 0, sphere_z}, sphere_r));
timer tm;
tm.start_measure();
- auto image = vp.render(vec3d::zero(), image_width, image_height); // camera position as the coordinate origin
+ auto image = vp.render(world, vec3d::zero(), image_width, image_height); // camera position as the coordinate origin
tm.stop_measure();
if (!caption.empty()) {
image.print(caption,
@@ -207,5 +219,5 @@ int main(int argc, char **argv) {
generate_image(image_width, std::stoul(ih),
std::stod(vw), std::stod(fl),
std::stod(sz), std::stod(sr), cap,
- std::max((int)(1.0 * image_width * 0.015 / 8), 1));
+ std::max((int) (1.0 * image_width * 0.015 / 8), 1));
} \ No newline at end of file