diff --git a/Makefile b/Makefile index 6267335..42fe342 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ CXX = g++ CXXFLAGS = -std=c++20 -Wall -Wextra -Wno-unused-parameter -march=native -O3 -flto -fopenmp -DEPS = util.h vec3.h color.h ray.h camera.h hittable.h hittable_list.h sphere.h material.h lodepng.h moving_sphere.h bvh.h aabb.h texture.h -OBJ = main.o material.o vec3.o lodepng.o sphere.o moving_sphere.o bvh.o +DEPS = util.h vec3.h color.h ray.h camera.h hittable.h hittable_list.h sphere.h material.h lodepng.h moving_sphere.h bvh.h aabb.h texture.h aarect.h +OBJ = main.o material.o vec3.o lodepng.o sphere.o moving_sphere.o bvh.o aarect.o TARGET = toytracer diff --git a/aarect.cpp b/aarect.cpp new file mode 100644 index 0000000..49adafe --- /dev/null +++ b/aarect.cpp @@ -0,0 +1,79 @@ +#include "aarect.h" + +bool Xy_rect::bounding_box(double t0, double t1, Aabb& output_box) const { + output_box = Aabb(Point3(x0, y0, k - 0.0001), Point3(x1, y1, k + 0.0001)); + return true; +} + +bool Xz_rect::bounding_box(double t0, double t1, Aabb& output_box) const { + output_box = Aabb(Point3(x0, k - 0.0001, z0), Point3(x1, k + 0.0001, z1)); + return true; +} + +bool Yz_rect::bounding_box(double t0, double t1, Aabb& output_box) const { + output_box = Aabb(Point3(k - 0.0001, y0, z0), Point3(k + 0.0001, y1, z1)); + return true; +} + +bool Xy_rect::hit(const Ray& r, double t0, double t1, hit_record& rec) const { + auto t = (k - r.origin().z()) / r.direction().z(); + if (t < t0 || t > t1) + return false; + + auto x = r.origin().x() + t * r.direction().x(); + auto y = r.origin().y() + t * r.direction().y(); + if (x < x0 || x > x1 || y < y0 || y > y1) + return false; + + rec.u = (x - x0) / (x1 - x0); + rec.v = (y - y0) / (y1 - y0); + rec.t = t; + + auto outward_normal = Vec3(0, 0, 1); + rec.set_face_normal(r, outward_normal); + rec.mat_ptr = mat_ptr; + rec.p = r.at(t); + return true; +} + +bool Xz_rect::hit(const Ray& r, double t0, double t1, hit_record& rec) const { + auto t = (k - r.origin().y()) / r.direction().y(); + if (t < t0 || t > t1) + return false; + + auto x = r.origin().x() + t * r.direction().x(); + auto z = r.origin().z() + t * r.direction().z(); + if (x < x0 || x > x1 || z < z0 || z > z1) + return false; + + rec.u = (x - x0) / (x1 - x0); + rec.v = (z - z0) / (z1 - z0); + rec.t = t; + + auto outward_normal = Vec3(0, 1, 0); + rec.set_face_normal(r, outward_normal); + rec.mat_ptr = mat_ptr; + rec.p = r.at(t); + return true; +} + +bool Yz_rect::hit(const Ray& r, double t0, double t1, hit_record& rec) const { + auto t = (k - r.origin().x()) / r.direction().x(); + if (t < t0 || t > t1) + return false; + + auto y = r.origin().y() + t * r.direction().y(); + auto z = r.origin().z() + t * r.direction().z(); + if (y < y0 || y > y1 || z < z0 || z > z1) + return false; + + rec.u = (y - y0) / (y1 - y0); + rec.v = (z - z0) / (z1 - z0); + rec.t = t; + + auto outward_normal = Vec3(1, 0, 0); + rec.set_face_normal(r, outward_normal); + rec.mat_ptr = mat_ptr; + rec.p = r.at(t); + return true; +} diff --git a/aarect.h b/aarect.h new file mode 100644 index 0000000..16df211 --- /dev/null +++ b/aarect.h @@ -0,0 +1,55 @@ +#ifndef AARECT_H +#define AARECT_H + +#include "hittable.h" +#include "material.h" + +class Xy_rect : public Hittable { + public: + Xy_rect() {} + + Xy_rect(double x0_, double x1_, double y0_, double y1_, double k_, std::shared_ptr mat) + : x0(x0_), x1(x1_), y0(y0_), y1(y1_), k(k_), mat_ptr(mat) {} + + virtual bool hit(const Ray& r, double t0, double t1, hit_record& rec) const; + + virtual bool bounding_box(double t0, double t1, Aabb& output_box) const; + + private: + double x0, x1, y0, y1, k; + std::shared_ptr mat_ptr; +}; + +class Xz_rect : public Hittable { + public: + Xz_rect() {} + + Xz_rect(double x0_, double x1_, double z0_, double z1_, double k_, std::shared_ptr mat) + : x0(x0_), x1(x1_), z0(z0_), z1(z1_), k(k_), mat_ptr(mat) {} + + virtual bool hit(const Ray& r, double t0, double t1, hit_record& rec) const; + + virtual bool bounding_box(double t0, double t1, Aabb& output_box) const; + + private: + double x0, x1, z0, z1, k; + std::shared_ptr mat_ptr; +}; + +class Yz_rect : public Hittable { + public: + Yz_rect() {} + + Yz_rect(double y0_, double y1_, double z0_, double z1_, double k_, std::shared_ptr mat) + : y0(y0_), y1(y1_), z0(z0_), z1(z1_), k(k_), mat_ptr(mat) {} + + virtual bool hit(const Ray& r, double t0, double t1, hit_record& rec) const; + + virtual bool bounding_box(double t0, double t1, Aabb& output_box) const; + + private: + double y0, y1, z0, z1, k; + std::shared_ptr mat_ptr; +}; + +#endif // AARECT_H