From 4d5f0973c6a0ee75fc335038df04c3afbfb7c6cb Mon Sep 17 00:00:00 2001 From: Zach Date: Mon, 5 Feb 2024 14:04:03 -0500 Subject: [PATCH] [bvh]: add an AABB class --- CMakeLists.txt | 1 + include/3d/AABB.cuh | 20 +++++++++++++ include/math/Interval.cuh | 20 ++++++------- include/math/Vec3.cuh | 1 + src/3d/AABB.cu | 63 +++++++++++++++++++++++++++++++++++++++ src/math/Vec3.cu | 9 ++++++ 6 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 include/3d/AABB.cuh create mode 100644 src/3d/AABB.cu diff --git a/CMakeLists.txt b/CMakeLists.txt index 70a9f9a..a75aebd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(LIBRARY_SOURCE_DIR ${CMAKE_SOURCE_DIR}/src) set(LIBRARY_SOURCES + ${LIBRARY_SOURCE_DIR}/3d/AABB.cu ${LIBRARY_SOURCE_DIR}/3d/Camera.cu ${LIBRARY_SOURCE_DIR}/3d/Material.cu ${LIBRARY_SOURCE_DIR}/3d/Object.cu diff --git a/include/3d/AABB.cuh b/include/3d/AABB.cuh new file mode 100644 index 0000000..6cc3431 --- /dev/null +++ b/include/3d/AABB.cuh @@ -0,0 +1,20 @@ +#ifndef AABB_H +#define AABB_H + +#include "Interval.cuh" +#include "Ray.cuh" +#include "Vec3.cuh" + +class AABB { +public: + Interval x, y, z; + + __device__ AABB(); + __device__ AABB(const Interval &_x, const Interval &_y, const Interval &_z); + __device__ AABB(const Point3 &a, const Point3 &b); + + __device__ const Interval &axis(int i) const; + __device__ bool hit(const Ray &r, Interval ray_t) const; +}; + +#endif // AABB_H \ No newline at end of file diff --git a/include/math/Interval.cuh b/include/math/Interval.cuh index 2ad7a80..4b7860a 100644 --- a/include/math/Interval.cuh +++ b/include/math/Interval.cuh @@ -5,27 +5,27 @@ class Interval { public: - float _min; - float _max; + float min; + float max; - __host__ __device__ Interval() : _min(+infinity), _max(-infinity) {} + __host__ __device__ Interval() : min(+infinity), max(-infinity) {} - __host__ __device__ Interval(float min, float max) : _min(min), _max(max) {} + __host__ __device__ Interval(float min, float max) : min(min), max(max) {} __host__ __device__ bool contains(float x) const { - return _min <= x && x <= _max; + return min <= x && x <= max; } __host__ __device__ bool surrounds(float x) const { - return _min < x && x < _max; + return min < x && x < max; } __host__ __device__ float clamp(float x) const { - if (x < _min) - return _min; + if (x < min) + return min; - if (x > _max) - return _max; + if (x > max) + return max; return x; } diff --git a/include/math/Vec3.cuh b/include/math/Vec3.cuh index 54623c9..fde4e84 100644 --- a/include/math/Vec3.cuh +++ b/include/math/Vec3.cuh @@ -19,6 +19,7 @@ public: __device__ Vec3(float x, float y, float z); __device__ void set(float x, float y, float z); + __device__ float get(int i) const; __device__ float length() const; __device__ float lengthSquared() const; diff --git a/src/3d/AABB.cu b/src/3d/AABB.cu new file mode 100644 index 0000000..fa6f80b --- /dev/null +++ b/src/3d/AABB.cu @@ -0,0 +1,63 @@ +#include "AABB.cuh" +#include "Interval.cuh" +#include "Vec3.cuh" + +__device__ AABB::AABB() {} +__device__ AABB::AABB(const Interval &_x, const Interval &_y, + const Interval &_z) + : x(_x), y(_y), z(_z) {} +__device__ AABB::AABB(const Point3 &a, const Point3 &b) { + x = Interval(fmin(a.x, b.x), fmax(a.x, b.x)); + y = Interval(fmin(a.y, b.y), fmax(a.y, b.y)); + z = Interval(fmin(a.z, b.z), fmax(a.z, b.z)); +} + +__device__ const Interval &AABB::axis(int i) const { + if (i == 0) + return x; + if (i == 1) + return y; + /* else */ return z; +} + +__device__ bool AABB::hit(const Ray &r, Interval ray_t) const { + // for (int a = 0; a < 3; a++) { + // auto t0 = fmin((axis(a).min - r.origin.get(a)) / r.direction.get(a), + // (axis(a).max - r.origin.get(a)) / r.direction.get(a)); + // auto t1 = fmax((axis(a).min - r.origin.get(a)) / r.direction.get(a), + // (axis(a).max - r.origin.get(a)) / r.direction.get(a)); + + // ray_t.min = fmax(t0, ray_t.min); + // ray_t.max = fmin(t1, ray_t.max); + + // if (ray_t.max <= ray_t.min) + // return false; + + // return true; + // } + + for (int a = 0; a < 3; a++) { + float inverseDirection = 1.0f / r.direction.get(a); + float origin = r.origin.get(a); + + float t0 = (axis(a).min - origin) * inverseDirection; + float t1 = (axis(a).max - origin) * inverseDirection; + + if (inverseDirection < 0) { + float temp = t0; + t0 = t1; + t1 = temp; + } + + if (t0 > ray_t.min) + ray_t.min = t0; + if (t1 < ray_t.max) + ray_t.max = t1; + + if (ray_t.max <= ray_t.min) { + return false; + } + } + + return true; +} \ No newline at end of file diff --git a/src/math/Vec3.cu b/src/math/Vec3.cu index 8bf024f..9b4d589 100644 --- a/src/math/Vec3.cu +++ b/src/math/Vec3.cu @@ -5,6 +5,15 @@ __device__ Vec3::Vec3() : x(0), y(0), z(0) {} __device__ Vec3::Vec3(float x, float y, float z) : x(x), y(y), z(z) {} +__device__ float Vec3::get(int i) const { + if (i == 0) { + return x; + } + if (i == 1) { + return y; + } + /* else */ return z; +} __device__ void Vec3::set(float x, float y, float z) { this->x = x; this->y = y;