X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fgeometry%2Fgeometry.cpp;h=1d7beeb20777747d500bbebf3e6a1300f60f1fee;hb=refs%2Fheads%2Fmaster;hp=8deed860dc0622825153fd07873240bcac91c0a1;hpb=0e069351615f1315a5c7103fe5c849a242f72683;p=gong.git diff --git a/src/geometry/geometry.cpp b/src/geometry/geometry.cpp index 8deed86..1d7beeb 100644 --- a/src/geometry/geometry.cpp +++ b/src/geometry/geometry.cpp @@ -46,6 +46,16 @@ std::ostream &operator <<(std::ostream &out, const AABB &box) { return out << "AABB(" << box.min << ", " << box.max << ')'; } +bool Intersection(const AABB &a, const AABB &b) noexcept { + if (a.max.x < b.min.x) return false; + if (b.max.x < a.min.x) return false; + if (a.max.y < b.min.y) return false; + if (b.max.y < a.min.y) return false; + if (a.max.z < b.min.z) return false; + if (b.max.z < a.min.z) return false; + return true; +} + std::ostream &operator <<(std::ostream &out, const Ray &ray) { return out << "Ray(" << ray.orig << ", " << ray.dir << ')'; } @@ -217,6 +227,16 @@ std::ostream &operator <<(std::ostream &out, const Plane &plane) { return out << "Plane(" << plane.normal << ", " << plane.dist << ')'; } +float Distance(const glm::vec3 &point, const Plane &plane) { + return std::abs(SignedDistance(point, plane)); +} + +float SignedDistance(const glm::vec3 &point, const Plane &plane) { + return ( + plane.A() * point.x + plane.B() * point.y + plane.C() * point.z + plane.D() + ) / glm::length(plane.normal); +} + std::ostream &operator <<(std::ostream &out, const Frustum &frustum) { return out << "Frustum(" << std::endl << "\tleft: " << frustum.plane[0] << std::endl @@ -277,6 +297,60 @@ bool CullTest(const AABB &box, const Frustum &frustum) noexcept { } return false; } + +std::ostream &operator <<(std::ostream &out, const Sphere &s) { + return out << "Sphere(" << s.origin << ", " << s.radius << ')'; } +bool Intersection( + const Sphere &a, + const Sphere &b, + float &dist, + glm::vec3 &norm +) noexcept { + glm::vec3 diff(b.origin - a.origin); + float dist2 = glm::length2(diff); + if (dist2 < std::numeric_limits::epsilon()) { + // origins coincide, use smaller of the diameters for + // depth and pick arbitrary normal + dist = 2.0f * std::min(a.radius, b.radius); + norm = glm::vec3(1.0f, 0.0f, 0.0f); + return true; + } + if (dist2 < (a.radius + b.radius) * (a.radius + b.radius)) { + dist = std::sqrt(dist2); + norm = diff / dist; + dist = a.radius - (dist - b.radius); + return true; + } else { + return false; + } +} + +bool Intersection( + const Sphere &sphere, + const Plane &plane, + float &dist, + glm::vec3 &norm +) noexcept { + float sig_dist = SignedDistance(sphere.origin, plane); + dist = sphere.radius - std::abs(sig_dist); + if (dist > 0.0f) { + norm = sig_dist > 0.0f ? plane.normal : -plane.normal; + return true; + } else { + return false; + } +} + +bool Intersection( + const Sphere &sphere, + const Plane &plane, + float &dist +) noexcept { + dist = sphere.radius - SignedDistance(sphere.origin, plane); + return dist > 0.0f; +} + +} }