aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2020-12-20 21:59:33 +0100
committerladevieq <ladevie.quentin@gmail.com>2020-12-20 21:59:33 +0100
commitc7c4f8f82c66cfe89b72d176ee51dab8bd30dc95 (patch)
treed0c2caeccda953d86806cb7c7b27c8941e0ef845 /src
parentfc601fd503ec1ebd08e4daffeb9aa0812aff2b71 (diff)
Add hittable interface and hit infos on hit
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/hittable_list.cpp28
-rw-r--r--src/main.cpp32
-rw-r--r--src/ray.cpp2
-rw-r--r--src/sphere.cpp37
-rw-r--r--src/vec3.cpp16
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();
}