]> git.localhorst.tv Git - gong.git/blobdiff - src/geometry/geometry.cpp
sphere/sphere intersection test
[gong.git] / src / geometry / geometry.cpp
index 1c1bfd61655bf8e2225d681c35984798f400da56..1d7beeb20777747d500bbebf3e6a1300f60f1fee 100644 (file)
@@ -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 << ')';
 }
@@ -292,6 +302,31 @@ 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<float>::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,