X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fgeometry.cpp;h=df48ad3deac2c440f66d89f8fb69e69aac1e9b88;hb=8881c507009521d08648560984c0f50166224542;hp=c5f806997fae8cee4d9e26311ec0067dd607e808;hpb=4d0ef1687987a0801469c7262f81efd36636605a;p=blank.git diff --git a/src/geometry.cpp b/src/geometry.cpp index c5f8069..df48ad3 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -1,31 +1,43 @@ #include "geometry.hpp" +#include + namespace blank { -bool Intersection(const Ray &ray, const AABB &aabb, const glm::mat4 &M, float *dist) { +bool Intersection( + const Ray &ray, + const AABB &aabb, + const glm::mat4 &M, + float *dist, + glm::vec3 *normal +) { float t_min = 0.0f; float t_max = 1.0e5f; const glm::vec3 aabb_pos(M[3].x, M[3].y, M[3].z); const glm::vec3 delta = aabb_pos - ray.orig; + glm::vec3 t1(t_min, t_min, t_min), t2(t_max, t_max, t_max); + bool x_swap = false, y_swap = false, z_swap = false; + { // X const glm::vec3 xaxis(M[0].x, M[0].y, M[0].z); const float e = glm::dot(xaxis, delta); const float f = glm::dot(ray.dir, xaxis); - if (std::abs(f) > 0.001f) { - float t1 = (e + aabb.min.x) / f; - float t2 = (e + aabb.max.x) / f; + if (std::abs(f) > std::numeric_limits::epsilon()) { + t1.x = (e + aabb.min.x) / f; + t2.x = (e + aabb.max.x) / f; - if (t1 > t2) { - std::swap(t1, t2); + if (t1.x > t2.x) { + std::swap(t1.x, t2.x); + x_swap = true; } - if (t1 > t_min) { - t_min = t1; + if (t1.x > t_min) { + t_min = t1.x; } - if (t2 < t_max) { - t_max = t2; + if (t2.x < t_max) { + t_max = t2.x; } if (t_max < t_min) { return false; @@ -42,18 +54,19 @@ bool Intersection(const Ray &ray, const AABB &aabb, const glm::mat4 &M, float *d const float e = glm::dot(yaxis, delta); const float f = glm::dot(ray.dir, yaxis); - if (std::abs(f) > 0.001f) { - float t1 = (e + aabb.min.y) / f; - float t2 = (e + aabb.max.y) / f; + if (std::abs(f) > std::numeric_limits::epsilon()) { + t1.y = (e + aabb.min.y) / f; + t2.y = (e + aabb.max.y) / f; - if (t1 > t2) { - std::swap(t1, t2); + if (t1.y > t2.y) { + std::swap(t1.y, t2.y); + y_swap = true; } - if (t1 > t_min) { - t_min = t1; + if (t1.y > t_min) { + t_min = t1.y; } - if (t2 < t_max) { - t_max = t2; + if (t2.y < t_max) { + t_max = t2.y; } if (t_max < t_min) { return false; @@ -70,18 +83,19 @@ bool Intersection(const Ray &ray, const AABB &aabb, const glm::mat4 &M, float *d const float e = glm::dot(zaxis, delta); const float f = glm::dot(ray.dir, zaxis); - if (std::abs(f) > 0.001f) { - float t1 = (e + aabb.min.z) / f; - float t2 = (e + aabb.max.z) / f; + if (std::abs(f) > std::numeric_limits::epsilon()) { + t1.z = (e + aabb.min.z) / f; + t2.z = (e + aabb.max.z) / f; - if (t1 > t2) { - std::swap(t1, t2); + if (t1.z > t2.z) { + std::swap(t1.z, t2.z); + z_swap = true; } - if (t1 > t_min) { - t_min = t1; + if (t1.z > t_min) { + t_min = t1.z; } - if (t2 < t_max) { - t_max = t2; + if (t2.z < t_max) { + t_max = t2.z; } if (t_max < t_min) { return false; @@ -96,6 +110,19 @@ bool Intersection(const Ray &ray, const AABB &aabb, const glm::mat4 &M, float *d if (dist) { *dist = t_min; } + if (normal) { + if (t1.x > t1.y) { + if (t1.x > t1.z) { + *normal = glm::vec3(x_swap ? 1 : -1, 0, 0); + } else { + *normal = glm::vec3(0, 0, z_swap ? 1 : -1); + } + } else if (t1.y > t1.z) { + *normal = glm::vec3(0, y_swap ? 1 : -1, 0); + } else { + *normal = glm::vec3(0, 0, z_swap ? 1 : -1); + } + } return true; }