diff options
Diffstat (limited to 'gfx')
-rw-r--r-- | gfx/camera.cpp | 24 | ||||
-rw-r--r-- | gfx/camera.h | 23 | ||||
-rw-r--r-- | gfx/frustum.cpp | 30 | ||||
-rw-r--r-- | gfx/frustum.h | 31 |
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; +}; |