]> git.localhorst.tv Git - blobs.git/blob - src/math/geometry.hpp
8f062841fe8adf64b05f6c8a0668f3e8a07adf2f
[blobs.git] / src / math / geometry.hpp
1 #ifndef BLOBS_MATH_GEOMETRY_HPP_
2 #define BLOBS_MATH_GEOMETRY_HPP_
3
4 #include "glm.hpp"
5
6 #include <algorithm>
7 #include <ostream>
8 #include <glm/gtx/io.hpp>
9
10
11 namespace blobs {
12 namespace math {
13
14 struct AABB {
15
16         glm::dvec3 min;
17         glm::dvec3 max;
18
19         void Adjust() noexcept {
20                 if (max.x < min.x) std::swap(max.x, min.x);
21                 if (max.y < min.y) std::swap(max.y, min.y);
22                 if (max.z < min.z) std::swap(max.z, min.z);
23         }
24
25         glm::dvec3 Center() const noexcept {
26                 return min + (max - min) * 0.5;
27         }
28
29 };
30
31 inline std::ostream &operator <<(std::ostream &out, const AABB &b) {
32         return out << "AABB(" << b.min << ", " << b.max << ")";
33 }
34 /// matrices must not scale
35 bool Intersect(
36         const AABB &a_box,
37         const glm::dmat4 &a_m,
38         const AABB &b_box,
39         const glm::dmat4 &b_m,
40         glm::dvec3 &normal,
41         double &depth) noexcept;
42
43 class Ray {
44
45 public:
46         Ray(const glm::dvec3 &orig, const glm::dvec3 &dir)
47         : orig(orig), dir(dir), inv_dir(1.0 / dir) { }
48
49         void Origin(const glm::dvec3 &o) noexcept { orig = o; }
50         const glm::dvec3 &Origin() const noexcept { return orig; }
51         void Direction(const glm::dvec3 &d) noexcept { dir = d; inv_dir = 1.0 / d; }
52         const glm::dvec3 &Direction() const noexcept { return dir; }
53         const glm::dvec3 &InverseDirection() const noexcept { return inv_dir; }
54
55 private:
56         glm::dvec3 orig;
57         glm::dvec3 dir;
58         glm::dvec3 inv_dir;
59
60 };
61
62 inline Ray operator *(const glm::dmat4 &m, const Ray &r) noexcept {
63         glm::dvec4 o(m * glm::dvec4(r.Origin(), 1.0));
64         glm::dvec4 d(m * glm::dvec4(r.Origin() + r.Direction(), 1.0));
65         return Ray(glm::dvec3(o) / o.w, glm::normalize((glm::dvec3(d) / d.w) - (glm::dvec3(o) / o.w)));
66 }
67
68 inline std::ostream &operator <<(std::ostream &out, const Ray &r) {
69         return out << "Ray(" << r.Origin() << ", " << r.Direction() << ")";
70 }
71
72 /// oriented ray/box intersection test
73 bool Intersect(
74         const Ray &,
75         const AABB &,
76         const glm::dmat4 &M,
77         glm::dvec3 &normal,
78         double &dist) noexcept;
79
80 }
81 }
82
83 #endif