diff --git a/RayTracer/tools/AxisAlignedBoundingBox.cpp b/RayTracer/tools/AxisAlignedBoundingBox.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0a541ea8ea3c6e69c3ff363f7a83c15cd6b1c28 --- /dev/null +++ b/RayTracer/tools/AxisAlignedBoundingBox.cpp @@ -0,0 +1,59 @@ +#include "AxisAlignedBoundingBox.h" + +#include <algorithm> +#include <limits> + +namespace util { + +// Constructor +AxisAlignedBoundingBox::AxisAlignedBoundingBox() : min(Vec3(0)), max(Vec3(0)) { +} + +AxisAlignedBoundingBox::AxisAlignedBoundingBox(Vec3& min, Vec3& max) + : min(min), max(max) { +} +// Operator +AxisAlignedBoundingBox AxisAlignedBoundingBox::operator+( + AxisAlignedBoundingBox& rhs) const { + Vec3 min(std::min<float>(min.x(), rhs.min.x()), + std::min<float>(min.y(), rhs.min.y()), + std::min<float>(min.z(), rhs.min.z())); + Vec3 max(std::max<float>(max.x(), rhs.max.x()), + std::max<float>(max.y(), rhs.max.y()), + std::max<float>(max.z(), rhs.max.z())); + + return AxisAlignedBoundingBox(min, max); +} +// Methods +// https://education.siggraph.org/static/HyperGraph/raytrace/rtinter3.htm +bool AxisAlignedBoundingBox::intersects(cam::Ray& r) const { + float t1x = (min.x() - r.x0.x()) / r.d.x(); + float t2x = (max.x() - r.x0.x()) / r.d.x(); + float t1y = (min.y() - r.x0.y()) / r.d.y(); + float t2y = (max.y() - r.x0.y()) / r.d.y(); + float t1z = (min.z() - r.x0.z()) / r.d.z(); + float t2z = (max.z() - r.x0.z()) / r.d.z(); + float tmin = + std::max<float>({std::min<float>(t1x, t2x), std::min<float>(t1y, t2y), + std::min<float>(t1z, t2z)}); + float tmax = + std::min<float>({std::max<float>(t1x, t2x), std::max<float>(t1y, t2y), + std::max<float>(t1z, t2z)}); + + return tmax >= tmin && tmax > 0; +} + +bool AxisAlignedBoundingBox::contains(Vec3& v) const { + bool x = min.x() <= v.x() && v.x() <= max.x(); + bool y = min.y() <= v.y() && v.y() <= max.y(); + bool z = min.z() <= v.z() && v.z() <= max.z(); + + return x && y && z; +} +Vec3 AxisAlignedBoundingBox::minBound() const { + return min; +} +Vec3 AxisAlignedBoundingBox::maxBound() const { + return max; +} +} // namespace util \ No newline at end of file diff --git a/RayTracer/tools/AxisAlignedBoundingBox.h b/RayTracer/tools/AxisAlignedBoundingBox.h new file mode 100644 index 0000000000000000000000000000000000000000..8e758a2b3c2ae2074d276b4c475154e3f6d6fb58 --- /dev/null +++ b/RayTracer/tools/AxisAlignedBoundingBox.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../camera/Ray.h" +#include "Vec3.h" + +namespace util { + +class AxisAlignedBoundingBox { + public: + AxisAlignedBoundingBox(); + AxisAlignedBoundingBox(Vec3& min, Vec3& max); + // Operator + AxisAlignedBoundingBox operator+(AxisAlignedBoundingBox& rhs) const; + // Methods + bool intersects(cam::Ray& r) const; + bool contains(Vec3& v) const; + Vec3 minBound() const; + Vec3 maxBound() const; + + private: + const Vec3 min, max; +}; +} // namespace util \ No newline at end of file