mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 23:13:26 +00:00
huge improvement
This commit is contained in:
@@ -5,9 +5,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <omath/Vector3.hpp>
|
||||
#include <omath/Mat.hpp>
|
||||
#include <omath/Vector3.hpp>
|
||||
#include "ErrorCodes.hpp"
|
||||
#include <omath/Angle.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace omath::projection
|
||||
@@ -18,29 +20,60 @@ namespace omath::projection
|
||||
float m_width;
|
||||
float m_height;
|
||||
|
||||
[[nodiscard]] constexpr float AspectRatio() const {return m_width / m_height;}
|
||||
[[nodiscard]] constexpr float AspectRatio() const
|
||||
{
|
||||
return m_width / m_height;
|
||||
}
|
||||
};
|
||||
|
||||
template<class ViewAnglesType, class ViewMatFunc, class ProjectionFunc>
|
||||
requires std::is_same_v<std::invoke_result_t<ViewMatFunc, const ViewAnglesType&, const Vector3&>,
|
||||
std::invoke_result_t<ProjectionFunc, const float&, const float&, const float&, const float&>>
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera(const Vector3& position, const Vector3& viewAngles, const ViewPort& viewPort,
|
||||
float fov, float near, float far, float lensZoom);
|
||||
void SetViewAngles(const Vector3& viewAngles);
|
||||
Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort,
|
||||
const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, const float near, const float far,
|
||||
const std::function<ViewMatFunc>& viewMatFunc, const std::function<ProjectionFunc>& projFunc) :
|
||||
m_viewPort(viewPort), m_fieldOfView(fov), m_farPlaneDistance(far), m_nearPlaneDistance(near),
|
||||
m_viewAngles(viewAngles), m_origin(position), CreateViewMatrix(viewMatFunc), CreateProjectionMatrix(projFunc)
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] Mat<4, 4> GetViewMatrix() const;
|
||||
void LookAt(const Vector3& target);
|
||||
|
||||
[[nodiscard]] std::expected<Vector3, Error> WorldToScreen(const Vector3& worldPosition) const;
|
||||
[[nodiscard]] auto GetViewMatrix() const
|
||||
{
|
||||
return CreateViewMatrix(m_viewAngles, m_origin);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto GetProjectionMatrix() const
|
||||
{
|
||||
return CreateProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<Vector3, Error> WorldToScreen([[maybe_unused]] const Vector3& worldPosition) const
|
||||
{
|
||||
using mat = std::invoke_result_t<ViewMatFunc, const ViewAnglesType&, const Vector3&>;
|
||||
const auto vecAsMatrix = MatColumnFromVector<float, mat::GetStoreOrdering()>(worldPosition);
|
||||
|
||||
const auto projected = GetViewMatrix().Transposed() * vecAsMatrix;
|
||||
|
||||
|
||||
return Vector3{projected.At(0,0), projected.At(1,0), projected.At(2,0)};
|
||||
}
|
||||
|
||||
ViewPort m_viewPort{};
|
||||
float m_fieldOfView;
|
||||
Angle<float, 0.f, 180.f, AngleFlags::Clamped> m_fieldOfView;
|
||||
|
||||
float m_farPlaneDistance;
|
||||
float m_nearPlaneDistance;
|
||||
float m_lensZoom;
|
||||
|
||||
private:
|
||||
Vector3 m_viewAngles;
|
||||
ViewAnglesType m_viewAngles;
|
||||
Vector3 m_origin;
|
||||
|
||||
std::function<ViewMatFunc> CreateViewMatrix;
|
||||
std::function<ProjectionFunc> CreateProjectionMatrix;
|
||||
};
|
||||
}
|
||||
} // namespace omath::projection
|
||||
|
||||
Reference in New Issue
Block a user