X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fmodel%2Fgeometry.cpp;h=a4ac5006d55a019544f122a035af5d98d21cf308;hb=0d580658b896dfec07466c31ae4847455724ee95;hp=b08d59fe5b556ebcdbc680b568cf36358f89a5f7;hpb=0580ff3941fe5f5ea25c96e737edba1541d9271f;p=blank.git diff --git a/src/model/geometry.cpp b/src/model/geometry.cpp index b08d59f..a4ac500 100644 --- a/src/model/geometry.cpp +++ b/src/model/geometry.cpp @@ -1,10 +1,41 @@ #include "geometry.hpp" #include +#include +#include +#include namespace blank { +glm::mat3 find_rotation(const glm::vec3 &a, const glm::vec3 &b) noexcept { + glm::vec3 v(cross(a, b)); + if (iszero(v)) { + // a and b are parallel + if (iszero(a - b)) { + // a and b are identical + return glm::mat3(1.0f); + } else { + // a and b are opposite + // create arbitrary unit vector perpendicular to a and + // rotate 180° around it + glm::vec3 arb(a); + if (std::abs(a.x - 1.0f) > std::numeric_limits::epsilon()) { + arb.x += 1.0f; + } else { + arb.y += 1.0f; + } + glm::vec3 axis(normalize(cross(a, arb))); + return glm::mat3(glm::rotate(PI, axis)); + } + } + float mv = length_squared(v); + float c = dot(a, b); + float f = (1 - c) / mv; + glm::mat3 vx(matrixCross3(v)); + return glm::mat3(1.0f) + vx + (pow2(vx) * f); +} + bool Intersection( const Ray &ray, const AABB &aabb, @@ -47,20 +78,17 @@ 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; } @@ -70,7 +98,9 @@ bool Intersection( const AABB &a_box, const glm::mat4 &a_m, const AABB &b_box, - const glm::mat4 &b_m + 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)), @@ -103,6 +133,10 @@ bool Intersection( 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(); @@ -121,11 +155,17 @@ bool Intersection( } if (a_max < b_min || b_max < a_min) return false; - } - // TODO: find intersection point and normals - // normal could be deduced from the axis with the lowest min? + 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; }