From 3ce9ce8e3b1080e2ff5268b9dadb62ed0fb5c6b9 Mon Sep 17 00:00:00 2001 From: GeorgH93 Date: Sat, 22 May 2021 18:55:55 +0200 Subject: [PATCH] Update camera class --- openVulkanoCpp/Scene/Camera.hpp | 350 ++++++++++++++++---------------- 1 file changed, 172 insertions(+), 178 deletions(-) diff --git a/openVulkanoCpp/Scene/Camera.hpp b/openVulkanoCpp/Scene/Camera.hpp index 8d2a004..6ef0b4c 100644 --- a/openVulkanoCpp/Scene/Camera.hpp +++ b/openVulkanoCpp/Scene/Camera.hpp @@ -9,190 +9,184 @@ #include "Node.hpp" #include "Math/Math.hpp" -namespace openVulkanoCpp +namespace openVulkanoCpp::Scene { - namespace Scene + class Camera : public Node { - class Camera : public Node + protected: + + Math::Matrix4f viewProjection{1}, view{1}, projection{1}; + Math::Vector4f camPosition{}; + float nearPlane, farPlane, width, height; + + Camera() : nearPlane(0), farPlane(0), width(0), height(0) {} + + Camera(float width, float height, float nearPlane, float farPlane) + : nearPlane(nearPlane), farPlane(farPlane), width(width), height(height) { - protected: - float width, height, nearPlane, farPlane; + } - Math::Matrix4f viewProjection, view, projection; - Math::Vector4f camPosition; + ~Camera() override = default; - Camera() : width(0), height(0), nearPlane(0), farPlane(0), viewProjection(1), view(1), projection(1) {} - - Camera(float width, float height, float nearPlane, float farPlane) - : width(width), height(height), nearPlane(nearPlane), farPlane(farPlane) - , viewProjection(1), view(1), projection(1) - { - } - - ~Camera() override = default; - - public: - void Init(float nearPlane, float farPlane) - { - Init(16, 9, farPlane, nearPlane); - } - - void Init(float width, float height, float nearPlane, float farPlane) - { - this->width = width; - this->height = height; - this->nearPlane = nearPlane; - this->farPlane = farPlane; - Node::Init(); - UpdateProjectionMatrix(); - } - - virtual void SetSize(const float width, const float height) - { - if (this->width == width && this->height == height) return; - this->width = width; - this->height = height; - UpdateProjectionMatrix(); - } - - void SetNearPlane(float nearPlane) - { - this->nearPlane = nearPlane; - } - - void SetFarPlane(float farPlane) - { - this->farPlane = farPlane; - } - - - [[nodiscard]] float NearPlane() const - { - return nearPlane; - } - - [[nodiscard]] float FarPlane() const - { - return farPlane; - } - - virtual void UpdateProjectionMatrix() = 0; - - void UpdateViewProjectionMatrix() - { // In vulkan the screen space is defined as y=0=top and y=1=bottom and thus the coordinate have to be flipped - viewProjection = projection * Math::Matrix4f(1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1) * view; - } - - void UpdateWorldMatrix(const Math::Matrix4f& parentWorldMat) override - { - Node::UpdateWorldMatrix(parentWorldMat); - view = Math::Utils::inverse(GetWorldMatrix()); - camPosition = GetWorldMatrix()[3]; - UpdateViewProjectionMatrix(); - } - - [[nodiscard]] const Math::Matrix4f& GetViewProjectionMatrix() const - { - return viewProjection; - } - }; - - class PerspectiveCamera : public Camera + public: + void Init(float width, float height, float nearPlane, float farPlane) { - protected: - float fov = 0, aspect = 0; + this->width = width; + this->height = height; + this->nearPlane = nearPlane; + this->farPlane = farPlane; + Node::Init(); + UpdateProjectionMatrix(); + } - public: - PerspectiveCamera() = default; - ~PerspectiveCamera() override = default; - - PerspectiveCamera(float fovDegrees, float nearPlane = 0.1f, float farPlane = 1000.0f, float width = 16, float height = 9) - : Camera() - { - Init(fovDegrees, width, height, nearPlane, farPlane); - PerspectiveCamera::UpdateProjectionMatrix(); - } - - void Init(float fovDegrees, float nearPlane, float farPlane) - { - Init(fovDegrees, 16, 9, nearPlane, farPlane); - } - - void Init(float fovDegrees, float width, float height, float nearPlane, float farPlane) - { - this->fov = Math::Utils::radians(fovDegrees); - aspect = width / height; - Camera::Init(width, height, nearPlane, farPlane); - } - - void SetSize(const float width, const float height) override - { - aspect = width / height; - Camera::SetSize(width, height); - } - - void SetAspect(const float aspect) - { - this->aspect = aspect; - Camera::SetSize(aspect, 1); - } - - void SetFovX(const float fov) - { - SetFov(2 * atan(tan(fov * 0.5f) * aspect)); - } - - void SetFovXRad(const float fov) - { - SetFovRad(2 * atan(tan(fov * 0.5f) * aspect)); - } - - void SetFov(const float fov) - { - SetFovRad(Math::Utils::radians(fov)); - } - - void SetFovRad(const float fov) - { - this->fov = fov; - } - - [[nodiscard]] float GetFov() const - { - return Math::Utils::degrees(fov); - } - - [[nodiscard]] float GetFovX() const - { - return 2.0f * atanf(tanf(GetFov() * 0.5f) * aspect); - } - - [[nodiscard]] float GetFovRad() const - { - return fov; - } - - [[nodiscard]] float GetFovXRad() const - { - return 2.0f * atanf(tanf(fov * 0.5f) * aspect); - } - - void UpdateProjectionMatrix() override - { - projection = Math::Utils::perspectiveRH_ZO(fov, aspect, nearPlane, farPlane); - UpdateViewProjectionMatrix(); - } - }; - - class OrthographicCamera : public Camera + virtual void SetSize(const float width, const float height) { - public: - void UpdateProjectionMatrix() override - { - const float widthHalf = width * 0.5f, heightHalf = height * 0.5f; - projection = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, nearPlane, farPlane); - UpdateViewProjectionMatrix(); - } - }; - } + if (this->width == width && this->height == height) return; + this->width = width; + this->height = height; + UpdateProjectionMatrix(); + } + + void SetNearPlane(float nearPlane) + { + this->nearPlane = nearPlane; + } + + void SetFarPlane(float farPlane) + { + this->farPlane = farPlane; + } + + + [[nodiscard]] float NearPlane() const + { + return nearPlane; + } + + [[nodiscard]] float FarPlane() const + { + return farPlane; + } + + virtual void UpdateProjectionMatrix() = 0; + + void UpdateViewProjectionMatrix() + { + //TODO this should be done based on the clipspace used by the rendering api + // In vulkan the screen space is defined as y=0=top and y=1=bottom and thus the coordinate have to be flipped + viewProjection = projection * Math::Matrix4f(1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1) * view; + } + + void UpdateWorldMatrix(const Math::Matrix4f& parentWorldMat) override + { + Node::UpdateWorldMatrix(parentWorldMat); + view = Math::Utils::inverse(GetWorldMatrix()); + camPosition = GetWorldMatrix()[3]; + UpdateViewProjectionMatrix(); + } + + [[nodiscard]] const Math::Matrix4f& GetViewProjectionMatrix() const + { + return viewProjection; + } + }; + + class PerspectiveCamera : public Camera + { + protected: + float fov = 0, aspect = 0; + + public: + PerspectiveCamera() = default; + ~PerspectiveCamera() override = default; + + PerspectiveCamera(float fovDegrees, float nearPlane = 0.1f, float farPlane = 1000.0f, float width = 16, float height = 9) + : Camera() + { + Init(fovDegrees, width, height, nearPlane, farPlane); + PerspectiveCamera::UpdateProjectionMatrix(); + } + + void Init(float fovDegrees, float nearPlane, float farPlane) + { + Init(fovDegrees, 16, 9, nearPlane, farPlane); + } + + void Init(float fovDegrees, float width, float height, float nearPlane, float farPlane) + { + this->fov = Math::Utils::radians(fovDegrees); + aspect = width / height; + Camera::Init(width, height, nearPlane, farPlane); + } + + void SetSize(const float width, const float height) override + { + aspect = width / height; + Camera::SetSize(width, height); + } + + void SetAspect(const float aspect) + { + this->aspect = aspect; + Camera::SetSize(aspect, 1); + } + + void SetFovX(const float fov) + { + SetFov(2 * atan(tan(fov * 0.5f) * aspect)); + } + + void SetFovXRad(const float fov) + { + SetFovRad(2 * atan(tan(fov * 0.5f) * aspect)); + } + + void SetFov(const float fov) + { + SetFovRad(Math::Utils::radians(fov)); + } + + void SetFovRad(const float fov) + { + this->fov = fov; + } + + [[nodiscard]] float GetFov() const + { + return Math::Utils::degrees(fov); + } + + [[nodiscard]] float GetFovX() const + { + return 2.0f * atanf(tanf(GetFov() * 0.5f) * aspect); + } + + [[nodiscard]] float GetFovRad() const + { + return fov; + } + + [[nodiscard]] float GetFovXRad() const + { + return 2.0f * atanf(tanf(fov * 0.5f) * aspect); + } + + void UpdateProjectionMatrix() final + { + projection = Math::Utils::perspectiveRH_ZO(fov, aspect, nearPlane, farPlane); + UpdateViewProjectionMatrix(); + } + }; + + class OrthographicCamera : public Camera + { + public: + void UpdateProjectionMatrix() final + { + const float widthHalf = width * 0.5f, heightHalf = height * 0.5f; + projection = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, nearPlane, farPlane); + UpdateViewProjectionMatrix(); + } + }; } +