From 8c1324c0742ec92e62805d877c61b8886d52e553 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 21 Aug 2021 00:20:51 +0200 Subject: [PATCH] Midway hittable list inclusion --- Makefile | 2 +- hittable.cpp | 16 ++++++++++++++ hittable.hpp | 25 ++++++++++++++++++++++ hittable_list.hpp | 45 ++++++++++++++++++++++++++++++++++++++++ sphere.hpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++ vec3.hpp | 2 +- 6 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 hittable.cpp create mode 100644 hittable.hpp create mode 100644 hittable_list.hpp create mode 100644 sphere.hpp diff --git a/Makefile b/Makefile index a88ac5c..5f8bbab 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -raytracer: main.cpp vec3.hpp color.hpp ray.hpp +raytracer: main.cpp vec3.hpp color.hpp ray.hpp hittable.hpp sphere.hpp hittable_list.hpp @g++ -g -Wall -Wextra -Wpedantic main.cpp -o raytracer image: raytracer diff --git a/hittable.cpp b/hittable.cpp new file mode 100644 index 0000000..c3b21d4 --- /dev/null +++ b/hittable.cpp @@ -0,0 +1,16 @@ +#ifndef HITTABLE_H +#define HITTABLE_H + +#include "ray.h" + +struct hit_record { + point3 p; + vec3 normal; + double t; +}; + +struct hittable { + virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0; +}; + +#endif diff --git a/hittable.hpp b/hittable.hpp new file mode 100644 index 0000000..42cc05e --- /dev/null +++ b/hittable.hpp @@ -0,0 +1,25 @@ +#ifndef HITTABLE_H +#define HITTABLE_H + +#include "ray.hpp" + +/* Representation of a hitpoint of a ray against a hittable object */ +struct hit_record { + point3 p; + vec3 normal; + double t; + bool front_face; + + inline void set_face_normal(const ray& r, const vec3& outward_normal) + { + front_face = dot(r.direction, outward_normal) < 0; + normal = front_face ? outward_normal : -outward_normal; + } +}; + +/* Virtual class that represents objects who could collide against a ray */ +struct hittable { + virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0; +}; + +#endif diff --git a/hittable_list.hpp b/hittable_list.hpp new file mode 100644 index 0000000..2a5c609 --- /dev/null +++ b/hittable_list.hpp @@ -0,0 +1,45 @@ +#ifndef HITTABLE_LIST_H +#define HITTABLE_LIST_H + +#include "hittable.hpp" + +#include +#include + +using std::shared_ptr; +using std::make_shared; + +struct hittable_list : hittable { + /* Attributes */ + std::vector> objects; + + /* Constructor */ + hittable_list(shared_ptr h) { add(h); } + + /* Methods */ + void clear() { objects.clear(); } + void add (shared_ptr h) { objects.push_back(h); } + + virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const override; +}; + +bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const +{ + hit_record temp_rec; + bool hit_anything = false; + double closest_so_far = t_max; + + for (const auto& object : objects) + { + if (object->hit(r, t_min, closest_so_far, temp_rec)) + { + hit_anything = true; + closest_so_far = temp_rec.t; + rec = temp_rec; + } + } + + return hit_anything; +} + +#endif diff --git a/sphere.hpp b/sphere.hpp new file mode 100644 index 0000000..f92d2ce --- /dev/null +++ b/sphere.hpp @@ -0,0 +1,53 @@ +#ifndef SPHERE_H +#define SPHERE_H + +#include "hittable.hpp" +#include "vec3.hpp" + +struct sphere : hittable { + /* Attributes */ + point3 center; + double radius; + + /* Contructor */ + sphere(point3 c, double r) + { + center = c; + radius = r; + } + + /* Virtual methods declaration */ + virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const override; +}; + +/* Virtual method implementations */ +bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const +{ + vec3 oc = r.origin - center; + double a = r.direction.length_squared(); + double half_b = dot(oc, r.direction); + double c = oc.length_squared() - radius*radius; + + double discriminant = half_b*half_b - a*c; + if (discriminant < 0) + return false; + double sqrtd = sqrt(discriminant); + + // Find the nearest root that lies in the acceptable range + double root = (-half_b - sqrtd) / a; + if (root < t_min || t_max < root) + { + root = (-half_b + sqrtd) / a; + if (root < t_min || t_max < root) + return false; + } + + rec.t = root; + rec.p = r.at(rec.t); + vec3 outward_normal = (rec.p - center) / radius; + rec.set_face_normal(r, outward_normal); + + return true; +} + +#endif diff --git a/vec3.hpp b/vec3.hpp index a841b0d..fbb44f0 100644 --- a/vec3.hpp +++ b/vec3.hpp @@ -21,7 +21,7 @@ struct vec3 { /* Overriden operators */ // - operator. Not to be confused with substraction - vec3 operator-() + vec3 operator-() const { return vec3(-x, -y, -z); }