]> git.localhorst.tv Git - blank.git/commitdiff
split geometry lib
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 3 Nov 2015 12:06:18 +0000 (13:06 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 3 Nov 2015 12:06:18 +0000 (13:06 +0100)
29 files changed:
src/ai/AIController.hpp
src/ai/ai.cpp
src/client/net.cpp
src/geometry/const.hpp [new file with mode: 0644]
src/geometry/distance.hpp [new file with mode: 0644]
src/geometry/geometry.cpp [new file with mode: 0644]
src/geometry/primitive.hpp [new file with mode: 0644]
src/geometry/rotation.hpp [new file with mode: 0644]
src/graphics/mesh.cpp
src/graphics/viewport.cpp
src/model/Part.hpp
src/model/Shape.hpp
src/model/bounds.hpp
src/model/geometry.cpp [deleted file]
src/model/geometry.hpp [deleted file]
src/net/net.cpp
src/server/net.cpp
src/ui/ui.cpp
src/world/Chunk.hpp
src/world/Entity.hpp
src/world/block.cpp
src/world/chunk.cpp
src/world/world.cpp
tst/geometry/IntersectionTest.cpp [new file with mode: 0644]
tst/geometry/IntersectionTest.hpp [new file with mode: 0644]
tst/model/GeometryTest.cpp [deleted file]
tst/model/GeometryTest.hpp [deleted file]
tst/net/PacketTest.cpp
tst/net/PacketTest.hpp

index 5cbfd0ebc88455a43c434619ac3bd1c52473d0d4..15645a256dd66aa604b70b491214da8e24e1e3c3 100644 (file)
@@ -2,7 +2,7 @@
 #define BLANK_AI_AICONTROLLER_HPP_
 
 #include "../app/IntervalTimer.hpp"
-#include "../model/geometry.hpp"
+#include "../geometry/primitive.hpp"
 #include "../world/EntityController.hpp"
 
 #include <glm/glm.hpp>
index c47b4d3893de5a0483b86033ef16ad3f817f9644..8386c59d174067b65fbcd241765902db023c09c2 100644 (file)
@@ -4,7 +4,8 @@
 #include "IdleState.hpp"
 #include "RoamState.hpp"
 
-#include "../model/geometry.hpp"
+#include "../geometry/distance.hpp"
+#include "../geometry/rotation.hpp"
 #include "../rand/GaloisLFSR.hpp"
 #include "../world/Entity.hpp"
 #include "../world/World.hpp"
index aba3e767421534b9f7dde0b97ba124b68cbb3566..1c13f9e2912c7c79971a5042806079194bf0ab5e 100644 (file)
@@ -4,6 +4,7 @@
 #include "NetworkedInput.hpp"
 
 #include "../app/init.hpp"
+#include "../geometry/distance.hpp"
 #include "../io/WorldSave.hpp"
 #include "../net/Packet.hpp"
 #include "../world/Chunk.hpp"
diff --git a/src/geometry/const.hpp b/src/geometry/const.hpp
new file mode 100644 (file)
index 0000000..00d33e0
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef BLANK_GEOMETRY_CONST_HPP_
+#define BLANK_GEOMETRY_CONST_HPP_
+
+
+namespace blank {
+
+constexpr float PI = 3.141592653589793238462643383279502884;
+constexpr float PI_0p25 = PI * 0.25f;
+constexpr float PI_0p5 = PI * 0.5f;
+constexpr float PI_1p5 = PI * 1.5f;
+constexpr float PI_2p0 = PI * 2.0f;
+
+constexpr float PI_inv = 1.0f / PI;
+constexpr float PI_0p5_inv = 1.0f / PI_0p5;
+
+}
+
+#endif
diff --git a/src/geometry/distance.hpp b/src/geometry/distance.hpp
new file mode 100644 (file)
index 0000000..d4bec9b
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef BLANK_GEOMETRY_DISTANCE_HPP_
+#define BLANK_GEOMETRY_DISTANCE_HPP_
+
+#include <algorithm>
+#include <limits>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+inline float length_squared(const glm::vec3 &v) noexcept {
+       return dot(v, v);
+}
+
+inline float distance_squared(const glm::vec3 &a, const glm::vec3 &b) noexcept {
+       return length_squared(a - b);
+}
+
+template <class T>
+inline bool iszero(const T &v) noexcept {
+       return length_squared(v) < std::numeric_limits<typename T::value_type>::epsilon();
+}
+
+template<class T>
+T manhattan_distance(const glm::tvec3<T> &a, const glm::tvec3<T> &b) noexcept {
+       glm::tvec3<T> diff(abs(a - b));
+       return diff.x + diff.y + diff.z;
+}
+
+template<class T>
+T manhattan_radius(const glm::tvec3<T> &v) noexcept {
+       glm::tvec3<T> a(abs(v));
+       return std::max(a.x, std::max(a.y, a.z));
+}
+
+}
+
+#endif
diff --git a/src/geometry/geometry.cpp b/src/geometry/geometry.cpp
new file mode 100644 (file)
index 0000000..ff28d2e
--- /dev/null
@@ -0,0 +1,214 @@
+#include "const.hpp"
+#include "distance.hpp"
+#include "primitive.hpp"
+#include "rotation.hpp"
+
+#include <limits>
+#include <glm/gtx/matrix_cross_product.hpp>
+#include <glm/gtx/optimum_pow.hpp>
+#include <glm/gtx/transform.hpp>
+
+
+namespace blank {
+
+glm::mat3 find_rotation(const glm::vec3 &a, const glm::vec3 &b) noexcept {
+       glm::vec3 v(cross(a, b));
+       if (iszero(v)) {
+               // a and b are parallel
+               if (iszero(a - b)) {
+                       // a and b are identical
+                       return glm::mat3(1.0f);
+               } else {
+                       // a and b are opposite
+                       // create arbitrary unit vector perpendicular to a and
+                       // rotate 180° around it
+                       glm::vec3 arb(a);
+                       if (std::abs(a.x - 1.0f) > std::numeric_limits<float>::epsilon()) {
+                               arb.x += 1.0f;
+                       } else {
+                               arb.y += 1.0f;
+                       }
+                       glm::vec3 axis(normalize(cross(a, arb)));
+                       return glm::mat3(glm::rotate(PI, axis));
+               }
+       }
+       float mv = length_squared(v);
+       float c = dot(a, b);
+       float f = (1 - c) / mv;
+       glm::mat3 vx(matrixCross3(v));
+       return glm::mat3(1.0f) + vx + (pow2(vx) * f);
+}
+
+bool Intersection(
+       const Ray &ray,
+       const AABB &aabb,
+       const glm::mat4 &M,
+       float *dist,
+       glm::vec3 *normal
+) noexcept {
+       float t_min = 0.0f;
+       float t_max = std::numeric_limits<float>::infinity();
+       const glm::vec3 aabb_pos(M[3].x, M[3].y, M[3].z);
+       const glm::vec3 delta = aabb_pos - ray.orig;
+
+       glm::vec3 t1(t_min, t_min, t_min), t2(t_max, t_max, t_max);
+
+       for (int i = 0; i < 3; ++i) {
+               const glm::vec3 axis(M[i].x, M[i].y, M[i].z);
+               const float e = glm::dot(axis, delta);
+               const float f = glm::dot(axis, ray.dir);
+
+               if (std::abs(f) > std::numeric_limits<float>::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.0f || aabb.max[i] - e < 0.0f) {
+                               return false;
+                       }
+               }
+       }
+
+       glm::vec3 min_all(min(t1, t2));
+
+       if (dist) {
+               *dist = t_min;
+       }
+       if (normal) {
+               if (min_all.x > min_all.y) {
+                       if (min_all.x > min_all.z) {
+                               normal->x = t2.x < t1.x ? 1 : -1;
+                       } else {
+                               normal->z = t2.z < t1.z ? 1 : -1;
+                       }
+               } else if (min_all.y > min_all.z) {
+                       normal->y = t2.y < t1.y ? 1 : -1;
+               } else {
+                       normal->z = t2.z < t1.z ? 1 : -1;
+               }
+       }
+       return true;
+}
+
+
+bool Intersection(
+       const AABB &a_box,
+       const glm::mat4 &a_m,
+       const AABB &b_box,
+       const glm::mat4 &b_m,
+       float &depth,
+       glm::vec3 &normal
+) noexcept {
+       glm::vec3 a_corners[8] = {
+               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.min.y, a_box.min.z, 1)),
+               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.min.y, a_box.max.z, 1)),
+               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.max.y, a_box.min.z, 1)),
+               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.max.y, a_box.max.z, 1)),
+               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.min.y, a_box.min.z, 1)),
+               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.min.y, a_box.max.z, 1)),
+               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.max.y, a_box.min.z, 1)),
+               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.max.y, a_box.max.z, 1)),
+       };
+
+       glm::vec3 b_corners[8] = {
+               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.min.y, b_box.min.z, 1)),
+               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.min.y, b_box.max.z, 1)),
+               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.max.y, b_box.min.z, 1)),
+               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.max.y, b_box.max.z, 1)),
+               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.min.y, b_box.min.z, 1)),
+               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.min.y, b_box.max.z, 1)),
+               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.max.y, b_box.min.z, 1)),
+               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.max.y, b_box.max.z, 1)),
+       };
+
+       glm::vec3 axes[6] = {
+               glm::vec3(a_m * glm::vec4(1, 0, 0, 0)),
+               glm::vec3(a_m * glm::vec4(0, 1, 0, 0)),
+               glm::vec3(a_m * glm::vec4(0, 0, 1, 0)),
+               glm::vec3(b_m * glm::vec4(1, 0, 0, 0)),
+               glm::vec3(b_m * glm::vec4(0, 1, 0, 0)),
+               glm::vec3(b_m * glm::vec4(0, 0, 1, 0)),
+       };
+
+       depth = std::numeric_limits<float>::infinity();
+       int min_axis = 0;
+
+       int cur_axis = 0;
+       for (const glm::vec3 &axis : axes) {
+               float a_min = std::numeric_limits<float>::infinity();
+               float a_max = -std::numeric_limits<float>::infinity();
+               for (const glm::vec3 &corner : a_corners) {
+                       float val = glm::dot(corner, axis);
+                       a_min = std::min(a_min, val);
+                       a_max = std::max(a_max, val);
+               }
+
+               float b_min = std::numeric_limits<float>::infinity();
+               float b_max = -std::numeric_limits<float>::infinity();
+               for (const glm::vec3 &corner : b_corners) {
+                       float val = glm::dot(corner, axis);
+                       b_min = std::min(b_min, val);
+                       b_max = std::max(b_max, val);
+               }
+
+               if (a_max < b_min || b_max < a_min) return false;
+
+               float overlap = std::min(a_max, b_max) - std::max(a_min, b_min);
+               if (overlap < depth) {
+                       depth = overlap;
+                       min_axis = cur_axis;
+               }
+
+               ++cur_axis;
+       }
+
+       normal = axes[min_axis];
+       return true;
+}
+
+
+bool CullTest(const AABB &box, const glm::mat4 &MVP) noexcept {
+       // transform corners into clip space
+       glm::vec4 corners[8] = {
+               { box.min.x, box.min.y, box.min.z, 1.0f },
+               { box.min.x, box.min.y, box.max.z, 1.0f },
+               { box.min.x, box.max.y, box.min.z, 1.0f },
+               { box.min.x, box.max.y, box.max.z, 1.0f },
+               { box.max.x, box.min.y, box.min.z, 1.0f },
+               { box.max.x, box.min.y, box.max.z, 1.0f },
+               { box.max.x, box.max.y, box.min.z, 1.0f },
+               { box.max.x, box.max.y, box.max.z, 1.0f },
+       };
+       for (glm::vec4 &corner : corners) {
+               corner = MVP * corner;
+               corner /= corner.w;
+       }
+
+       int hits[6] = { 0, 0, 0, 0, 0, 0 };
+
+       // check how many corners lie outside
+       for (const glm::vec4 &corner : corners) {
+               if (corner.x >  1.0f) ++hits[0];
+               if (corner.x < -1.0f) ++hits[1];
+               if (corner.y >  1.0f) ++hits[2];
+               if (corner.y < -1.0f) ++hits[3];
+               if (corner.z >  1.0f) ++hits[4];
+               if (corner.z < -1.0f) ++hits[5];
+       }
+
+       // if all corners are outside any given clip plane, the test is true
+       for (int hit : hits) {
+               if (hit == 8) return true;
+       }
+
+       // otherwise the box might still get culled completely, but can't say for sure ;)
+       return false;
+}
+
+}
diff --git a/src/geometry/primitive.hpp b/src/geometry/primitive.hpp
new file mode 100644 (file)
index 0000000..351a3a4
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef BLANK_GEOMETRY_PRIMITIVE_HPP_
+#define BLANK_GEOMETRY_PRIMITIVE_HPP_
+
+#include <algorithm>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+struct AABB {
+       glm::vec3 min;
+       glm::vec3 max;
+
+       void Adjust() noexcept {
+               if (max.x < min.x) std::swap(max.x, min.x);
+               if (max.y < min.y) std::swap(max.y, min.y);
+               if (max.z < min.z) std::swap(max.z, min.z);
+       }
+
+       glm::vec3 Center() const noexcept {
+               return min + (max - min) * 0.5f;
+       }
+};
+
+struct Ray {
+       glm::vec3 orig;
+       glm::vec3 dir;
+};
+
+bool Intersection(
+       const Ray &,
+       const AABB &,
+       const glm::mat4 &M,
+       float *dist = nullptr,
+       glm::vec3 *normal = nullptr) noexcept;
+
+bool Intersection(
+       const AABB &a_box,
+       const glm::mat4 &a_m,
+       const AABB &b_box,
+       const glm::mat4 &b_m,
+       float &depth,
+       glm::vec3 &normal) noexcept;
+
+bool CullTest(const AABB &box, const glm::mat4 &MVP) noexcept;
+
+}
+
+#endif
diff --git a/src/geometry/rotation.hpp b/src/geometry/rotation.hpp
new file mode 100644 (file)
index 0000000..ac208dc
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef BLANK_GEOMETRY_ROTATION_HPP_
+#define BLANK_GEOMETRY_ROTATION_HPP_
+
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+glm::mat3 find_rotation(const glm::vec3 &a, const glm::vec3 &b) noexcept;
+
+}
+
+#endif
index 4a63d99c8f56a2f87612e4dd83748abe90324971..5cd38832174c4f040d56a6f063ea4405bbddeb2f 100644 (file)
@@ -4,7 +4,7 @@
 #include "SkyBoxMesh.hpp"
 #include "SpriteMesh.hpp"
 
-#include "../model/geometry.hpp"
+#include "../geometry/primitive.hpp"
 
 #include <algorithm>
 #include <iostream>
index 9abe48f248261f81e8999a82eff70bc4a87a0010..c46ef28c76fa91bbc6da470615319f69ad75bc73 100644 (file)
@@ -4,7 +4,7 @@
 #include "Viewport.hpp"
 
 #include "../app/init.hpp"
-#include "../model/geometry.hpp"
+#include "../geometry/const.hpp"
 
 #include <GL/glew.h>
 #include <glm/gtc/matrix_transform.hpp>
index 8c1db600244e4d4db37685c5abd3f0b1819c59e5..97743469a85aba210d12d9048a650e2ed6d39f86 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef BLAMK_MODEL_PART_HPP_
 #define BLAMK_MODEL_PART_HPP_
 
-#include "geometry.hpp"
-
 #include <cstdint>
 #include <list>
 #include <memory>
index 9170475b2f6dfc5cd670bec8327368a2a521c1f2..fe58d017510c2cfd1e9da65b265ca52ad1145c8a 100644 (file)
@@ -2,7 +2,7 @@
 #define BLANK_MODEL_SHAPE_HPP_
 
 #include "CollisionBounds.hpp"
-#include "geometry.hpp"
+#include "../geometry/primitive.hpp"
 #include "../graphics/BlockMesh.hpp"
 #include "../graphics/EntityMesh.hpp"
 #include "../world/Block.hpp"
index 3bbb6d798250bb442f84670a38582d51b41751fd..df5f77f66410ef1c43e08701aae15d6883553a3c 100644 (file)
@@ -2,7 +2,7 @@
 #define BLANK_MODEL_BOUNDS_HPP_
 
 #include "CollisionBounds.hpp"
-#include "geometry.hpp"
+#include "../geometry/primitive.hpp"
 
 #include <vector>
 #include <glm/glm.hpp>
diff --git a/src/model/geometry.cpp b/src/model/geometry.cpp
deleted file mode 100644 (file)
index a4ac500..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-#include "geometry.hpp"
-
-#include <limits>
-#include <glm/gtx/matrix_cross_product.hpp>
-#include <glm/gtx/optimum_pow.hpp>
-#include <glm/gtx/transform.hpp>
-
-
-namespace blank {
-
-glm::mat3 find_rotation(const glm::vec3 &a, const glm::vec3 &b) noexcept {
-       glm::vec3 v(cross(a, b));
-       if (iszero(v)) {
-               // a and b are parallel
-               if (iszero(a - b)) {
-                       // a and b are identical
-                       return glm::mat3(1.0f);
-               } else {
-                       // a and b are opposite
-                       // create arbitrary unit vector perpendicular to a and
-                       // rotate 180° around it
-                       glm::vec3 arb(a);
-                       if (std::abs(a.x - 1.0f) > std::numeric_limits<float>::epsilon()) {
-                               arb.x += 1.0f;
-                       } else {
-                               arb.y += 1.0f;
-                       }
-                       glm::vec3 axis(normalize(cross(a, arb)));
-                       return glm::mat3(glm::rotate(PI, axis));
-               }
-       }
-       float mv = length_squared(v);
-       float c = dot(a, b);
-       float f = (1 - c) / mv;
-       glm::mat3 vx(matrixCross3(v));
-       return glm::mat3(1.0f) + vx + (pow2(vx) * f);
-}
-
-bool Intersection(
-       const Ray &ray,
-       const AABB &aabb,
-       const glm::mat4 &M,
-       float *dist,
-       glm::vec3 *normal
-) noexcept {
-       float t_min = 0.0f;
-       float t_max = std::numeric_limits<float>::infinity();
-       const glm::vec3 aabb_pos(M[3].x, M[3].y, M[3].z);
-       const glm::vec3 delta = aabb_pos - ray.orig;
-
-       glm::vec3 t1(t_min, t_min, t_min), t2(t_max, t_max, t_max);
-
-       for (int i = 0; i < 3; ++i) {
-               const glm::vec3 axis(M[i].x, M[i].y, M[i].z);
-               const float e = glm::dot(axis, delta);
-               const float f = glm::dot(axis, ray.dir);
-
-               if (std::abs(f) > std::numeric_limits<float>::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.0f || aabb.max[i] - e < 0.0f) {
-                               return false;
-                       }
-               }
-       }
-
-       glm::vec3 min_all(min(t1, t2));
-
-       if (dist) {
-               *dist = t_min;
-       }
-       if (normal) {
-               if (min_all.x > min_all.y) {
-                       if (min_all.x > min_all.z) {
-                               normal->x = t2.x < t1.x ? 1 : -1;
-                       } else {
-                               normal->z = t2.z < t1.z ? 1 : -1;
-                       }
-               } else if (min_all.y > min_all.z) {
-                       normal->y = t2.y < t1.y ? 1 : -1;
-               } else {
-                       normal->z = t2.z < t1.z ? 1 : -1;
-               }
-       }
-       return true;
-}
-
-
-bool Intersection(
-       const AABB &a_box,
-       const glm::mat4 &a_m,
-       const AABB &b_box,
-       const glm::mat4 &b_m,
-       float &depth,
-       glm::vec3 &normal
-) noexcept {
-       glm::vec3 a_corners[8] = {
-               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.min.y, a_box.min.z, 1)),
-               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.min.y, a_box.max.z, 1)),
-               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.max.y, a_box.min.z, 1)),
-               glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.max.y, a_box.max.z, 1)),
-               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.min.y, a_box.min.z, 1)),
-               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.min.y, a_box.max.z, 1)),
-               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.max.y, a_box.min.z, 1)),
-               glm::vec3(a_m * glm::vec4(a_box.max.x, a_box.max.y, a_box.max.z, 1)),
-       };
-
-       glm::vec3 b_corners[8] = {
-               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.min.y, b_box.min.z, 1)),
-               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.min.y, b_box.max.z, 1)),
-               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.max.y, b_box.min.z, 1)),
-               glm::vec3(b_m * glm::vec4(b_box.min.x, b_box.max.y, b_box.max.z, 1)),
-               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.min.y, b_box.min.z, 1)),
-               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.min.y, b_box.max.z, 1)),
-               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.max.y, b_box.min.z, 1)),
-               glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.max.y, b_box.max.z, 1)),
-       };
-
-       glm::vec3 axes[6] = {
-               glm::vec3(a_m * glm::vec4(1, 0, 0, 0)),
-               glm::vec3(a_m * glm::vec4(0, 1, 0, 0)),
-               glm::vec3(a_m * glm::vec4(0, 0, 1, 0)),
-               glm::vec3(b_m * glm::vec4(1, 0, 0, 0)),
-               glm::vec3(b_m * glm::vec4(0, 1, 0, 0)),
-               glm::vec3(b_m * glm::vec4(0, 0, 1, 0)),
-       };
-
-       depth = std::numeric_limits<float>::infinity();
-       int min_axis = 0;
-
-       int cur_axis = 0;
-       for (const glm::vec3 &axis : axes) {
-               float a_min = std::numeric_limits<float>::infinity();
-               float a_max = -std::numeric_limits<float>::infinity();
-               for (const glm::vec3 &corner : a_corners) {
-                       float val = glm::dot(corner, axis);
-                       a_min = std::min(a_min, val);
-                       a_max = std::max(a_max, val);
-               }
-
-               float b_min = std::numeric_limits<float>::infinity();
-               float b_max = -std::numeric_limits<float>::infinity();
-               for (const glm::vec3 &corner : b_corners) {
-                       float val = glm::dot(corner, axis);
-                       b_min = std::min(b_min, val);
-                       b_max = std::max(b_max, val);
-               }
-
-               if (a_max < b_min || b_max < a_min) return false;
-
-               float overlap = std::min(a_max, b_max) - std::max(a_min, b_min);
-               if (overlap < depth) {
-                       depth = overlap;
-                       min_axis = cur_axis;
-               }
-
-               ++cur_axis;
-       }
-
-       normal = axes[min_axis];
-       return true;
-}
-
-
-bool CullTest(const AABB &box, const glm::mat4 &MVP) noexcept {
-       // transform corners into clip space
-       glm::vec4 corners[8] = {
-               { box.min.x, box.min.y, box.min.z, 1.0f },
-               { box.min.x, box.min.y, box.max.z, 1.0f },
-               { box.min.x, box.max.y, box.min.z, 1.0f },
-               { box.min.x, box.max.y, box.max.z, 1.0f },
-               { box.max.x, box.min.y, box.min.z, 1.0f },
-               { box.max.x, box.min.y, box.max.z, 1.0f },
-               { box.max.x, box.max.y, box.min.z, 1.0f },
-               { box.max.x, box.max.y, box.max.z, 1.0f },
-       };
-       for (glm::vec4 &corner : corners) {
-               corner = MVP * corner;
-               corner /= corner.w;
-       }
-
-       int hits[6] = { 0, 0, 0, 0, 0, 0 };
-
-       // check how many corners lie outside
-       for (const glm::vec4 &corner : corners) {
-               if (corner.x >  1.0f) ++hits[0];
-               if (corner.x < -1.0f) ++hits[1];
-               if (corner.y >  1.0f) ++hits[2];
-               if (corner.y < -1.0f) ++hits[3];
-               if (corner.z >  1.0f) ++hits[4];
-               if (corner.z < -1.0f) ++hits[5];
-       }
-
-       // if all corners are outside any given clip plane, the test is true
-       for (int hit : hits) {
-               if (hit == 8) return true;
-       }
-
-       // otherwise the box might still get culled completely, but can't say for sure ;)
-       return false;
-}
-
-}
diff --git a/src/model/geometry.hpp b/src/model/geometry.hpp
deleted file mode 100644 (file)
index 5065124..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef BLANK_MODEL_GEOMETRY_H_
-#define BLANK_MODEL_GEOMETRY_H_
-
-#include <algorithm>
-#include <limits>
-#include <glm/glm.hpp>
-
-
-namespace blank {
-
-constexpr float PI = 3.141592653589793238462643383279502884;
-constexpr float PI_0p25 = PI * 0.25f;
-constexpr float PI_0p5 = PI * 0.5f;
-constexpr float PI_1p5 = PI * 1.5f;
-constexpr float PI_2p0 = PI * 2.0f;
-
-constexpr float PI_inv = 1.0f / PI;
-constexpr float PI_0p5_inv = 1.0f / PI_0p5;
-
-constexpr float DEG_RAD_FACTOR = PI / 180.0f;
-constexpr float RAD_DEG_FACTOR = 180.0f / PI;
-
-constexpr float deg2rad(float d) noexcept {
-       return d * DEG_RAD_FACTOR;
-}
-
-constexpr float rad2deg(float r) noexcept {
-       return r * RAD_DEG_FACTOR;
-}
-
-
-inline float length_squared(const glm::vec3 &v) noexcept {
-       return dot(v, v);
-}
-
-inline float distance_squared(const glm::vec3 &a, const glm::vec3 &b) noexcept {
-       return length_squared(a - b);
-}
-
-
-template <class T>
-inline bool iszero(const T &v) noexcept {
-       return length_squared(v) < std::numeric_limits<typename T::value_type>::epsilon();
-}
-
-
-template<class T>
-T manhattan_distance(const glm::tvec3<T> &a, const glm::tvec3<T> &b) noexcept {
-       glm::tvec3<T> diff(abs(a - b));
-       return diff.x + diff.y + diff.z;
-}
-
-template<class T>
-T manhattan_radius(const glm::tvec3<T> &v) noexcept {
-       glm::tvec3<T> a(abs(v));
-       return std::max(a.x, std::max(a.y, a.z));
-}
-
-
-glm::mat3 find_rotation(const glm::vec3 &a, const glm::vec3 &b) noexcept;
-
-
-struct AABB {
-       glm::vec3 min;
-       glm::vec3 max;
-
-       void Adjust() noexcept {
-               if (max.x < min.x) std::swap(max.x, min.x);
-               if (max.y < min.y) std::swap(max.y, min.y);
-               if (max.z < min.z) std::swap(max.z, min.z);
-       }
-
-       glm::vec3 Center() const noexcept {
-               return min + (max - min) * 0.5f;
-       }
-};
-
-struct Ray {
-       glm::vec3 orig;
-       glm::vec3 dir;
-};
-
-bool Intersection(
-       const Ray &,
-       const AABB &,
-       const glm::mat4 &M,
-       float *dist = nullptr,
-       glm::vec3 *normal = nullptr) noexcept;
-
-bool Intersection(
-       const AABB &a_box,
-       const glm::mat4 &a_m,
-       const AABB &b_box,
-       const glm::mat4 &b_m,
-       float &depth,
-       glm::vec3 &normal) noexcept;
-
-bool CullTest(const AABB &box, const glm::mat4 &MVP) noexcept;
-
-}
-
-#endif
index 1f4e0a951edd655d08547ad1b4dfad7f696a7503..9130e8ecb8a2b646ee5d5ba0a827aac028a7ced0 100644 (file)
@@ -5,6 +5,7 @@
 #include "Packet.hpp"
 
 #include "../app/init.hpp"
+#include "../geometry/const.hpp"
 #include "../model/Model.hpp"
 #include "../world/Entity.hpp"
 #include "../world/EntityState.hpp"
index aa1bdeb89448c46c757f6a4f47eb283c730ce581..8eba85706de21ae7a703930f0544fe3cf35c26e4 100644 (file)
@@ -3,6 +3,7 @@
 #include "Server.hpp"
 
 #include "../app/init.hpp"
+#include "../geometry/distance.hpp"
 #include "../io/WorldSave.hpp"
 #include "../model/Model.hpp"
 #include "../world/ChunkIndex.hpp"
index f5664dc0f4828b894f80e983b233441c1397ebb7..c45b34b13213cf85dc6317e46e63fecae0abfa2d 100644 (file)
@@ -13,6 +13,7 @@
 #include "../app/init.hpp"
 #include "../audio/Audio.hpp"
 #include "../audio/SoundBank.hpp"
+#include "../geometry/distance.hpp"
 #include "../graphics/Font.hpp"
 #include "../graphics/Viewport.hpp"
 #include "../io/TokenStreamReader.hpp"
@@ -374,8 +375,8 @@ void HUD::UpdatePosition() {
 
 void HUD::UpdateOrientation() {
        std::stringstream s;
-       s << std::setprecision(3) << "pitch: " << rad2deg(player.GetEntity().Pitch())
-               << ", yaw: " << rad2deg(player.GetEntity().Yaw());
+       s << std::setprecision(3) << "pitch: " << glm::degrees(player.GetEntity().Pitch())
+               << ", yaw: " << glm::degrees(player.GetEntity().Yaw());
        orientation_text.Set(env.assets.small_ui_font, s.str());
 }
 
index eaed28a0fd48f727b0274f5cf1f6e6a3f7b20fe0..b6298b3c7d2239e77c86394b1a7bf7d95bf339dc 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "Block.hpp"
 #include "BlockTypeRegistry.hpp"
-#include "../model/geometry.hpp"
+#include "../geometry/primitive.hpp"
 
 #include <vector>
 #include <glm/glm.hpp>
index 802ea90642db422063f33cd23c09f09cf8bd5bcd..4b24944b42b7648e2634daf00087b65284aea4bc 100644 (file)
@@ -3,8 +3,8 @@
 
 #include "Chunk.hpp"
 #include "EntityState.hpp"
+#include "../geometry/primitive.hpp"
 #include "../model/Instance.hpp"
-#include "../model/geometry.hpp"
 
 #include <cstdint>
 #include <string>
index 7050da4cc115532ad643b6d9d40a6a01edbdf5ef..d6e5507ddf5777f1b061dca6e256099d34397c68 100644 (file)
@@ -2,8 +2,6 @@
 #include "BlockType.hpp"
 #include "BlockTypeRegistry.hpp"
 
-#include "../model/geometry.hpp"
-
 #include <ostream>
 #include <glm/gtx/euler_angles.hpp>
 #include <glm/gtx/transform.hpp>
index ef9f578fa3e90dd9c90a1336925e086c1d0b3611..8340d56cd50b1888b6798108fd747d028d3baa37 100644 (file)
@@ -8,6 +8,7 @@
 #include "Generator.hpp"
 #include "WorldCollision.hpp"
 #include "../app/Assets.hpp"
+#include "../geometry/distance.hpp"
 #include "../graphics/BlockLighting.hpp"
 #include "../graphics/BlockMesh.hpp"
 #include "../graphics/Viewport.hpp"
index a17b0cb1f6e2a19f64676f5b575f8f2c11cca8ee..937203190ff1b3879b64a5339f5e540b222e3ff8 100644 (file)
@@ -9,6 +9,8 @@
 #include "EntityCollision.hpp"
 #include "WorldCollision.hpp"
 #include "../app/Assets.hpp"
+#include "../geometry/const.hpp"
+#include "../geometry/distance.hpp"
 #include "../graphics/Format.hpp"
 #include "../graphics/Viewport.hpp"
 
@@ -204,8 +206,8 @@ void Entity::OrientBody(float dt) noexcept {
                                std::cout << "forward:   " << forward << std::endl;
                                std::cout << "facing:    " << facing << std::endl;
                                std::cout << "direction: " << direction << std::endl;
-                               std::cout << "difference: " << rad2deg(relative_difference) << "°" << std::endl;
-                               std::cout << "correction: " << rad2deg(correction) << "°" << std::endl;
+                               std::cout << "difference: " << glm::degrees(relative_difference) << "°" << std::endl;
+                               std::cout << "correction: " << glm::degrees(correction) << "°" << std::endl;
                                std::cout  << std::endl;
                        }
                        // now rotate body by correction and head by -correction
diff --git a/tst/geometry/IntersectionTest.cpp b/tst/geometry/IntersectionTest.cpp
new file mode 100644 (file)
index 0000000..41fb81a
--- /dev/null
@@ -0,0 +1,120 @@
+#include "IntersectionTest.hpp"
+
+#include "geometry/const.hpp"
+#include "geometry/primitive.hpp"
+
+#include <limits>
+#include <glm/gtx/io.hpp>
+#include <glm/gtx/transform.hpp>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::IntersectionTest);
+
+
+namespace blank {
+namespace test {
+
+void IntersectionTest::setUp() {
+}
+
+void IntersectionTest::tearDown() {
+}
+
+
+void IntersectionTest::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::mat4 M(1); // no transformation
+
+       const float delta = std::numeric_limits<float>::epsilon();
+
+       float distance = 0;
+       glm::vec3 normal(0);
+
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray at origin not intersecting box at origin",
+               Intersection(ray, box, M, &distance)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               0.0f, distance, delta
+       );
+       // 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.orig.x = -5;
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing at box doesn't intersect",
+               Intersection(ray, box, M, &distance, &normal)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "intersection distance way off",
+               4.0f, distance, delta
+       );
+       CPPUNIT_ASSERT_EQUAL_MESSAGE(
+               "wrong surface normal at intersection point",
+               glm::vec3(-1, 0, 0), normal
+       );
+
+       // move ray to the other side, so it's pointing away now
+       ray.orig.x = 5;
+       CPPUNIT_ASSERT_MESSAGE(
+               "ray pointing away from box still intersects",
+               !Intersection(ray, box, M)
+       );
+}
+
+void IntersectionTest::testBoxBoxIntersection() {
+       const float delta = std::numeric_limits<float>::epsilon();
+       float depth = 0;
+       glm::vec3 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",
+               Intersection(box, Ma, box, Mb, depth, normal)
+       );
+       // 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.0f, depth, delta
+       );
+
+       Ma = glm::translate(glm::vec3(-2, 0, 0)); // 2 to the left
+       Mb = glm::translate(glm::vec3(2, 0, 0)); // 2 to the right
+       CPPUNIT_ASSERT_MESSAGE(
+               "distant OBBs intersect (2 apart, no rotation)",
+               !Intersection(box, Ma, box, Mb, depth, normal)
+       );
+       // depth and normal undefined for non-intersecting objects
+
+       Ma = glm::rotate(PI_0p25, glm::vec3(0, 0, 1)); // rotated 45° around Z
+       Mb = glm::translate(glm::vec3(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°)",
+               Intersection(box, Ma, box, Mb, depth, normal)
+       );
+       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+               "bad penetration depth (with rotation)",
+               0.01421356237309504880f, depth, delta
+       );
+       CPPUNIT_ASSERT_EQUAL_MESSAGE(
+               "bad intersection normal (with rotation)",
+               glm::vec3(1, 0, 0), abs(normal) // normal can be in + or - x, therefore abs()
+       );
+
+       Mb = glm::translate(glm::vec3(3, 0, 0)); // 3 to the right
+       CPPUNIT_ASSERT_MESSAGE(
+               "OBBs intersect (one rotated by 45°)",
+               !Intersection(box, Ma, box, Mb, depth, normal)
+       );
+}
+
+}
+}
diff --git a/tst/geometry/IntersectionTest.hpp b/tst/geometry/IntersectionTest.hpp
new file mode 100644 (file)
index 0000000..7922290
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef BLANK_TEST_GEOMETRY_INTERSECTIONTEST_H_
+#define BLANK_TEST_GEOMETRY_INTERSECTIONTEST_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+namespace blank {
+namespace test {
+
+class IntersectionTest
+: public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE(IntersectionTest);
+
+CPPUNIT_TEST(testRayBoxIntersection);
+CPPUNIT_TEST(testBoxBoxIntersection);
+
+CPPUNIT_TEST_SUITE_END();
+
+public:
+       void setUp();
+       void tearDown();
+
+       void testRayBoxIntersection();
+       void testBoxBoxIntersection();
+
+};
+
+}
+}
+
+#endif
diff --git a/tst/model/GeometryTest.cpp b/tst/model/GeometryTest.cpp
deleted file mode 100644 (file)
index 82f88ee..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "GeometryTest.hpp"
-
-#include "model/geometry.hpp"
-
-#include <limits>
-#include <glm/gtx/io.hpp>
-#include <glm/gtx/transform.hpp>
-
-CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::GeometryTest);
-
-
-namespace blank {
-namespace test {
-
-void GeometryTest::setUp() {
-}
-
-void GeometryTest::tearDown() {
-}
-
-
-void GeometryTest::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::mat4 M(1); // no transformation
-
-       const float delta = std::numeric_limits<float>::epsilon();
-
-       float distance = 0;
-       glm::vec3 normal(0);
-
-       CPPUNIT_ASSERT_MESSAGE(
-               "ray at origin not intersecting box at origin",
-               Intersection(ray, box, M, &distance)
-       );
-       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
-               "intersection distance way off",
-               0.0f, distance, delta
-       );
-       // 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.orig.x = -5;
-       CPPUNIT_ASSERT_MESSAGE(
-               "ray pointing at box doesn't intersect",
-               Intersection(ray, box, M, &distance, &normal)
-       );
-       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
-               "intersection distance way off",
-               4.0f, distance, delta
-       );
-       CPPUNIT_ASSERT_EQUAL_MESSAGE(
-               "wrong surface normal at intersection point",
-               glm::vec3(-1, 0, 0), normal
-       );
-
-       // move ray to the other side, so it's pointing away now
-       ray.orig.x = 5;
-       CPPUNIT_ASSERT_MESSAGE(
-               "ray pointing away from box still intersects",
-               !Intersection(ray, box, M)
-       );
-}
-
-void GeometryTest::testBoxBoxIntersection() {
-       const float delta = std::numeric_limits<float>::epsilon();
-       float depth = 0;
-       glm::vec3 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",
-               Intersection(box, Ma, box, Mb, depth, normal)
-       );
-       // 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.0f, depth, delta
-       );
-
-       Ma = glm::translate(glm::vec3(-2, 0, 0)); // 2 to the left
-       Mb = glm::translate(glm::vec3(2, 0, 0)); // 2 to the right
-       CPPUNIT_ASSERT_MESSAGE(
-               "distant OBBs intersect (2 apart, no rotation)",
-               !Intersection(box, Ma, box, Mb, depth, normal)
-       );
-       // depth and normal undefined for non-intersecting objects
-
-       Ma = glm::rotate(PI_0p25, glm::vec3(0, 0, 1)); // rotated 45° around Z
-       Mb = glm::translate(glm::vec3(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°)",
-               Intersection(box, Ma, box, Mb, depth, normal)
-       );
-       CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
-               "bad penetration depth (with rotation)",
-               0.01421356237309504880f, depth, delta
-       );
-       CPPUNIT_ASSERT_EQUAL_MESSAGE(
-               "bad intersection normal (with rotation)",
-               glm::vec3(1, 0, 0), abs(normal) // normal can be in + or - x, therefore abs()
-       );
-
-       Mb = glm::translate(glm::vec3(3, 0, 0)); // 3 to the right
-       CPPUNIT_ASSERT_MESSAGE(
-               "OBBs intersect (one rotated by 45°)",
-               !Intersection(box, Ma, box, Mb, depth, normal)
-       );
-}
-
-}
-}
diff --git a/tst/model/GeometryTest.hpp b/tst/model/GeometryTest.hpp
deleted file mode 100644 (file)
index 7ba2d2d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef BLANK_TEST_MODEL_GEOMETRYTEST_H_
-#define BLANK_TEST_MODEL_GEOMETRYTEST_H_
-
-#include <cppunit/extensions/HelperMacros.h>
-
-
-namespace blank {
-namespace test {
-
-class GeometryTest
-: public CppUnit::TestFixture {
-
-CPPUNIT_TEST_SUITE(GeometryTest);
-
-CPPUNIT_TEST(testRayBoxIntersection);
-CPPUNIT_TEST(testBoxBoxIntersection);
-
-CPPUNIT_TEST_SUITE_END();
-
-public:
-       void setUp();
-       void tearDown();
-
-       void testRayBoxIntersection();
-       void testBoxBoxIntersection();
-
-};
-
-}
-}
-
-#endif
index 248bb61e07e7df6ac1aa360e79821f2e2367b1ce..695010dea4db7efb1246dded120ab80e2bb5eef8 100644 (file)
@@ -1,5 +1,6 @@
 #include "PacketTest.hpp"
 
+#include "geometry/const.hpp"
 #include "model/Model.hpp"
 #include "world/Entity.hpp"
 
index 54839acba9ebbc8c50b917c96771d9a9dc09c4fb..25256d9906dc823e6771d55a87306e6b26b524f7 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef BLANK_TEST_NET_PACKETTEST_HPP_
 #define BLANK_TEST_NET_PACKETTEST_HPP_
 
-#include "model/geometry.hpp"
+#include "geometry/primitive.hpp"
 #include "net/Packet.hpp"
 #include "world/EntityState.hpp"