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