X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fmodel%2Fgeometry.cpp;h=e0b55826de35ed58bb05ca441a260a5877f45e86;hb=7e782291e0ce39eb2d4e8c1df28f682c313e6f8d;hp=416d930c4f68d0c24a0f690851264b98556b855b;hpb=b7d09e1e35ef90282c97509e0020b20db3c7ea9f;p=blank.git diff --git a/src/model/geometry.cpp b/src/model/geometry.cpp index 416d930..e0b5582 100644 --- a/src/model/geometry.cpp +++ b/src/model/geometry.cpp @@ -35,7 +35,7 @@ bool Intersection( return false; } } else { - if (aabb.min[i] - e < 0.0f || -aabb.max[i] - e > 0.0f) { + if (aabb.min[i] - e > 0.0f || aabb.max[i] - e < 0.0f) { return false; } } @@ -47,24 +47,98 @@ bool Intersection( *dist = t_min; } if (normal) { - glm::vec4 norm(0.0f); if (min_all.x > min_all.y) { if (min_all.x > min_all.z) { - norm.x = t2.x < t1.x ? 1 : -1; + normal->x = t2.x < t1.x ? 1 : -1; } else { - norm.z = t2.z < t1.z ? 1 : -1; + normal->z = t2.z < t1.z ? 1 : -1; } } else if (min_all.y > min_all.z) { - norm.y = t2.y < t1.y ? 1 : -1; + normal->y = t2.y < t1.y ? 1 : -1; } else { - norm.z = t2.z < t1.z ? 1 : -1; + normal->z = t2.z < t1.z ? 1 : -1; } - norm = M * norm; - *normal = glm::vec3(norm); } return true; } + +bool Intersection( + const AABB &a_box, + const glm::mat4 &a_m, + const AABB &b_box, + const glm::mat4 &b_m, + float &depth, + glm::vec3 &normal +) noexcept { + glm::vec3 a_corners[8] = { + glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.min.y, a_box.min.z, 1)), + glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.min.y, a_box.max.z, 1)), + glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.max.y, a_box.min.z, 1)), + glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.max.y, a_box.max.z, 1)), + glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.min.y, a_box.min.z, 1)), + glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.min.y, a_box.max.z, 1)), + glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.max.y, a_box.min.z, 1)), + glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.max.y, a_box.max.z, 1)), + }; + + glm::vec3 b_corners[8] = { + glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.min.y, b_box.min.z, 1)), + glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.min.y, b_box.max.z, 1)), + glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.max.y, b_box.min.z, 1)), + glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.max.y, b_box.max.z, 1)), + glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.min.y, b_box.min.z, 1)), + glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.min.y, b_box.max.z, 1)), + glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.max.y, b_box.min.z, 1)), + glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.max.y, b_box.max.z, 1)), + }; + + glm::vec3 axes[6] = { + glm::vec3(a_m * glm::vec4(1, 0, 0, 0)), + glm::vec3(a_m * glm::vec4(0, 1, 0, 0)), + glm::vec3(a_m * glm::vec4(0, 0, 1, 0)), + glm::vec3(b_m * glm::vec4(1, 0, 0, 0)), + glm::vec3(b_m * glm::vec4(0, 1, 0, 0)), + glm::vec3(b_m * glm::vec4(0, 0, 1, 0)), + }; + + depth = std::numeric_limits::infinity(); + int min_axis = 0; + + int cur_axis = 0; + for (const glm::vec3 &axis : axes) { + float a_min = std::numeric_limits::infinity(); + float a_max = -std::numeric_limits::infinity(); + for (const glm::vec3 &corner : a_corners) { + float val = glm::dot(corner, axis); + a_min = std::min(a_min, val); + a_max = std::max(a_max, val); + } + + float b_min = std::numeric_limits::infinity(); + float b_max = -std::numeric_limits::infinity(); + for (const glm::vec3 &corner : b_corners) { + float val = glm::dot(corner, axis); + b_min = std::min(b_min, val); + b_max = std::max(b_max, val); + } + + if (a_max < b_min || b_max < a_min) return false; + + float overlap = std::min(a_max, b_max) - std::max(a_min, b_min); + if (overlap < depth) { + depth = overlap; + min_axis = cur_axis; + } + + ++cur_axis; + } + + normal = axes[min_axis]; + return true; +} + + bool CullTest(const AABB &box, const glm::mat4 &MVP) noexcept { // transform corners into clip space glm::vec4 corners[8] = {