mirror of
https://github.com/orange-cpp/omath.git
synced 2026-04-25 16:43:27 +00:00
added types impl
This commit is contained in:
@@ -51,17 +51,17 @@ namespace omath::projection
|
|||||||
template<class T, class MatType, class ViewAnglesType, class NumericType>
|
template<class T, class MatType, class ViewAnglesType, class NumericType>
|
||||||
concept CameraEngineConcept =
|
concept CameraEngineConcept =
|
||||||
requires(const Vector3<NumericType>& cam_origin, const Vector3<NumericType>& look_at,
|
requires(const Vector3<NumericType>& cam_origin, const Vector3<NumericType>& look_at,
|
||||||
const ViewAnglesType& angles, const FieldOfView& fov, const ViewPort& viewport,
|
const ViewAnglesType& angles, const FieldOfView& fov, const ViewPort& viewport, NumericType z_near,
|
||||||
NumericType znear, NumericType zfar, NDCDepthRange ndc_depth_range) {
|
NumericType z_far, NDCDepthRange ndc_depth_range) {
|
||||||
// Presence + return types
|
// Presence + return types
|
||||||
{ T::calc_look_at_angle(cam_origin, look_at) } -> std::same_as<ViewAnglesType>;
|
{ T::calc_look_at_angle(cam_origin, look_at) } -> std::same_as<ViewAnglesType>;
|
||||||
{ T::calc_view_matrix(angles, cam_origin) } -> std::same_as<MatType>;
|
{ T::calc_view_matrix(angles, cam_origin) } -> std::same_as<MatType>;
|
||||||
{ T::calc_projection_matrix(fov, viewport, znear, zfar, ndc_depth_range) } -> std::same_as<MatType>;
|
{ T::calc_projection_matrix(fov, viewport, z_near, z_far, ndc_depth_range) } -> std::same_as<MatType>;
|
||||||
requires std::is_floating_point_v<NumericType>;
|
requires std::is_floating_point_v<NumericType>;
|
||||||
// Enforce noexcept as in the trait declaration
|
// Enforce noexcept as in the trait declaration
|
||||||
requires noexcept(T::calc_look_at_angle(cam_origin, look_at));
|
requires noexcept(T::calc_look_at_angle(cam_origin, look_at));
|
||||||
requires noexcept(T::calc_view_matrix(angles, cam_origin));
|
requires noexcept(T::calc_view_matrix(angles, cam_origin));
|
||||||
requires noexcept(T::calc_projection_matrix(fov, viewport, znear, zfar, ndc_depth_range));
|
requires noexcept(T::calc_projection_matrix(fov, viewport, z_near, z_far, ndc_depth_range));
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Mat4X4Type, class ViewAnglesType, class TraitClass,
|
template<class Mat4X4Type, class ViewAnglesType, class TraitClass,
|
||||||
@@ -93,7 +93,7 @@ namespace omath::projection
|
|||||||
struct ProjectionParams final
|
struct ProjectionParams final
|
||||||
{
|
{
|
||||||
FieldOfView fov;
|
FieldOfView fov;
|
||||||
float aspect_ratio{};
|
NumericType aspect_ratio{};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Recovers vertical FOV and aspect ratio from a perspective projection matrix
|
// Recovers vertical FOV and aspect ratio from a perspective projection matrix
|
||||||
@@ -106,7 +106,8 @@ namespace omath::projection
|
|||||||
// 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])
|
||||||
const auto f = proj_matrix.at(1, 1);
|
const auto f = proj_matrix.at(1, 1);
|
||||||
// m[0,0] == m[1,1] / aspect_ratio => aspect = m[1,1] / m[0,0]
|
// m[0,0] == m[1,1] / aspect_ratio => aspect = m[1,1] / m[0,0]
|
||||||
return {FieldOfView::from_radians(2.f * std::atan(1.f / f)), f / proj_matrix.at(0, 0)};
|
return {FieldOfView::from_radians(NumericType{2} * std::atan(NumericType{1} / f)),
|
||||||
|
f / proj_matrix.at(0, 0)};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@@ -423,11 +424,11 @@ namespace omath::projection
|
|||||||
// (the "positive vertex"). If it's outside, the entire AABB is outside.
|
// (the "positive vertex"). If it's outside, the entire AABB is outside.
|
||||||
for (const auto& [a, b, c, d] : planes)
|
for (const auto& [a, b, c, d] : planes)
|
||||||
{
|
{
|
||||||
const auto px = a >= 0.f ? aabb.max.x : aabb.min.x;
|
const auto px = a >= NumericType{0} ? aabb.max.x : aabb.min.x;
|
||||||
const auto py = b >= 0.f ? aabb.max.y : aabb.min.y;
|
const auto py = b >= NumericType{0} ? aabb.max.y : aabb.min.y;
|
||||||
const auto pz = c >= 0.f ? aabb.max.z : aabb.min.z;
|
const auto pz = c >= NumericType{0} ? aabb.max.z : aabb.min.z;
|
||||||
|
|
||||||
if (a * px + b * py + c * pz + d < 0.f)
|
if (a * px + b * py + c * pz + d < NumericType{0})
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,9 +455,10 @@ namespace omath::projection
|
|||||||
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
|
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
|
||||||
|
|
||||||
// ReSharper disable once CppTooWideScope
|
// ReSharper disable once CppTooWideScope
|
||||||
constexpr auto z_min = depth_range == NDCDepthRange::ZERO_TO_ONE ? 0.0f : -1.0f;
|
constexpr auto z_min = depth_range == NDCDepthRange::ZERO_TO_ONE ? NumericType{0} : -NumericType{1};
|
||||||
const auto clipped_manually = clipping == ViewPortClipping::MANUAL
|
const auto clipped_manually =
|
||||||
&& (projected.at(2, 0) < z_min - eps || projected.at(2, 0) > 1.0f + eps);
|
clipping == ViewPortClipping::MANUAL
|
||||||
|
&& (projected.at(2, 0) < z_min - eps || projected.at(2, 0) > NumericType{1} + eps);
|
||||||
if (clipped_manually)
|
if (clipped_manually)
|
||||||
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
|
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
|
||||||
|
|
||||||
@@ -522,9 +524,9 @@ namespace omath::projection
|
|||||||
|
|
||||||
const auto& data = ndc.raw_array();
|
const auto& data = ndc.raw_array();
|
||||||
// x and y are always in [-1, 1]
|
// x and y are always in [-1, 1]
|
||||||
if (data[0] < -1.0f - eps || data[0] > 1.0f + eps)
|
if (data[0] < -NumericType{1} - eps || data[0] > NumericType{1} + eps)
|
||||||
return true;
|
return true;
|
||||||
if (data[1] < -1.0f - eps || data[1] > 1.0f + eps)
|
if (data[1] < -NumericType{1} - eps || data[1] > NumericType{1} + eps)
|
||||||
return true;
|
return true;
|
||||||
return is_ndc_z_value_out_of_bounds(data[2]);
|
return is_ndc_z_value_out_of_bounds(data[2]);
|
||||||
}
|
}
|
||||||
@@ -534,9 +536,9 @@ namespace omath::projection
|
|||||||
{
|
{
|
||||||
constexpr auto eps = std::numeric_limits<NumericType>::epsilon();
|
constexpr auto eps = std::numeric_limits<NumericType>::epsilon();
|
||||||
if constexpr (depth_range == NDCDepthRange::NEGATIVE_ONE_TO_ONE)
|
if constexpr (depth_range == NDCDepthRange::NEGATIVE_ONE_TO_ONE)
|
||||||
return z_ndc < -1.0f - eps || z_ndc > 1.0f + eps;
|
return z_ndc < -NumericType{1} - eps || z_ndc > NumericType{1} + eps;
|
||||||
if constexpr (depth_range == NDCDepthRange::ZERO_TO_ONE)
|
if constexpr (depth_range == NDCDepthRange::ZERO_TO_ONE)
|
||||||
return z_ndc < 0.0f - eps || z_ndc > 1.0f + eps;
|
return z_ndc < NumericType{0} - eps || z_ndc > NumericType{1} + eps;
|
||||||
|
|
||||||
std::unreachable();
|
std::unreachable();
|
||||||
}
|
}
|
||||||
@@ -569,7 +571,8 @@ namespace omath::projection
|
|||||||
|
|
|
|
||||||
⌄
|
⌄
|
||||||
*/
|
*/
|
||||||
return {(ndc.x + 1.f) / 2.f * m_view_port.m_width, (ndc.y / -2.f + 0.5f) * m_view_port.m_height, ndc.z};
|
return {(ndc.x + NumericType{1}) / NumericType{2} * m_view_port.m_width,
|
||||||
|
(ndc.y / -NumericType{2} + NumericType{0.5}) * m_view_port.m_height, ndc.z};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Vector3<NumericType>
|
[[nodiscard]] Vector3<NumericType>
|
||||||
@@ -586,18 +589,19 @@ namespace omath::projection
|
|||||||
| (0, 0)
|
| (0, 0)
|
||||||
+------------------------>
|
+------------------------>
|
||||||
*/
|
*/
|
||||||
return {(ndc.x + 1.f) / 2.f * m_view_port.m_width, (ndc.y / 2.f + 0.5f) * m_view_port.m_height, ndc.z};
|
return {(ndc.x + NumericType{1}) / NumericType{2} * m_view_port.m_width,
|
||||||
|
(ndc.y / NumericType{2} + NumericType{0.5}) * m_view_port.m_height, ndc.z};
|
||||||
}
|
}
|
||||||
|
|
||||||
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]] 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 * 2.f - 1.f, 1.f - screen_pos.y / m_view_port.m_height * 2.f,
|
return {screen_pos.x / m_view_port.m_width * NumericType{2} - NumericType{1},
|
||||||
screen_pos.z};
|
NumericType{1} - screen_pos.y / m_view_port.m_height * NumericType{2}, screen_pos.z};
|
||||||
else if constexpr (screen_start == ScreenStart::BOTTOM_LEFT_CORNER)
|
else if constexpr (screen_start == ScreenStart::BOTTOM_LEFT_CORNER)
|
||||||
return {screen_pos.x / m_view_port.m_width * 2.f - 1.f,
|
return {screen_pos.x / m_view_port.m_width * NumericType{2} - NumericType{1},
|
||||||
(screen_pos.y / m_view_port.m_height - 0.5f) * 2.f, screen_pos.z};
|
(screen_pos.y / m_view_port.m_height - NumericType{0.5}) * NumericType{2}, screen_pos.z};
|
||||||
else
|
else
|
||||||
std::unreachable();
|
std::unreachable();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user