diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2020-12-20 21:59:33 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2020-12-20 21:59:33 +0100 |
| commit | c7c4f8f82c66cfe89b72d176ee51dab8bd30dc95 (patch) | |
| tree | d0c2caeccda953d86806cb7c7b27c8941e0ef845 /src | |
| parent | fc601fd503ec1ebd08e4daffeb9aa0812aff2b71 (diff) | |
Add hittable interface and hit infos on hit
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/hittable_list.cpp | 28 | ||||
| -rw-r--r-- | src/main.cpp | 32 | ||||
| -rw-r--r-- | src/ray.cpp | 2 | ||||
| -rw-r--r-- | src/sphere.cpp | 37 | ||||
| -rw-r--r-- | src/vec3.cpp | 16 |
6 files changed, 88 insertions, 29 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d8b1f6..268dd02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,3 @@ include_directories(${CMAKE_SOURCE_DIR}/include) -add_executable(path-tracer main.cpp vec3.cpp color.cpp ray.cpp) +add_executable(path-tracer main.cpp vec3.cpp color.cpp ray.cpp sphere.cpp hittable_list.cpp) diff --git a/src/hittable_list.cpp b/src/hittable_list.cpp new file mode 100644 index 0000000..9140304 --- /dev/null +++ b/src/hittable_list.cpp @@ -0,0 +1,28 @@ +#include "hittable_list.hpp" + +hittable_list::hittable_list() {}; + +void hittable_list::add(std::shared_ptr<hittable> hittable) { + hittables.push_back(hittable); +} + +void hittable_list::clear() { + hittables.clear(); +} + + +bool hittable_list::hit(const ray& r, double t_min, double t_max, struct hit_info& info) const { + struct hit_info temp_info; + bool hit_anything = false; + double closest_hit = t_max; + + for (auto& hittable: hittables) { + if (hittable->hit(r, t_min, closest_hit, temp_info)) { + hit_anything = true; + closest_hit = temp_info.t; + info = temp_info; + } + } + + return hit_anything; +} diff --git a/src/main.cpp b/src/main.cpp index e2ef071..f6b3012 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,31 +1,22 @@ #include <iostream> -#include "color.hpp" -#include "vec3.hpp" -#include "ray.hpp" +#include "rt.hpp" +#include "hittable_list.hpp" color ground_color { 1.0, 1.0, 1.0 }; color sky_color { 0.5, 0.7, 1.0 }; -bool hit_sphere(const point3& sphere_pos, double sphere_radius, const ray& r) { - // Vector from the ray origin to sphere position - vec3 origin_center = r.origin - sphere_pos; - double a = r.direction.dot(r.direction); - double b = 2.0 * r.direction.dot(origin_center); - double c = origin_center.dot(origin_center) - sphere_radius * sphere_radius; - double discriminant = b * b - 4.0 * a * c; +color ray_color(ray& r, const hittable& world) { + sphere sphere { { 0.0, 0.0, -1.0 }, 0.5 }; - return (discriminant > 0); -} - -color ray_color(ray& r) { auto unit_dir = r.direction.unit(); auto t = (unit_dir.y + 1.0) * 0.5; auto c = lerp(ground_color, sky_color, t); - if (hit_sphere(point3{ 0.0, 0.0, -1.0 }, .5, r)) { - c = color { 1.0, 0.0, 0.0 }; + struct hit_info info; + if (world.hit(r, 0.0, infinity, info)) { + c = 0.5 * (info.normal + vec3{ 1.0, 1.0, 1.0}); } return c; @@ -36,10 +27,11 @@ int main() { const double aspect_ratio = 16.0 / 9.0; const size_t width = 400; const size_t height = width / aspect_ratio; - // const size_t width = 256; - // const size_t height = 256; - // const double aspect_ratio = width / height; + // World hittable objects + hittable_list world {}; + world.add(std::make_shared<sphere>(point3(0,0,-1), 0.5)); + world.add(std::make_shared<sphere>(point3(0,-100.5,-1), 100)); // Viewport dimensions const double viewport_height = 2.0; @@ -78,7 +70,7 @@ int main() { ray ray { eye_pos, direction }; - write_color(std::cout, ray_color(ray)); + write_color(std::cout, ray_color(ray, world)); // write_color(std::cout, color(direction.unit().y, direction.unit().y, direction.unit().y)); // write_color(std::cout, color(y.y, y.y, y.y)); } diff --git a/src/ray.cpp b/src/ray.cpp index 2d479b7..ebf392b 100644 --- a/src/ray.cpp +++ b/src/ray.cpp @@ -3,6 +3,6 @@ ray::ray(const point3& origin, const vec3& direction): origin(origin), direction(direction) {} -point3 ray::at(double t) { +point3 ray::at(double t) const { return origin + direction * t; } diff --git a/src/sphere.cpp b/src/sphere.cpp new file mode 100644 index 0000000..31915a2 --- /dev/null +++ b/src/sphere.cpp @@ -0,0 +1,37 @@ +#include "sphere.hpp" + +sphere::sphere(point3 center, double radius) : center(center), radius(radius) +{} + +bool sphere::hit(const ray& r, double t_min, double t_max, struct hit_info& info) const { + // Vector from the ray origin to sphere position + vec3 origin_center = r.origin - center; + + double a = r.direction.dot(r.direction); + double half_b = r.direction.dot(origin_center); + double c = origin_center.dot(origin_center) - radius * radius; + double discriminant = half_b * half_b - a * c; + + if (discriminant < 0) { + return false; + } + + double sq_discriminant = sqrt(discriminant); + double t = (-half_b - sq_discriminant) / a ; + + if (t_min > t || t_max < t) { + t = (-half_b + sq_discriminant) / a ; + + if (t_min > t || t_max < t) { + return false; + } + } + + info.t = t; + info.point = r.at(t); + + vec3 out_normal = (info.point - center).unit(); + info.set_face_normal(r, out_normal); + + return true; +} diff --git a/src/vec3.cpp b/src/vec3.cpp index fdd8969..b850bfc 100644 --- a/src/vec3.cpp +++ b/src/vec3.cpp @@ -4,10 +4,12 @@ vec3::vec3(): x(0.0), y(0.0), z(0.0) {} vec3::vec3(double x, double y, double z): x(x), y(y), z(z) {} -void vec3::operator-() { - x = -x; - y = -y; - z = -z; +vec3 vec3::operator-() const { + return vec3 { + -x, + -y, + -z + }; } vec3& vec3::operator+=(vec3& vec) { @@ -34,11 +36,11 @@ vec3& vec3::operator/=(double numerator) { return *this; } -double vec3::length() { +double vec3::length() const { return sqrt(length_sq()); } -double vec3::length_sq() { +double vec3::length_sq() const { return x * x + y * y + z * z; } @@ -54,7 +56,7 @@ vec3 vec3::cross(const vec3& vec) const { ); } -vec3 vec3::unit() { +vec3 vec3::unit() const { return *this / length(); } |
