]> git.localhorst.tv Git - blobs.git/commitdiff
add ray/box intersect test
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 7 Dec 2017 10:08:11 +0000 (11:08 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 7 Dec 2017 10:08:11 +0000 (11:08 +0100)
src/graphics/viewport.cpp
src/math/const.hpp
src/math/geometry.cpp
src/math/geometry.hpp
src/world/world.cpp
tst/math/IntersectTest.cpp [new file with mode: 0644]
tst/math/IntersectTest.hpp [new file with mode: 0644]
tst/world/OrbitTest.cpp

index 1e7ea4be21f28dfd0e8a38a38594141bfeab5bc8..ff19021f39c09eb9e2886b733569c8f707f9b58c 100644 (file)
@@ -17,7 +17,7 @@ namespace blobs {
 namespace graphics {
 
 Camera::Camera(const world::Body &r) noexcept
-: fov(PI_0p25)
+: fov(PI * 0.25)
 , aspect(1.0f)
 , near(0.1f)
 , far(12560.0f)
index 082cca1cd9dc200f93e9b9159d5eccdb0a6b9db3..8c0acdeaa05f30705e315a1aaf6dc037c8ab5d52 100644 (file)
@@ -5,13 +5,7 @@
 namespace blobs {
 
 constexpr double PI = 3.141592653589793238462643383279502884;
-constexpr double PI_0p25 = PI * 0.25;
-constexpr double PI_0p5 = PI * 0.5;
-constexpr double PI_1p5 = PI * 1.5;
-constexpr double PI_2p0 = PI * 2.0;
-
 constexpr double PI_inv = 1.0 / PI;
-constexpr double PI_0p5_inv = 1.0 / PI_0p5;
 
 /// gravitational constant
 constexpr double G = 6.674e-11; // m³kg¯¹s¯²
index aa0389dac3df5b54d7783440c19f261e2feb1fac..f822ad68e4de3529a14847a6b4d5ab38b5ffeedc 100644 (file)
@@ -94,5 +94,59 @@ bool Intersect(
 }
 
 
+bool Intersect(
+       const Ray &ray,
+       const AABB &aabb,
+       const glm::dmat4 &M,
+       glm::dvec3 &normal,
+       double &dist
+) noexcept {
+       double t_min = 0.0;
+       double t_max = std::numeric_limits<double>::infinity();
+       const glm::dvec3 aabb_pos(M[3].x, M[3].y, M[3].z);
+       const glm::dvec3 delta = aabb_pos - ray.Origin();
+
+       glm::dvec3 t1(t_min, t_min, t_min), t2(t_max, t_max, t_max);
+
+       for (int i = 0; i < 3; ++i) {
+               const glm::dvec3 axis(M[i].x, M[i].y, M[i].z);
+               const double e = glm::dot(axis, delta);
+               const double f = glm::dot(axis, ray.Direction());
+
+               if (std::abs(f) > std::numeric_limits<double>::epsilon()) {
+                       t1[i] = (e + aabb.min[i]) / f;
+                       t2[i] = (e + aabb.max[i]) / f;
+
+                       t_min = std::max(t_min, std::min(t1[i], t2[i]));
+                       t_max = std::min(t_max, std::max(t1[i], t2[i]));
+
+                       if (t_max < t_min) {
+                               return false;
+                       }
+               } else {
+                       if (aabb.min[i] - e > 0.0 || aabb.max[i] - e < 0.0) {
+                               return false;
+                       }
+               }
+       }
+
+       dist = t_min;
+
+       glm::dvec3 min_all(glm::min(t1, t2));
+       if (min_all.x > min_all.y) {
+               if (min_all.x > min_all.z) {
+                       normal = glm::dvec3(t2.x < t1.x ? 1 : -1, 0, 0);
+               } else {
+                       normal = glm::dvec3(0, 0, t2.z < t1.z ? 1 : -1);
+               }
+       } else if (min_all.y > min_all.z) {
+               normal = glm::dvec3(0, t2.y < t1.y ? 1 : -1, 0);
+       } else {
+               normal = glm::dvec3(0, 0, t2.z < t1.z ? 1 : -1);
+       }
+
+       return true;
+}
+
 }
 }
index 4d1b07bbf2f1e93c61f97f5a6fbf685c56f6b724..6410ee013cb622f84879e3788dfd5dee8bb6d720 100644 (file)
@@ -35,6 +35,33 @@ 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;
+
+};
+
+/// oriented ray/box intersection test
+bool Intersect(
+       const Ray &,
+       const AABB &,
+       const glm::dmat4 &M,
+       glm::dvec3 &normal,
+       double &dist) noexcept;
+
 }
 }
 
index 87c85ae7ad413514b6f6958425e12beefa08f3d7..ef9311fbb79022e1f826593dcd3d791c15704f55 100644 (file)
@@ -26,9 +26,6 @@
 #include <glm/gtx/io.hpp>
 #include <glm/gtx/transform.hpp>
 
-using blobs::G;
-using blobs::PI_2p0;
-
 using std::sin;
 using std::cos;
 using std::pow;
@@ -104,7 +101,7 @@ double Body::GravitationalParameter() const noexcept {
 
 double Body::OrbitalPeriod() const noexcept {
        if (parent) {
-               return PI_2p0 * sqrt(pow(orbit.SemiMajorAxis(), 3) / (G * (parent->Mass() + Mass())));
+               return PI * 2.0 * sqrt(pow(orbit.SemiMajorAxis(), 3) / (G * (parent->Mass() + Mass())));
        } else {
                return 0.0;
        }
@@ -114,7 +111,7 @@ double Body::RotationalPeriod() const noexcept {
        if (std::abs(angular) < std::numeric_limits<double>::epsilon()) {
                return std::numeric_limits<double>::infinity();
        } else {
-               return PI_2p0 * Inertia() / angular;
+               return PI * 2.0 * Inertia() / angular;
        }
 }
 
@@ -165,11 +162,11 @@ void Body::Tick(double dt) {
 void Body::Cache() noexcept {
        if (parent) {
                orbital =
-                       orbit.Matrix(PI_2p0 * (GetSimulation().Time() / OrbitalPeriod()))
+                       orbit.Matrix(PI * 2.0 * (GetSimulation().Time() / OrbitalPeriod()))
                        * glm::eulerAngleXY(axis_tilt.x, axis_tilt.y);
                inverse_orbital =
                        glm::eulerAngleYX(-axis_tilt.y, -axis_tilt.x)
-                       * orbit.InverseMatrix(PI_2p0 * (GetSimulation().Time() / OrbitalPeriod()));
+                       * orbit.InverseMatrix(PI * 2.0 * (GetSimulation().Time() / OrbitalPeriod()));
        } else {
                orbital = glm::eulerAngleXY(axis_tilt.x, axis_tilt.y);
                inverse_orbital = glm::eulerAngleYX(-axis_tilt.y, -axis_tilt.x);
diff --git a/tst/math/IntersectTest.cpp b/tst/math/IntersectTest.cpp
new file mode 100644 (file)
index 0000000..dc6667a
--- /dev/null
@@ -0,0 +1,228 @@
+#include "IntersectTest.hpp"
+
+#include "../assert.hpp"
+
+#include "math/const.hpp"
+#include "math/geometry.hpp"
+
+#include <limits>
+#include <glm/gtx/transform.hpp>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(blobs::math::test::IntersectTest);
+
+using blobs::test::AssertEqual;
+
+
+namespace blobs {
+namespace math {
+namespace test {
+
+void IntersectTest::setUp() {
+}
+
+void IntersectTest::tearDown() {
+}
+
+
+void IntersectTest::testRayBoxIntersection() {
+       Ray ray{ { 0, 0, 0 }, { 1, 0, 0 } }; // at origin, pointing right
+       AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
+       glm::dmat4 M(1); // no transformation
+
+       const double delta = 1.0e-15;
+
+       double distance = 0;
+       glm::dvec3 normal(0);
+
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray at origin not intersecting box at origin",
+               Intersect(ray, box, M, normal, distance)
+       );
+       // normal undefined, so can't test
+
+       // move ray outside the box, but have it still point at it
+       // should be 4 units to the left now
+       ray.Origin({ -5, 0, 0 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box to the right doesn't intersect",
+               Intersect(ray, box, M, normal, distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               4.0, distance, delta
+       );
+       AssertEqual(
+               "wrong surface normal at intersection point",
+               glm::dvec3(-1, 0, 0), normal
+       );
+
+       // move ray to the other side, so it's pointing away now
+       ray.Origin({ 5, 0, 0 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing away from box to the left still intersects",
+               !Intersect(ray, box, M, normal, distance)
+       );
+
+       // turn ray around
+       ray.Direction({ -1, 0, 0 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box to the left does not intersect",
+               Intersect(ray, box, M, normal, distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               4.0, distance, delta
+       );
+       AssertEqual(
+               "wrong surface normal at intersection point",
+               glm::dvec3(1, 0, 0), normal
+       );
+
+       // ray below
+       ray.Origin({ 0, -5, 0 });
+       ray.Direction({ 0, 1, 0 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box above does not intersect",
+               Intersect(ray, box, M, normal, distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               4.0, distance, delta
+       );
+       AssertEqual(
+               "wrong surface normal at intersection point",
+               glm::dvec3(0, -1, 0), normal
+       );
+
+       // turn ray around
+       ray.Direction({ 0, -1, 0 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing away from box above still intersects",
+               !Intersect(ray, box, M, normal, distance)
+       );
+
+       // move ray above
+       ray.Origin({ 0, 5, 0 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box below does not intersect",
+               Intersect(ray, box, M, normal, distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               4.0, distance, delta
+       );
+       AssertEqual(
+               "wrong surface normal at intersection point",
+               glm::dvec3(0, 1, 0), normal
+       );
+
+       // ray behind
+       ray.Origin({ 0, 0, -5 });
+       ray.Direction({ 0, 0, 1 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box in front does not intersect",
+               Intersect(ray, box, M, normal, distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               4.0, distance, delta
+       );
+       AssertEqual(
+               "wrong surface normal at intersection point",
+               glm::dvec3(0, 0, -1), normal
+       );
+
+       // turn ray around
+       ray.Direction({ 0, 0, -1 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing away from box in front still intersects",
+               !Intersect(ray, box, M, normal, distance)
+       );
+
+       // move ray in front
+       ray.Origin({ 0, 0, 5 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box behind does not intersect",
+               Intersect(ray, box, M, normal, distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               4.0, distance, delta
+       );
+       AssertEqual(
+               "wrong surface normal at intersection point",
+               glm::dvec3(0, 0, 1), normal
+       );
+
+       // 45 deg down from 4 units away, so should be about 4 * sqrt(2)
+       ray.Origin({ -5, 4.5, 0 });
+       ray.Direction({ 0.70710678118654752440, -0.70710678118654752440, 0 });
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box doesn't intersect",
+               Intersect(ray, box, M, normal, distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               5.65685424949238019520, distance, delta
+       );
+       AssertEqual(
+               "wrong surface normal at intersection point",
+               glm::dvec3(-1, 0, 0), normal
+       );
+}
+
+void IntersectTest::testBoxBoxIntersection() {
+       const double delta = std::numeric_limits<double>::epsilon();
+       double depth = 0;
+       glm::dvec3 normal(0);
+
+       AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
+       glm::mat4 Ma(1); // identity
+       glm::mat4 Mb(1); // identity
+       // they're identical, so should probably intersect ^^
+
+       CPPUNIT_ASSERT_MESSAGE(
+               "identical OBBs don't intersect",
+               Intersect(box, Ma, box, Mb, normal, depth)
+       );
+       // depth is two, but normal can be any
+       // (will probably be the first axis of box a, but any is valid)
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "penetration depth of coincidental 2x2x2 boxes is not 2",
+               2.0, depth, delta
+       );
+
+       Ma = glm::translate(glm::dvec3(-2, 0, 0)); // 2 to the left
+       Mb = glm::translate(glm::dvec3(2, 0, 0)); // 2 to the right
+       CPPUNIT_ASSERT_MESSAGE(
+               "distant OBBs intersect (2 apart, no rotation)",
+               !Intersect(box, Ma, box, Mb, normal, depth)
+       );
+       // depth and normal undefined for non-intersecting objects
+
+       Ma = glm::rotate(PI * 0.25, glm::dvec3(0, 0, 1)); // rotated 45° around Z
+       Mb = glm::translate(glm::dvec3(2.4, 0, 0)); // 2.4 to the right
+       // they should barely touch. intersect by about sqrt(2) - 1.4 if my head works
+       CPPUNIT_ASSERT_MESSAGE(
+               "OBBs don't intersect (one rotated by 45°)",
+               Intersect(box, Ma, box, Mb, normal, depth)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth (with rotation)",
+               0.0142134428024292, depth, delta
+       );
+       AssertEqual(
+               "bad intersection normal (with rotation)",
+               glm::dvec3(1, 0, 0), abs(normal) // normal can be in + or - x, therefore abs()
+       );
+
+       Mb = glm::translate(glm::dvec3(3, 0, 0)); // 3 to the right
+       CPPUNIT_ASSERT_MESSAGE(
+               "OBBs intersect (one rotated by 45°)",
+               !Intersect(box, Ma, box, Mb, normal, depth)
+       );
+}
+
+}
+}
+}
diff --git a/tst/math/IntersectTest.hpp b/tst/math/IntersectTest.hpp
new file mode 100644 (file)
index 0000000..13ac134
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef BLOBS_TEST_MATH_INTERSECTTEST_HPP_
+#define BLOBS_TEST_MATH_INTERSECTTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+namespace blobs {
+namespace math {
+namespace test {
+
+class IntersectTest
+: public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE(IntersectTest);
+
+CPPUNIT_TEST(testRayBoxIntersection);
+CPPUNIT_TEST(testBoxBoxIntersection);
+
+CPPUNIT_TEST_SUITE_END();
+
+public:
+       void setUp();
+       void tearDown();
+
+       void testRayBoxIntersection();
+       void testBoxBoxIntersection();
+
+};
+
+}
+}
+}
+
+#endif
index a7ef6817a7d7eb50c1c2db6eec3bedb65d31a2bd..3becd711371d8b4374795902d3aeb1c761ac1d32 100644 (file)
@@ -59,7 +59,7 @@ void OrbitTest::testDefault() {
 
        // at 90° position should be (0,0,sma) since the zero inclination
        // reference plane is XZ and rotates counter-clockwise
-       pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, -1.0f),
@@ -75,7 +75,7 @@ void OrbitTest::testDefault() {
        );
 
        // at 270° position should be (0,0,-sma)
-       pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 1.0f),
@@ -83,7 +83,7 @@ void OrbitTest::testDefault() {
        );
 
        // at 360° position should be (sma,0,0), the initial position
-       pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(1.0f, 0.0f, 0.0f),
@@ -110,7 +110,7 @@ void OrbitTest::testSMA() {
 
        // at 90° position should be (0,0,sma) since the zero inclination
        // reference plane is XZ and rotates counter-clockwise
-       pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, -2.0f),
@@ -126,7 +126,7 @@ void OrbitTest::testSMA() {
        );
 
        // at 270° position should be (0,0,-sma)
-       pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 2.0f),
@@ -134,7 +134,7 @@ void OrbitTest::testSMA() {
        );
 
        // at 360° position should be (sma,0,0), the initial position
-       pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(2.0f, 0.0f, 0.0f),
@@ -157,7 +157,7 @@ void OrbitTest::testEcc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(-0.935130834579468f, 0.0f, -0.779740869998932f),
@@ -171,14 +171,14 @@ void OrbitTest::testEcc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(-0.935130834579468f, 0.0f, 0.779740869998932f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.5f, 0.0f, 0.0f),
@@ -203,7 +203,7 @@ void OrbitTest::testInc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.70710676908493f, -0.70710676908493f),
@@ -217,14 +217,14 @@ void OrbitTest::testInc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, -0.70710676908493f, 0.70710676908493f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(1.0f, 0.0f, 0.0f),
@@ -251,7 +251,7 @@ void OrbitTest::testLngAsc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 1.0f, 0.0f),
@@ -265,14 +265,14 @@ void OrbitTest::testLngAsc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, -1.0f, 0.0f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f),
@@ -300,7 +300,7 @@ void OrbitTest::testArgPe() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 1.0f, 0.0f),
@@ -314,14 +314,14 @@ void OrbitTest::testArgPe() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, -1.0f, 0.0f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f),
@@ -347,7 +347,7 @@ void OrbitTest::testMnAn() {
 
        // at 90° position should be (0,0,sma) since the zero inclination
        // reference plane is XZ and rotates counter-clockwise
-       pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(-0.70710676908493f, 0.0f, -0.70710676908493f),
@@ -363,7 +363,7 @@ void OrbitTest::testMnAn() {
        );
 
        // at 270° position should be (0,0,-sma)
-       pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f),
@@ -371,7 +371,7 @@ void OrbitTest::testMnAn() {
        );
 
        // at 360° position should be (sma,0,0), the initial position
-       pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f),
@@ -392,7 +392,7 @@ void OrbitTest::testInverseDefault() {
 
        // at 90° position should be (0,0,sma) since the zero inclination
        // reference plane is XZ and rotates counter-clockwise
-       pos = orbit.InverseMatrix(PI_0p5) * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -408,7 +408,7 @@ void OrbitTest::testInverseDefault() {
        );
 
        // at 270° position should be (0,0,-sma)
-       pos = orbit.InverseMatrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -416,7 +416,7 @@ void OrbitTest::testInverseDefault() {
        );
 
        // at 360° position should be (sma,0,0), the initial position
-       pos = orbit.InverseMatrix(PI_2p0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -439,7 +439,7 @@ void OrbitTest::testInverseSMA() {
 
        // at 90° position should be (0,0,sma) since the zero inclination
        // reference plane is XZ and rotates counter-clockwise
-       pos = orbit.InverseMatrix(PI_0p5) * glm::vec4(0.0f, 0.0f, -2.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, -2.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -455,7 +455,7 @@ void OrbitTest::testInverseSMA() {
        );
 
        // at 270° position should be (0,0,-sma)
-       pos = orbit.InverseMatrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 2.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 2.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -463,7 +463,7 @@ void OrbitTest::testInverseSMA() {
        );
 
        // at 360° position should be (sma,0,0), the initial position
-       pos = orbit.InverseMatrix(PI_2p0) * glm::vec4(2.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(2.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -482,7 +482,7 @@ void OrbitTest::testInverseEcc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_0p5) * glm::vec4(-0.935130834579468f, 0.0f, -0.779740869998932f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(-0.935130834579468f, 0.0f, -0.779740869998932f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -496,14 +496,14 @@ void OrbitTest::testInverseEcc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_1p5) * glm::vec4(-0.935130834579468f, 0.0f, 0.779740869998932f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(-0.935130834579468f, 0.0f, 0.779740869998932f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 0.0f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_2p0) * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -524,7 +524,7 @@ void OrbitTest::testInverseInc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_0p5) * glm::vec4(0.0f, 0.70710676908493f, -0.70710676908493f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.70710676908493f, -0.70710676908493f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -538,14 +538,14 @@ void OrbitTest::testInverseInc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_1p5) * glm::vec4(0.0f, -0.70710676908493f, 0.70710676908493f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -0.70710676908493f, 0.70710676908493f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 0.0f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_2p0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -567,7 +567,7 @@ void OrbitTest::testInverseLngAsc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_0p5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -581,14 +581,14 @@ void OrbitTest::testInverseLngAsc() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_1p5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 0.0f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_2p0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -611,7 +611,7 @@ void OrbitTest::testInverseArgPe() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_0p5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -625,14 +625,14 @@ void OrbitTest::testInverseArgPe() {
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_1p5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 0.0f),
                glm::vec3(pos) / pos.w
        );
 
-       pos = orbit.InverseMatrix(PI_2p0) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -654,7 +654,7 @@ void OrbitTest::testInverseMnAn() {
 
        // at 90° position should be (0,0,sma) since the zero inclination
        // reference plane is XZ and rotates counter-clockwise
-       pos = orbit.InverseMatrix(PI_0p5) * glm::vec4(-0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(-0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
        AssertEqual(
                "wrong position at t=90°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -670,7 +670,7 @@ void OrbitTest::testInverseMnAn() {
        );
 
        // at 270° position should be (0,0,-sma)
-       pos = orbit.InverseMatrix(PI_1p5) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
        AssertEqual(
                "wrong position at t=270°",
                glm::vec3(0.0f, 0.0f, 0.0f),
@@ -678,7 +678,7 @@ void OrbitTest::testInverseMnAn() {
        );
 
        // at 360° position should be (sma,0,0), the initial position
-       pos = orbit.InverseMatrix(PI_2p0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
+       pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
        AssertEqual(
                "wrong position at t=360°",
                glm::vec3(0.0f, 0.0f, 0.0f),