summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2025-03-05 23:52:18 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2025-03-05 23:52:18 +0000
commit4e10d57f83f719e02005fe41e70fe1a4721a9439 (patch)
tree44a7300f97e1a7c09ad560f2176e1c089da6fe20
parentMove camera out of gl folder, it's not OpenGL specific (diff)
downloadilt-4e10d57f83f719e02005fe41e70fe1a4721a9439.tar.bz2
ilt-4e10d57f83f719e02005fe41e70fe1a4721a9439.tar.xz
ilt-4e10d57f83f719e02005fe41e70fe1a4721a9439.zip
Split core view definition out of Camera into Frustum
-rw-r--r--gfx/camera.cpp24
-rw-r--r--gfx/camera.h23
-rw-r--r--gfx/frustum.cpp30
-rw-r--r--gfx/frustum.h31
4 files changed, 76 insertions, 32 deletions
diff --git a/gfx/camera.cpp b/gfx/camera.cpp
index 9e165fa..cc6a2dd 100644
--- a/gfx/camera.cpp
+++ b/gfx/camera.cpp
@@ -4,13 +4,16 @@
#include <maths.h>
#include <ray.h>
-Camera::Camera(GlobalPosition3D pos, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar) :
- position {pos}, forward {::north}, up {::up}, near {zNear}, far {zFar}, view {},
- projection {
- glm::perspective(fov, aspect, static_cast<RelativeDistance>(zNear), static_cast<RelativeDistance>(zFar))},
- viewProjection {}, inverseViewProjection {}
+Camera::Camera(GlobalPosition3D pos, Angle fov, Angle aspect, GlobalDistance near, GlobalDistance far) :
+ Camera {pos, near, far, glm::lookAt({}, ::north, ::up),
+ glm::perspective(fov, aspect, static_cast<RelativeDistance>(near), static_cast<RelativeDistance>(far))}
+{
+}
+
+Camera::Camera(GlobalPosition3D pos, GlobalDistance near, GlobalDistance far, const glm::mat4 & view,
+ const glm::mat4 & projection) :
+ Frustum {view, projection}, position {pos}, forward {::north}, up {::up}, near {near}, far {far}
{
- updateView();
}
Ray<GlobalPosition3D>
@@ -26,14 +29,7 @@ Camera::unProject(const ScreenRelCoord & mouse) const
void
Camera::updateView()
{
- view = glm::lookAt({}, forward, up);
- viewProjection = projection * view;
- inverseViewProjection = glm::inverse(viewProjection);
- static constexpr auto PLANES = std::array {0, 1, 2} * std::array {1.F, -1.F};
- std::ranges::transform(PLANES, frustumPlanes.begin(), [vpt = glm::transpose(viewProjection)](const auto & idxs) {
- const auto [idx, sgn] = idxs;
- return vpt[3] + (vpt[idx] * sgn);
- });
+ Frustum::updateView(glm::lookAt({}, forward, up));
}
Direction3D
diff --git a/gfx/camera.h b/gfx/camera.h
index d4fe6de..a52ec8b 100644
--- a/gfx/camera.h
+++ b/gfx/camera.h
@@ -1,19 +1,14 @@
#pragma once
#include "config/types.h"
+#include "frustum.h"
#include <glm/glm.hpp>
#include <maths.h>
#include <ray.h>
-class Camera {
+class Camera : public Frustum {
public:
- Camera(GlobalPosition3D, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar);
-
- [[nodiscard]] glm::mat4
- getViewProjection() const
- {
- return viewProjection;
- }
+ Camera(GlobalPosition3D position, Angle fov, Angle aspect, GlobalDistance near, GlobalDistance far);
[[nodiscard]] Ray<GlobalPosition3D> unProject(const ScreenRelCoord &) const;
@@ -70,25 +65,17 @@ public:
return position;
}
- [[nodiscard]] auto &
- getFrustumPlanes() const
- {
- return frustumPlanes;
- }
-
[[nodiscard]] std::array<GlobalPosition4D, 4> extentsAtDist(GlobalDistance) const;
[[nodiscard]] static Direction3D upFromForward(const Direction3D & forward);
private:
+ Camera(GlobalPosition3D position, GlobalDistance near, GlobalDistance far, const glm::mat4 & view,
+ const glm::mat4 & projection);
void updateView();
GlobalPosition3D position;
Direction3D forward;
Direction3D up;
-
GlobalDistance near, far;
- glm::mat4 view, projection;
- glm::mat4 viewProjection, inverseViewProjection;
- std::array<glm::vec4, 6> frustumPlanes;
};
diff --git a/gfx/frustum.cpp b/gfx/frustum.cpp
new file mode 100644
index 0000000..9e046f6
--- /dev/null
+++ b/gfx/frustum.cpp
@@ -0,0 +1,30 @@
+#include "frustum.h"
+#include <algorithm>
+#include <collections.h>
+#include <glm/ext/matrix_transform.hpp>
+
+static constexpr auto PLANES = std::array {0, 1, 2} * std::array {1.F, -1.F};
+
+Frustum::Frustum(const glm::mat4 & view, const glm::mat4 & projection) :
+ view {view}, projection {projection}, viewProjection {}, inverseViewProjection {}, planes {}
+{
+ updateCache();
+}
+
+void
+Frustum::updateView(const glm::mat4 & newView)
+{
+ view = newView;
+ updateCache();
+}
+
+void
+Frustum::updateCache()
+{
+ viewProjection = projection * view;
+ inverseViewProjection = glm::inverse(viewProjection);
+ std::ranges::transform(PLANES, planes.begin(), [vpt = glm::transpose(viewProjection)](const auto & idxs) {
+ const auto [idx, sgn] = idxs;
+ return vpt[3] + (vpt[idx] * sgn);
+ });
+}
diff --git a/gfx/frustum.h b/gfx/frustum.h
new file mode 100644
index 0000000..25dcc18
--- /dev/null
+++ b/gfx/frustum.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <array>
+#include <glm/mat4x4.hpp>
+
+class Frustum {
+public:
+ Frustum(const glm::mat4 & view, const glm::mat4 & projection);
+
+ [[nodiscard]] auto &
+ getFrustumPlanes() const
+ {
+ return planes;
+ }
+
+ [[nodiscard]] auto &
+ getViewProjection() const
+ {
+ return viewProjection;
+ }
+
+ void updateView(const glm::mat4 & view);
+
+protected:
+ static constexpr size_t FACES = 6;
+ void updateCache();
+
+ glm::mat4 view, projection;
+ glm::mat4 viewProjection, inverseViewProjection;
+ std::array<glm::vec4, FACES> planes;
+};