mirror of
https://github.com/orange-cpp/omath.git
synced 2026-06-08 16:24:35 +00:00
camera message
This commit is contained in:
@@ -32,7 +32,7 @@ namespace omath::projection
|
|||||||
float m_width;
|
float m_width;
|
||||||
float m_height;
|
float m_height;
|
||||||
|
|
||||||
[[nodiscard]] constexpr float aspect_ratio() const
|
[[nodiscard("You must use aspect ratio")]] constexpr float aspect_ratio() const
|
||||||
{
|
{
|
||||||
return m_width / m_height;
|
return m_width / m_height;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ namespace omath::projection
|
|||||||
// built by any of the engine traits. Both variants (ZERO_TO_ONE and
|
// built by any of the engine traits. Both variants (ZERO_TO_ONE and
|
||||||
// NEGATIVE_ONE_TO_ONE) share the same m[0,0]/m[1,1] layout, so this works
|
// NEGATIVE_ONE_TO_ONE) share the same m[0,0]/m[1,1] layout, so this works
|
||||||
// regardless of the NDC depth range.
|
// regardless of the NDC depth range.
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use extracted projection params")]]
|
||||||
static ProjectionParams extract_projection_params(const Mat4X4Type& proj_matrix) noexcept
|
static ProjectionParams extract_projection_params(const Mat4X4Type& proj_matrix) noexcept
|
||||||
{
|
{
|
||||||
// m[1,1] == 1 / tan(fov/2) => fov = 2 * atan(1 / m[1,1])
|
// m[1,1] == 1 / tan(fov/2) => fov = 2 * atan(1 / m[1,1])
|
||||||
@@ -112,7 +112,7 @@ namespace omath::projection
|
|||||||
f / proj_matrix.at(0, 0)};
|
f / proj_matrix.at(0, 0)};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use calculated view angles")]]
|
||||||
static ViewAnglesType calc_view_angles_from_view_matrix(const Mat4X4Type& view_matrix) noexcept
|
static ViewAnglesType calc_view_angles_from_view_matrix(const Mat4X4Type& view_matrix) noexcept
|
||||||
{
|
{
|
||||||
Vector3<NumericType> forward_vector = {view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
Vector3<NumericType> forward_vector = {view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
||||||
@@ -121,7 +121,7 @@ namespace omath::projection
|
|||||||
return TraitClass::calc_look_at_angle({}, forward_vector);
|
return TraitClass::calc_look_at_angle({}, forward_vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use calculated origin")]]
|
||||||
static Vector3<NumericType> calc_origin_from_view_matrix(const Mat4X4Type& view_matrix) noexcept
|
static Vector3<NumericType> calc_origin_from_view_matrix(const Mat4X4Type& view_matrix) noexcept
|
||||||
{
|
{
|
||||||
// The view matrix is R * T(-origin), so the last column stores t = -R * origin.
|
// The view matrix is R * T(-origin), so the last column stores t = -R * origin.
|
||||||
@@ -142,33 +142,33 @@ namespace omath::projection
|
|||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
m_view_matrix = std::nullopt;
|
m_view_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use calculated look-at angles")]]
|
||||||
ViewAnglesType calc_look_at_angles(const Vector3<NumericType>& look_to) const
|
ViewAnglesType calc_look_at_angles(const Vector3<NumericType>& look_to) const
|
||||||
{
|
{
|
||||||
return TraitClass::calc_look_at_angle(m_origin, look_to);
|
return TraitClass::calc_look_at_angle(m_origin, look_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use forward vector")]]
|
||||||
Vector3<NumericType> get_forward() const noexcept
|
Vector3<NumericType> get_forward() const noexcept
|
||||||
{
|
{
|
||||||
const auto& view_matrix = get_view_matrix();
|
const auto& view_matrix = get_view_matrix();
|
||||||
return {view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
return {view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use right vector")]]
|
||||||
Vector3<NumericType> get_right() const noexcept
|
Vector3<NumericType> get_right() const noexcept
|
||||||
{
|
{
|
||||||
const auto& view_matrix = get_view_matrix();
|
const auto& view_matrix = get_view_matrix();
|
||||||
return {view_matrix[0, 0], view_matrix[0, 1], view_matrix[0, 2]};
|
return {view_matrix[0, 0], view_matrix[0, 1], view_matrix[0, 2]};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use up vector")]]
|
||||||
Vector3<NumericType> get_up() const noexcept
|
Vector3<NumericType> get_up() const noexcept
|
||||||
{
|
{
|
||||||
const auto& view_matrix = get_view_matrix();
|
const auto& view_matrix = get_view_matrix();
|
||||||
return {view_matrix[1, 0], view_matrix[1, 1], view_matrix[1, 2]};
|
return {view_matrix[1, 0], view_matrix[1, 1], view_matrix[1, 2]};
|
||||||
}
|
}
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use absolute forward vector")]]
|
||||||
Vector3<NumericType> get_abs_forward() const noexcept
|
Vector3<NumericType> get_abs_forward() const noexcept
|
||||||
{
|
{
|
||||||
if constexpr (axes.inverted_forward)
|
if constexpr (axes.inverted_forward)
|
||||||
@@ -176,7 +176,7 @@ namespace omath::projection
|
|||||||
return get_forward();
|
return get_forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use absolute right vector")]]
|
||||||
Vector3<NumericType> get_abs_right() const noexcept
|
Vector3<NumericType> get_abs_right() const noexcept
|
||||||
{
|
{
|
||||||
if constexpr (axes.inverted_right)
|
if constexpr (axes.inverted_right)
|
||||||
@@ -184,13 +184,13 @@ namespace omath::projection
|
|||||||
return get_right();
|
return get_right();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use absolute up vector")]]
|
||||||
Vector3<NumericType> get_abs_up() const noexcept
|
Vector3<NumericType> get_abs_up() const noexcept
|
||||||
{
|
{
|
||||||
return get_up();
|
return get_up();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const Mat4X4Type& get_view_projection_matrix() const noexcept
|
[[nodiscard("You must use view-projection matrix")]] const Mat4X4Type& get_view_projection_matrix() const noexcept
|
||||||
{
|
{
|
||||||
if (!m_view_projection_matrix.has_value())
|
if (!m_view_projection_matrix.has_value())
|
||||||
m_view_projection_matrix = get_projection_matrix() * get_view_matrix();
|
m_view_projection_matrix = get_projection_matrix() * get_view_matrix();
|
||||||
@@ -198,14 +198,14 @@ namespace omath::projection
|
|||||||
return m_view_projection_matrix.value();
|
return m_view_projection_matrix.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const Mat4X4Type& get_view_matrix() const noexcept
|
[[nodiscard("You must use view matrix")]] const Mat4X4Type& get_view_matrix() const noexcept
|
||||||
{
|
{
|
||||||
if (!m_view_matrix.has_value())
|
if (!m_view_matrix.has_value())
|
||||||
m_view_matrix = TraitClass::calc_view_matrix(m_view_angles, m_origin);
|
m_view_matrix = TraitClass::calc_view_matrix(m_view_angles, m_origin);
|
||||||
|
|
||||||
return m_view_matrix.value();
|
return m_view_matrix.value();
|
||||||
}
|
}
|
||||||
[[nodiscard]] const Mat4X4Type& get_projection_matrix() const noexcept
|
[[nodiscard("You must use projection matrix")]] const Mat4X4Type& get_projection_matrix() const noexcept
|
||||||
{
|
{
|
||||||
if (!m_projection_matrix.has_value())
|
if (!m_projection_matrix.has_value())
|
||||||
m_projection_matrix = TraitClass::calc_projection_matrix(
|
m_projection_matrix = TraitClass::calc_projection_matrix(
|
||||||
@@ -255,33 +255,33 @@ namespace omath::projection
|
|||||||
m_projection_matrix = std::nullopt;
|
m_projection_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const FieldOfView& get_field_of_view() const noexcept
|
[[nodiscard("You must use field of view")]] const FieldOfView& get_field_of_view() const noexcept
|
||||||
{
|
{
|
||||||
return m_field_of_view;
|
return m_field_of_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const NumericType& get_near_plane() const noexcept
|
[[nodiscard("You must use near plane")]] const NumericType& get_near_plane() const noexcept
|
||||||
{
|
{
|
||||||
return m_near_plane_distance;
|
return m_near_plane_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const NumericType& get_far_plane() const noexcept
|
[[nodiscard("You must use far plane")]] const NumericType& get_far_plane() const noexcept
|
||||||
{
|
{
|
||||||
return m_far_plane_distance;
|
return m_far_plane_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const ViewAnglesType& get_view_angles() const noexcept
|
[[nodiscard("You must use view angles")]] const ViewAnglesType& get_view_angles() const noexcept
|
||||||
{
|
{
|
||||||
return m_view_angles;
|
return m_view_angles;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const Vector3<NumericType>& get_origin() const noexcept
|
[[nodiscard("You must use origin")]] const Vector3<NumericType>& get_origin() const noexcept
|
||||||
{
|
{
|
||||||
return m_origin;
|
return m_origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
||||||
[[nodiscard]] std::expected<Vector3<NumericType>, Error>
|
[[nodiscard("You must use screen position")]] std::expected<Vector3<NumericType>, Error>
|
||||||
world_to_screen(const Vector3<NumericType>& world_position) const noexcept
|
world_to_screen(const Vector3<NumericType>& world_position) const noexcept
|
||||||
{
|
{
|
||||||
const auto normalized_cords = world_to_view_port(world_position);
|
const auto normalized_cords = world_to_view_port(world_position);
|
||||||
@@ -297,7 +297,7 @@ namespace omath::projection
|
|||||||
std::unreachable();
|
std::unreachable();
|
||||||
}
|
}
|
||||||
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
||||||
[[nodiscard]] std::expected<Vector3<NumericType>, Error>
|
[[nodiscard("You must use unclipped screen position")]] std::expected<Vector3<NumericType>, Error>
|
||||||
world_to_screen_unclipped(const Vector3<NumericType>& world_position) const noexcept
|
world_to_screen_unclipped(const Vector3<NumericType>& world_position) const noexcept
|
||||||
{
|
{
|
||||||
const auto normalized_cords = world_to_view_port(world_position, ViewPortClipping::MANUAL);
|
const auto normalized_cords = world_to_view_port(world_position, ViewPortClipping::MANUAL);
|
||||||
@@ -313,7 +313,7 @@ namespace omath::projection
|
|||||||
std::unreachable();
|
std::unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool is_culled_by_frustum(const Triangle<Vector3<NumericType>>& triangle) const noexcept
|
[[nodiscard("You must use frustum culling result")]] bool is_culled_by_frustum(const Triangle<Vector3<NumericType>>& triangle) const noexcept
|
||||||
{
|
{
|
||||||
// Transform to clip space (before perspective divide)
|
// Transform to clip space (before perspective divide)
|
||||||
auto to_clip = [this](const Vector3<NumericType>& point)
|
auto to_clip = [this](const Vector3<NumericType>& point)
|
||||||
@@ -380,7 +380,7 @@ namespace omath::projection
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool is_aabb_culled_by_frustum(const primitives::Aabb<NumericType>& aabb) const noexcept
|
[[nodiscard("You must use AABB frustum culling result")]] bool is_aabb_culled_by_frustum(const primitives::Aabb<NumericType>& aabb) const noexcept
|
||||||
{
|
{
|
||||||
// For each plane, find the AABB corner most in the direction of the plane normal
|
// For each plane, find the AABB corner most in the direction of the plane normal
|
||||||
// (the "positive vertex"). If it's outside, the entire AABB is outside.
|
// (the "positive vertex"). If it's outside, the entire AABB is outside.
|
||||||
@@ -397,7 +397,7 @@ namespace omath::projection
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool is_obb_culled_by_frustum(const primitives::Obb<NumericType>& obb) const noexcept
|
[[nodiscard("You must use OBB frustum culling result")]] bool is_obb_culled_by_frustum(const primitives::Obb<NumericType>& obb) const noexcept
|
||||||
{
|
{
|
||||||
// For each plane, project the OBB extents onto the plane normal to get the
|
// For each plane, project the OBB extents onto the plane normal to get the
|
||||||
// effective radius, then test the center's signed distance against it.
|
// effective radius, then test the center's signed distance against it.
|
||||||
@@ -417,7 +417,7 @@ namespace omath::projection
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::expected<Vector3<NumericType>, Error>
|
[[nodiscard("You must use view port position")]] std::expected<Vector3<NumericType>, Error>
|
||||||
world_to_view_port(const Vector3<NumericType>& world_position,
|
world_to_view_port(const Vector3<NumericType>& world_position,
|
||||||
const ViewPortClipping& clipping = ViewPortClipping::AUTO) const noexcept
|
const ViewPortClipping& clipping = ViewPortClipping::AUTO) const noexcept
|
||||||
{
|
{
|
||||||
@@ -446,7 +446,7 @@ namespace omath::projection
|
|||||||
|
|
||||||
return Vector3<NumericType>{projected.at(0, 0), projected.at(1, 0), projected.at(2, 0)};
|
return Vector3<NumericType>{projected.at(0, 0), projected.at(1, 0), projected.at(2, 0)};
|
||||||
}
|
}
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use world position")]]
|
||||||
std::expected<Vector3<NumericType>, Error> view_port_to_world(const Vector3<NumericType>& ndc) const noexcept
|
std::expected<Vector3<NumericType>, Error> view_port_to_world(const Vector3<NumericType>& ndc) const noexcept
|
||||||
{
|
{
|
||||||
const auto inv_view_proj = get_view_projection_matrix().inverted();
|
const auto inv_view_proj = get_view_projection_matrix().inverted();
|
||||||
@@ -469,7 +469,7 @@ namespace omath::projection
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use world position")]]
|
||||||
std::expected<Vector3<NumericType>, Error>
|
std::expected<Vector3<NumericType>, Error>
|
||||||
screen_to_world(const Vector3<NumericType>& screen_pos) const noexcept
|
screen_to_world(const Vector3<NumericType>& screen_pos) const noexcept
|
||||||
{
|
{
|
||||||
@@ -477,7 +477,7 @@ namespace omath::projection
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use world position")]]
|
||||||
std::expected<Vector3<NumericType>, Error>
|
std::expected<Vector3<NumericType>, Error>
|
||||||
screen_to_world(const Vector2<NumericType>& screen_pos) const noexcept
|
screen_to_world(const Vector2<NumericType>& screen_pos) const noexcept
|
||||||
{
|
{
|
||||||
@@ -513,7 +513,7 @@ namespace omath::projection
|
|||||||
// Top = r3 - r1
|
// Top = r3 - r1
|
||||||
// Near = r3 + r2 ([-1,1]) or r2 ([0,1])
|
// Near = r3 + r2 ([-1,1]) or r2 ([0,1])
|
||||||
// Far = r3 - r2
|
// Far = r3 - r2
|
||||||
[[nodiscard]] std::array<FrustumPlane, 6> extract_frustum_planes() const noexcept
|
[[nodiscard("You must use frustum planes")]] std::array<FrustumPlane, 6> extract_frustum_planes() const noexcept
|
||||||
{
|
{
|
||||||
const auto& m = get_view_projection_matrix();
|
const auto& m = get_view_projection_matrix();
|
||||||
|
|
||||||
@@ -545,7 +545,7 @@ namespace omath::projection
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
[[nodiscard]] constexpr static bool is_ndc_out_of_bounds(const Type& ndc) noexcept
|
[[nodiscard("You must use NDC bounds check result")]] constexpr static bool is_ndc_out_of_bounds(const Type& ndc) noexcept
|
||||||
{
|
{
|
||||||
constexpr auto eps = std::numeric_limits<NumericType>::epsilon();
|
constexpr auto eps = std::numeric_limits<NumericType>::epsilon();
|
||||||
|
|
||||||
@@ -558,7 +558,7 @@ namespace omath::projection
|
|||||||
return is_ndc_z_value_out_of_bounds(data[2]);
|
return is_ndc_z_value_out_of_bounds(data[2]);
|
||||||
}
|
}
|
||||||
template<class ZType>
|
template<class ZType>
|
||||||
[[nodiscard]]
|
[[nodiscard("You must use NDC z bounds check result")]]
|
||||||
constexpr static bool is_ndc_z_value_out_of_bounds(const ZType& z_ndc) noexcept
|
constexpr static bool is_ndc_z_value_out_of_bounds(const ZType& z_ndc) noexcept
|
||||||
{
|
{
|
||||||
constexpr auto eps = std::numeric_limits<NumericType>::epsilon();
|
constexpr auto eps = std::numeric_limits<NumericType>::epsilon();
|
||||||
@@ -584,7 +584,7 @@ namespace omath::projection
|
|||||||
v
|
v
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[[nodiscard]] Vector3<NumericType>
|
[[nodiscard("You must use screen position")]] Vector3<NumericType>
|
||||||
ndc_to_screen_position_from_top_left_corner(const Vector3<NumericType>& ndc) const noexcept
|
ndc_to_screen_position_from_top_left_corner(const Vector3<NumericType>& ndc) const noexcept
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -602,7 +602,7 @@ namespace omath::projection
|
|||||||
(ndc.y / -NumericType{2} + NumericType{0.5}) * m_view_port.m_height, ndc.z};
|
(ndc.y / -NumericType{2} + NumericType{0.5}) * m_view_port.m_height, ndc.z};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Vector3<NumericType>
|
[[nodiscard("You must use screen position")]] Vector3<NumericType>
|
||||||
ndc_to_screen_position_from_bottom_left_corner(const Vector3<NumericType>& ndc) const noexcept
|
ndc_to_screen_position_from_bottom_left_corner(const Vector3<NumericType>& ndc) const noexcept
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -621,7 +621,7 @@ namespace omath::projection
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
|
||||||
[[nodiscard]] Vector3<NumericType> screen_to_ndc(const Vector3<NumericType>& screen_pos) const noexcept
|
[[nodiscard("You must use NDC position")]] Vector3<NumericType> screen_to_ndc(const Vector3<NumericType>& screen_pos) const noexcept
|
||||||
{
|
{
|
||||||
if constexpr (screen_start == ScreenStart::TOP_LEFT_CORNER)
|
if constexpr (screen_start == ScreenStart::TOP_LEFT_CORNER)
|
||||||
return {screen_pos.x / m_view_port.m_width * NumericType{2} - NumericType{1},
|
return {screen_pos.x / m_view_port.m_width * NumericType{2} - NumericType{1},
|
||||||
|
|||||||
Reference in New Issue
Block a user