]> git.localhorst.tv Git - blobs.git/blob - src/math/geometry.hpp
allow clicking celestial bodies
[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
44 class Ray {
45
46 public:
47         Ray(const glm::dvec3 &orig, const glm::dvec3 &dir)
48         : orig(orig), dir(dir), inv_dir(1.0 / dir) { }
49
50         void Origin(const glm::dvec3 &o) noexcept { orig = o; }
51         const glm::dvec3 &Origin() const noexcept { return orig; }
52         void Direction(const glm::dvec3 &d) noexcept { dir = d; inv_dir = 1.0 / d; }
53         const glm::dvec3 &Direction() const noexcept { return dir; }
54         const glm::dvec3 &InverseDirection() const noexcept { return inv_dir; }
55
56 private:
57         glm::dvec3 orig;
58         glm::dvec3 dir;
59         glm::dvec3 inv_dir;
60
61 };
62
63 inline Ray operator *(const glm::dmat4 &m, const Ray &r) noexcept {
64         glm::dvec4 o(m * glm::dvec4(r.Origin(), 1.0));
65         glm::dvec4 d(m * glm::dvec4(r.Origin() + r.Direction(), 1.0));
66         return Ray(glm::dvec3(o) / o.w, glm::normalize((glm::dvec3(d) / d.w) - (glm::dvec3(o) / o.w)));
67 }
68
69 inline std::ostream &operator <<(std::ostream &out, const Ray &r) {
70         return out << "Ray(" << r.Origin() << ", " << r.Direction() << ")";
71 }
72
73 /// oriented ray/box intersection test
74 bool Intersect(
75         const Ray &,
76         const AABB &,
77         const glm::dmat4 &M,
78         glm::dvec3 &normal,
79         double &dist) noexcept;
80
81
82 struct Sphere {
83
84         glm::dvec3 origin;
85         double radius;
86
87 };
88
89 /// matrix may scale, but only uniformly
90 inline Sphere operator *(const glm::dmat4 &m, const Sphere &s) noexcept {
91         glm::dvec4 o(m * glm::dvec4(s.origin, 1.0));
92         glm::dvec4 p(m * glm::dvec4(s.origin + glm::dvec3(s.radius, 0.0, 0.0), 1.0));
93         return Sphere{glm::dvec3(o) / o.w, glm::length((glm::dvec3(p) / p.w) - (glm::dvec3(o) / o.w))};
94 }
95
96 inline std::ostream &operator <<(std::ostream &out, const Sphere &s) {
97         return out << "Sphere(" << s.origin << ", " << s.radius << ")";
98 }
99
100 /// oriented ray/sphere intersection test
101 bool Intersect(
102         const Ray &,
103         const Sphere &,
104         glm::dvec3 &normal,
105         double &dist) noexcept;
106
107 }
108 }
109
110 #endif