X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fmath%2Fgeometry.hpp;h=b4a9f50bb43c86c283691a65736f90981b62368a;hb=a19fdf3d9f0d7ecbf6eeeec817856d85049a8336;hp=4d1b07bbf2f1e93c61f97f5a6fbf685c56f6b724;hpb=f5fc0c2bd1c0d1e2737d2b4ed49c3de16aa67c67;p=blobs.git diff --git a/src/math/geometry.hpp b/src/math/geometry.hpp index 4d1b07b..b4a9f50 100644 --- a/src/math/geometry.hpp +++ b/src/math/geometry.hpp @@ -4,6 +4,8 @@ #include "glm.hpp" #include +#include +#include namespace blobs { @@ -26,6 +28,9 @@ struct AABB { }; +inline std::ostream &operator <<(std::ostream &out, const AABB &b) { + return out << "AABB(" << b.min << ", " << b.max << ")"; +} /// matrices must not scale bool Intersect( const AABB &a_box, @@ -35,6 +40,70 @@ bool Intersect( glm::dvec3 &normal, double &depth) noexcept; + +class Ray { + +public: + Ray(const glm::dvec3 &orig, const glm::dvec3 &dir) + : orig(orig), dir(dir), inv_dir(1.0 / dir) { } + + void Origin(const glm::dvec3 &o) noexcept { orig = o; } + const glm::dvec3 &Origin() const noexcept { return orig; } + void Direction(const glm::dvec3 &d) noexcept { dir = d; inv_dir = 1.0 / d; } + const glm::dvec3 &Direction() const noexcept { return dir; } + const glm::dvec3 &InverseDirection() const noexcept { return inv_dir; } + +private: + glm::dvec3 orig; + glm::dvec3 dir; + glm::dvec3 inv_dir; + +}; + +inline Ray operator *(const glm::dmat4 &m, const Ray &r) noexcept { + glm::dvec4 o(m * glm::dvec4(r.Origin(), 1.0)); + glm::dvec4 d(m * glm::dvec4(r.Origin() + r.Direction(), 1.0)); + return Ray(glm::dvec3(o) / o.w, glm::normalize((glm::dvec3(d) / d.w) - (glm::dvec3(o) / o.w))); +} + +inline std::ostream &operator <<(std::ostream &out, const Ray &r) { + return out << "Ray(" << r.Origin() << ", " << r.Direction() << ")"; +} + +/// oriented ray/box intersection test +bool Intersect( + const Ray &, + const AABB &, + const glm::dmat4 &M, + glm::dvec3 &normal, + double &dist) noexcept; + + +struct Sphere { + + glm::dvec3 origin; + double radius; + +}; + +/// matrix may scale, but only uniformly +inline Sphere operator *(const glm::dmat4 &m, const Sphere &s) noexcept { + glm::dvec4 o(m * glm::dvec4(s.origin, 1.0)); + glm::dvec4 p(m * glm::dvec4(s.origin + glm::dvec3(s.radius, 0.0, 0.0), 1.0)); + return Sphere{glm::dvec3(o) / o.w, glm::length((glm::dvec3(p) / p.w) - (glm::dvec3(o) / o.w))}; +} + +inline std::ostream &operator <<(std::ostream &out, const Sphere &s) { + return out << "Sphere(" << s.origin << ", " << s.radius << ")"; +} + +/// oriented ray/sphere intersection test +bool Intersect( + const Ray &, + const Sphere &, + glm::dvec3 &normal, + double &dist) noexcept; + } }