From 73473e772058c223deb0e8a70be3abd84fa0a9a4 Mon Sep 17 00:00:00 2001 From: Keuin Date: Tue, 12 Apr 2022 13:54:52 +0800 Subject: Bugfix: object hit priority is incorrect. Replace unique_ptr with shared_ptr. --- main_simple_scanner.cpp | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/main_simple_scanner.cpp b/main_simple_scanner.cpp index 51870eb..13154e5 100644 --- a/main_simple_scanner.cpp +++ b/main_simple_scanner.cpp @@ -98,21 +98,31 @@ public: class viewport { double half_width, half_height; // viewport size vec3d center; // coordinate of the viewport center point - std::vector> objects; + std::vector> objects; // TODO move to world class // Given a ray from the camera, generate a color the camera seen on the viewport. pixel8b color(const ray3d &r) { // Detect hits - double hit_t; + bool hit = false; + double hit_t = std::numeric_limits::infinity(); + std::shared_ptr hit_obj; + // Check the nearest object we hit for (const auto &obj: objects) { - if (obj->hit(r, hit_t, 0.0)) { - // normal vector on hit point - const auto nv = obj->normal_vector(r.at(hit_t)); -// return obj->color(); - // visualize normal vector at hit point - return pixel8b::from_normalized(nv); + double t_; + if (obj->hit(r, t_, 0.0) && t_ < hit_t) { + hit = true; + hit_t = t_; + hit_obj = obj; } } + if (hit) { + // normal vector on hit point + const auto nv = hit_obj->normal_vector(r.at(hit_t)); +// return obj->color(); + // visualize normal vector at hit point + return pixel8b::from_normalized(nv); + } + // Does not hit anything. Get background color (infinity) const auto u = (r.direction().y + 1.0) * 0.5; @@ -131,7 +141,7 @@ public: half_width(width / 2.0), half_height(height / 2.0), center(viewport_center) {} // Add an object to the world. - void add_object(std::unique_ptr &&obj) { + void add_object(std::shared_ptr &&obj) { objects.push_back(std::move(obj)); } @@ -162,10 +172,10 @@ void generate_image(uint16_t image_width, uint16_t image_height, double viewport double sphere_z, double sphere_r) { double r = 1.0 * image_width / image_height; viewport vp{viewport_width, viewport_width / r, vec3d{0, 0, -focal_length}}; - vp.add_object(std::unique_ptr{new sphere{ + vp.add_object(std::make_shared( vec3d{0, -100.5, -1}, - 100}}); // the earth - vp.add_object(std::unique_ptr{new sphere{vec3d{0, 0, sphere_z}, sphere_r}}); + 100)); // the earth + vp.add_object(std::make_shared(vec3d{0, 0, sphere_z}, sphere_r)); timer tm; tm.start_measure(); const auto image = vp.render(vec3d::zero(), image_width, image_height); // camera position as the coordinate origin -- cgit v1.2.3