summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2022-01-02 21:07:37 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2022-01-02 21:07:37 +0000
commit7c8b8a39fd36e190578587d8d92f28f460a1fc4b (patch)
tree03c0943bcec657992aa92afb91a3613eb1c8423b
parentNo need to pass GameState around, it has a global pointer (diff)
downloadilt-7c8b8a39fd36e190578587d8d92f28f460a1fc4b.tar.bz2
ilt-7c8b8a39fd36e190578587d8d92f28f460a1fc4b.tar.xz
ilt-7c8b8a39fd36e190578587d8d92f28f460a1fc4b.zip
Encapsulate Ray
-rw-r--r--game/selectable.h4
-rw-r--r--game/vehicles/railVehicle.cpp9
-rw-r--r--game/vehicles/railVehicle.h3
-rw-r--r--game/vehicles/train.cpp6
-rw-r--r--game/vehicles/train.h3
-rw-r--r--gfx/gl/camera.cpp5
-rw-r--r--gfx/gl/camera.h3
-rw-r--r--lib/ray.hpp11
-rw-r--r--test/test-maths.cpp43
-rw-r--r--ui/gameMainWindow.cpp2
10 files changed, 55 insertions, 34 deletions
diff --git a/game/selectable.h b/game/selectable.h
index 0104f3d..3d734f3 100644
--- a/game/selectable.h
+++ b/game/selectable.h
@@ -3,11 +3,13 @@
#include <glm/glm.hpp>
#include <special_members.hpp>
+class Ray;
+
class Selectable {
public:
Selectable() = default;
virtual ~Selectable() = default;
DEFAULT_MOVE_COPY(Selectable);
- [[nodiscard]] virtual bool intersectRay(const glm::vec3 &, const glm::vec3 &, glm::vec2 *, float *) const = 0;
+ [[nodiscard]] virtual bool intersectRay(const Ray &, glm::vec2 *, float *) const = 0;
};
diff --git a/game/vehicles/railVehicle.cpp b/game/vehicles/railVehicle.cpp
index 8d7b06f..9ad1ea7 100644
--- a/game/vehicles/railVehicle.cpp
+++ b/game/vehicles/railVehicle.cpp
@@ -9,6 +9,7 @@
#include <location.hpp>
#include <maths.h>
#include <memory>
+#include <ray.hpp>
void
RailVehicle::render(const Shader & shader) const
@@ -29,7 +30,7 @@ RailVehicle::move(const Train * t, float & trailBy)
}
bool
-RailVehicle::intersectRay(const glm::vec3 & pos, const glm::vec3 & dir, glm::vec2 * baryPos, float * eh) const
+RailVehicle::intersectRay(const Ray & ray, glm::vec2 * baryPos, float * eh) const
{
constexpr const auto X = 1.35F;
const auto Y = this->rvClass->length / 2.F;
@@ -63,8 +64,8 @@ RailVehicle::intersectRay(const glm::vec3 & pos, const glm::vec3 & dir, glm::vec
{3, 6, 7},
}};
return std::any_of(
- triangles.begin(), triangles.end(), [&cornerVertices, &pos, &dir, &baryPos, &eh](const glm::uvec3 idx) {
- return glm::intersectRayTriangle(pos, dir, cornerVertices[idx[0]], cornerVertices[idx[1]],
- cornerVertices[idx[2]], *baryPos, *eh);
+ triangles.begin(), triangles.end(), [&cornerVertices, &ray, &baryPos, &eh](const glm::uvec3 idx) {
+ return glm::intersectRayTriangle(ray.start, ray.direction, cornerVertices[idx[0]],
+ cornerVertices[idx[1]], cornerVertices[idx[2]], *baryPos, *eh);
});
}
diff --git a/game/vehicles/railVehicle.h b/game/vehicles/railVehicle.h
index f52b154..5fbe1ed 100644
--- a/game/vehicles/railVehicle.h
+++ b/game/vehicles/railVehicle.h
@@ -10,6 +10,7 @@
#include <utility>
class Shader;
+class Ray;
class Train;
class RailVehicle : public Renderable, Selectable {
@@ -19,7 +20,7 @@ public:
void move(const Train *, float & trailBy);
void render(const Shader & shader) const override;
- [[nodiscard]] bool intersectRay(const glm::vec3 &, const glm::vec3 &, glm::vec2 *, float *) const override;
+ [[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override;
Location location;
diff --git a/game/vehicles/train.cpp b/game/vehicles/train.cpp
index 4f19bed..05915c4 100644
--- a/game/vehicles/train.cpp
+++ b/game/vehicles/train.cpp
@@ -9,6 +9,8 @@
#include <optional>
#include <utility>
+class Ray;
+
void
Train::render(const Shader & shader) const
{
@@ -24,9 +26,9 @@ Train::getBogiePosition(float linkDist, float dist) const
}
bool
-Train::intersectRay(const glm::vec3 & pos, const glm::vec3 & dir, glm::vec2 * baryPos, float * eh) const
+Train::intersectRay(const Ray & ray, glm::vec2 * baryPos, float * eh) const
{
- return applyOne(&RailVehicle::intersectRay, pos, dir, baryPos, eh) != end();
+ return applyOne(&RailVehicle::intersectRay, ray, baryPos, eh) != end();
}
void
diff --git a/game/vehicles/train.h b/game/vehicles/train.h
index 68f9fbf..0c6a741 100644
--- a/game/vehicles/train.h
+++ b/game/vehicles/train.h
@@ -14,6 +14,7 @@
#include <vector>
class Shader;
+class Ray;
class Train : public Vehicle, public Collection<RailVehicle, false>, public Can<Go>, public Can<Idle> {
public:
@@ -27,7 +28,7 @@ public:
void render(const Shader & shader) const override;
- [[nodiscard]] bool intersectRay(const glm::vec3 &, const glm::vec3 &, glm::vec2 *, float *) const override;
+ [[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override;
void tick(TickDuration elapsed) override;
void doActivity(Go *, TickDuration) override;
diff --git a/gfx/gl/camera.cpp b/gfx/gl/camera.cpp
index 905f78e..c751ba8 100644
--- a/gfx/gl/camera.cpp
+++ b/gfx/gl/camera.cpp
@@ -1,6 +1,7 @@
#include "camera.h"
#include <glm/gtx/transform.hpp> // IWYU pragma: keep
#include <maths.h>
+#include <ray.hpp>
Camera::Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar) :
pos {pos}, forward {::north}, up {::up}, projection {glm::perspective(fov, aspect, zNear, zFar)}
@@ -13,9 +14,9 @@ Camera::GetViewProjection() const
return projection * glm::lookAt(pos, pos + forward, up);
}
-glm::vec3
+Ray
Camera::unProject(const glm::vec2 & mouse) const
{
static constexpr const glm::vec4 screen {0, 0, 1, 1};
- return glm::normalize(glm::unProject(mouse ^ 1, glm::lookAt(::origin, forward, up), projection, screen));
+ return {pos, glm::normalize(glm::unProject(mouse ^ 1, glm::lookAt(::origin, forward, up), projection, screen))};
}
diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h
index 9fbb0a1..b4dd0d5 100644
--- a/gfx/gl/camera.h
+++ b/gfx/gl/camera.h
@@ -1,13 +1,14 @@
#pragma once
#include <glm/glm.hpp>
+#include <ray.hpp>
class Camera {
public:
Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar);
[[nodiscard]] glm::mat4 GetViewProjection() const;
- [[nodiscard]] glm::vec3 unProject(const glm::vec2 &) const;
+ [[nodiscard]] Ray unProject(const glm::vec2 &) const;
glm::vec3 pos;
glm::vec3 forward;
diff --git a/lib/ray.hpp b/lib/ray.hpp
new file mode 100644
index 0000000..4c0710a
--- /dev/null
+++ b/lib/ray.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <glm/glm.hpp>
+
+class Ray {
+public:
+ Ray(glm::vec3 start, glm::vec3 direction) : start {start}, direction {direction} { }
+
+ glm::vec3 start;
+ glm::vec3 direction;
+};
diff --git a/test/test-maths.cpp b/test/test-maths.cpp
index 86cb7b8..1f2a096 100644
--- a/test/test-maths.cpp
+++ b/test/test-maths.cpp
@@ -254,35 +254,36 @@ BOOST_DATA_TEST_CASE(curve1,
BOOST_AUTO_TEST_CASE(camera_clicks)
{
- Camera camera {{0, 0, 0}, ::half_pi, 1.25F, .1F, 10000.F};
+ Camera camera {::origin, ::half_pi, 1.25F, .1F, 10000.F};
constexpr float centre {0.5F}, right {0.9F}, left {0.1F}, top {1.F}, bottom {0.F};
camera.forward = ::north;
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}), ::north);
- BOOST_CHECK_CLOSE_VEC(camera.unProject({left, centre}), glm::normalize(::north + ::west));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({right, centre}), glm::normalize(::north + ::east));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}), glm::normalize(::north + ::up));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, bottom}), glm::normalize(::north + ::down));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({left, top}), glm::normalize(::north + ::west + ::up));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({right, top}), glm::normalize(::north + ::east + ::up));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({left, bottom}), glm::normalize(::north + ::west + ::down));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({right, bottom}), glm::normalize(::north + ::east + ::down));
+ BOOST_CHECK_EQUAL(camera.unProject({centre, centre}).start, ::origin);
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}).direction, ::north);
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({left, centre}).direction, glm::normalize(::north + ::west));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({right, centre}).direction, glm::normalize(::north + ::east));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}).direction, glm::normalize(::north + ::up));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, bottom}).direction, glm::normalize(::north + ::down));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({left, top}).direction, glm::normalize(::north + ::west + ::up));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({right, top}).direction, glm::normalize(::north + ::east + ::up));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({left, bottom}).direction, glm::normalize(::north + ::west + ::down));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({right, bottom}).direction, glm::normalize(::north + ::east + ::down));
camera.forward = ::east;
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}), ::east);
- BOOST_CHECK_CLOSE_VEC(camera.unProject({left, centre}), glm::normalize(::north + ::east));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({right, centre}), glm::normalize(::south + ::east));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}).direction, ::east);
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({left, centre}).direction, glm::normalize(::north + ::east));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({right, centre}).direction, glm::normalize(::south + ::east));
camera.forward = glm::normalize(::north + ::down);
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}), glm::normalize(::north + ::down));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}), glm::normalize(::north));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}).direction, glm::normalize(::north + ::down));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}).direction, glm::normalize(::north));
camera.forward = glm::normalize(::north + ::west + ::down);
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}), glm::normalize(::north + ::west + ::down));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}), glm::normalize(::north + ::west + ::up * 0.2F));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}).direction, glm::normalize(::north + ::west + ::down));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}).direction, glm::normalize(::north + ::west + ::up * 0.2F));
camera.forward = glm::normalize(::north + ::west);
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}), glm::normalize(::north + ::west));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}), glm::normalize(::north + ::west + ::up * 1.2F));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({right, centre}), glm::normalize(::north));
- BOOST_CHECK_CLOSE_VEC(camera.unProject({left, centre}), glm::normalize(::west));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, centre}).direction, glm::normalize(::north + ::west));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({centre, top}).direction, glm::normalize(::north + ::west + ::up * 1.2F));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({right, centre}).direction, glm::normalize(::north));
+ BOOST_CHECK_CLOSE_VEC(camera.unProject({left, centre}).direction, glm::normalize(::west));
}
diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp
index b904388..41bbb39 100644
--- a/ui/gameMainWindow.cpp
+++ b/ui/gameMainWindow.cpp
@@ -52,7 +52,7 @@ public:
float eh;
std::ignore = gameState->world.applyOne<Selectable>(
- &Selectable::intersectRay, camera->pos, camera->unProject(mouse), &baryPos, &eh);
+ &Selectable::intersectRay, camera->unProject(mouse), &baryPos, &eh);
}
}
return false;