mirror of
https://github.com/orange-cpp/omath.git
synced 2026-06-15 11:44:34 +00:00
added wrapers
This commit is contained in:
@@ -16,13 +16,8 @@ namespace omath::cry_engine
|
||||
const Vector3<float>& look_at) noexcept
|
||||
{
|
||||
const auto direction = (look_at - cam_origin).normalized();
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return {PitchAngle::from_radians(gcem::asin(direction.z)),
|
||||
YawAngle::from_radians(-gcem::atan2(direction.x, direction.y)), RollAngle::from_radians(0.f)};
|
||||
#else
|
||||
return {PitchAngle::from_radians(std::asin(direction.z)),
|
||||
YawAngle::from_radians(-std::atan2(direction.x, direction.y)), RollAngle::from_radians(0.f)};
|
||||
#endif
|
||||
return {PitchAngle::from_radians(internal::asin(direction.z)),
|
||||
YawAngle::from_radians(-internal::atan2(direction.x, direction.y)), RollAngle::from_radians(0.f)};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
||||
@@ -3,10 +3,147 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef OMATH_USE_GCEM
|
||||
#include <gcem.hpp>
|
||||
#define OMATH_CONSTEXPR constexpr
|
||||
#else
|
||||
#define OMATH_CONSTEXPR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace omath::internal
|
||||
{
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type sin(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::sin(value);
|
||||
#endif
|
||||
return std::sin(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type cos(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::cos(value);
|
||||
#endif
|
||||
return std::cos(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type tan(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::tan(value);
|
||||
#endif
|
||||
return std::tan(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type atan(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::atan(value);
|
||||
#endif
|
||||
return std::atan(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type atan2(const Type& y, const Type& x) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::atan2(y, x);
|
||||
#endif
|
||||
return std::atan2(y, x);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type asin(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::asin(value);
|
||||
#endif
|
||||
return std::asin(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type acos(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::acos(value);
|
||||
#endif
|
||||
return std::acos(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type sqrt(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::sqrt(value);
|
||||
#endif
|
||||
return std::sqrt(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type hypot(const Type& x, const Type& y) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::hypot(x, y);
|
||||
#endif
|
||||
return std::hypot(x, y);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type hypot(const Type& x, const Type& y, const Type& z) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::sqrt(x * x + y * y + z * z);
|
||||
#endif
|
||||
return std::hypot(x, y, z);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type abs(const Type& value) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::abs(value);
|
||||
#endif
|
||||
return std::abs(value);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type fmod(const Type& dividend, const Type& divisor) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
if (std::is_constant_evaluated())
|
||||
return gcem::fmod(dividend, divisor);
|
||||
#endif
|
||||
return std::fmod(dividend, divisor);
|
||||
}
|
||||
} // namespace omath::internal
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Created by vlad on 9/29/2024.
|
||||
//
|
||||
#pragma once
|
||||
#include "omath/internal/optional_constexpr_math.hpp"
|
||||
#include "vector3.hpp"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -634,11 +635,7 @@ namespace omath
|
||||
OMATH_CONSTEXPR Vector3<Type> mat_extract_scale(const Mat<4, 4, Type, St>& mat) noexcept
|
||||
{
|
||||
auto column_length = [](const Type x, const Type y, const Type z) {
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return static_cast<Type>(gcem::sqrt(x * x + y * y + z * z));
|
||||
#else
|
||||
return static_cast<Type>(std::sqrt(x * x + y * y + z * z));
|
||||
#endif
|
||||
return static_cast<Type>(internal::sqrt(x * x + y * y + z * z));
|
||||
};
|
||||
|
||||
const auto scale_x = column_length(mat.at(0, 0), mat.at(1, 0), mat.at(2, 0));
|
||||
@@ -648,15 +645,9 @@ namespace omath
|
||||
constexpr auto epsilon = std::numeric_limits<Type>::epsilon();
|
||||
|
||||
return {
|
||||
#ifdef OMATH_USE_GCEM
|
||||
gcem::abs(scale_x) < epsilon ? Type{1} : scale_x,
|
||||
gcem::abs(scale_y) < epsilon ? Type{1} : scale_y,
|
||||
gcem::abs(scale_z) < epsilon ? Type{1} : scale_z,
|
||||
#else
|
||||
std::abs(scale_x) < epsilon ? Type{1} : scale_x,
|
||||
std::abs(scale_y) < epsilon ? Type{1} : scale_y,
|
||||
std::abs(scale_z) < epsilon ? Type{1} : scale_z,
|
||||
#endif
|
||||
internal::abs(scale_x) < epsilon ? Type{1} : scale_x,
|
||||
internal::abs(scale_y) < epsilon ? Type{1} : scale_y,
|
||||
internal::abs(scale_z) < epsilon ? Type{1} : scale_z,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -673,15 +664,9 @@ namespace omath
|
||||
const auto m22 = mat.at(2, 2) / scale.z;
|
||||
|
||||
return {
|
||||
#ifdef OMATH_USE_GCEM
|
||||
angles::radians_to_degrees(gcem::atan2(m21, m22)),
|
||||
angles::radians_to_degrees(gcem::asin(std::clamp(-m20, Type{-1}, Type{1}))),
|
||||
angles::radians_to_degrees(gcem::atan2(m10, m00)),
|
||||
#else
|
||||
angles::radians_to_degrees(std::atan2(m21, m22)),
|
||||
angles::radians_to_degrees(std::asin(std::clamp(-m20, Type{-1}, Type{1}))),
|
||||
angles::radians_to_degrees(std::atan2(m10, m00)),
|
||||
#endif
|
||||
angles::radians_to_degrees(internal::atan2(m21, m22)),
|
||||
angles::radians_to_degrees(internal::asin(std::clamp(-m20, Type{-1}, Type{1}))),
|
||||
angles::radians_to_degrees(internal::atan2(m10, m00)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -744,11 +729,7 @@ namespace omath
|
||||
Mat<4, 4, Type, St> mat_perspective_left_handed_vertical_fov(const Type field_of_view, const Type aspect_ratio,
|
||||
const Type near, const Type far) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
const auto fov_half_tan = gcem::tan(angles::degrees_to_radians(field_of_view) / Type{2});
|
||||
#else
|
||||
const auto fov_half_tan = std::tan(angles::degrees_to_radians(field_of_view) / Type{2});
|
||||
#endif
|
||||
const auto fov_half_tan = internal::tan(angles::degrees_to_radians(field_of_view) / Type{2});
|
||||
if constexpr (DepthRange == NDCDepthRange::ZERO_TO_ONE)
|
||||
return {{Type{1} / (aspect_ratio * fov_half_tan), Type{0}, Type{0}, Type{0}},
|
||||
{Type{0}, Type{1} / fov_half_tan, Type{0}, Type{0}},
|
||||
@@ -769,11 +750,7 @@ namespace omath
|
||||
Mat<4, 4, Type, St> mat_perspective_right_handed_vertical_fov(const Type field_of_view, const Type aspect_ratio,
|
||||
const Type near, const Type far) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
const auto fov_half_tan = gcem::tan(angles::degrees_to_radians(field_of_view) / Type{2});
|
||||
#else
|
||||
const auto fov_half_tan = std::tan(angles::degrees_to_radians(field_of_view) / Type{2});
|
||||
#endif
|
||||
const auto fov_half_tan = internal::tan(angles::degrees_to_radians(field_of_view) / Type{2});
|
||||
|
||||
if constexpr (DepthRange == NDCDepthRange::ZERO_TO_ONE)
|
||||
return {{Type{1} / (aspect_ratio * fov_half_tan), Type{0}, Type{0}, Type{0}},
|
||||
@@ -799,11 +776,7 @@ namespace omath
|
||||
const Type aspect_ratio, const Type near,
|
||||
const Type far) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
const auto inv_tan_half_hfov = Type{1} / gcem::tan(angles::degrees_to_radians(horizontal_fov) / Type{2});
|
||||
#else
|
||||
const auto inv_tan_half_hfov = Type{1} / std::tan(angles::degrees_to_radians(horizontal_fov) / Type{2});
|
||||
#endif
|
||||
const auto inv_tan_half_hfov = Type{1} / internal::tan(angles::degrees_to_radians(horizontal_fov) / Type{2});
|
||||
const auto x_axis = inv_tan_half_hfov;
|
||||
const auto y_axis = inv_tan_half_hfov * aspect_ratio;
|
||||
|
||||
@@ -828,11 +801,7 @@ namespace omath
|
||||
const Type aspect_ratio, const Type near,
|
||||
const Type far) noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
const auto inv_tan_half_hfov = Type{1} / gcem::tan(angles::degrees_to_radians(horizontal_fov) / Type{2});
|
||||
#else
|
||||
const auto inv_tan_half_hfov = Type{1} / std::tan(angles::degrees_to_radians(horizontal_fov) / Type{2});
|
||||
#endif
|
||||
const auto inv_tan_half_hfov = Type{1} / internal::tan(angles::degrees_to_radians(horizontal_fov) / Type{2});
|
||||
|
||||
const auto x_axis = inv_tan_half_hfov;
|
||||
const auto y_axis = inv_tan_half_hfov * aspect_ratio;
|
||||
|
||||
@@ -69,11 +69,7 @@ namespace omath
|
||||
const auto side_b = side_b_length();
|
||||
const auto hypot_value = hypot();
|
||||
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::abs(side_a * side_a + side_b * side_b - hypot_value * hypot_value) <= 0.0001f;
|
||||
#else
|
||||
return std::abs(side_a * side_a + side_b * side_b - hypot_value * hypot_value) <= 0.0001f;
|
||||
#endif
|
||||
return internal::abs(side_a * side_a + side_b * side_b - hypot_value * hypot_value) <= 0.0001f;
|
||||
}
|
||||
[[nodiscard]]
|
||||
constexpr Vector side_b_vector() const
|
||||
|
||||
@@ -119,11 +119,7 @@ namespace omath
|
||||
[[nodiscard("You must use distance")]]
|
||||
OMATH_CONSTEXPR Type distance_to(const Vector2& other) const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::sqrt(distance_to_sqr(other));
|
||||
#else
|
||||
return std::sqrt(distance_to_sqr(other));
|
||||
#endif
|
||||
return internal::sqrt(distance_to_sqr(other));
|
||||
}
|
||||
|
||||
[[nodiscard("You must use squared distance")]]
|
||||
@@ -141,11 +137,7 @@ namespace omath
|
||||
#ifndef _MSC_VER
|
||||
[[nodiscard("You must use length")]] constexpr Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::hypot(this->x, this->y);
|
||||
#else
|
||||
return std::hypot(this->x, this->y);
|
||||
#endif
|
||||
return internal::hypot(this->x, this->y);
|
||||
}
|
||||
|
||||
[[nodiscard("You must use normalized vector")]] constexpr Vector2 normalized() const noexcept
|
||||
@@ -157,11 +149,7 @@ namespace omath
|
||||
[[nodiscard("You must use length")]]
|
||||
OMATH_CONSTEXPR Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::hypot(x, y);
|
||||
#else
|
||||
return std::hypot(x, y);
|
||||
#endif
|
||||
return internal::hypot(x, y);
|
||||
}
|
||||
|
||||
[[nodiscard("You must use normalized vector")]]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "omath/internal/optional_constexpr_math.hpp"
|
||||
#include "omath/linear_algebra/vector2.hpp"
|
||||
#include "omath/trigonometry/angle.hpp"
|
||||
#include <cstdint>
|
||||
@@ -142,11 +143,7 @@ namespace omath
|
||||
#ifndef _MSC_VER
|
||||
[[nodiscard("You must use length")]] constexpr Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::sqrt(this->x * this->x + this->y * this->y + z * z);
|
||||
#else
|
||||
return std::hypot(this->x, this->y, z);
|
||||
#endif
|
||||
return internal::hypot(this->x, this->y, z);
|
||||
}
|
||||
|
||||
[[nodiscard("You must use 2D length")]] constexpr Type length_2d() const noexcept
|
||||
@@ -167,11 +164,7 @@ namespace omath
|
||||
[[nodiscard("You must use length")]]
|
||||
OMATH_CONSTEXPR Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::sqrt(this->x * this->x + this->y * this->y + this->z * this->z);
|
||||
#else
|
||||
return std::hypot(this->x, this->y, z);
|
||||
#endif
|
||||
return internal::hypot(this->x, this->y, this->z);
|
||||
}
|
||||
|
||||
[[nodiscard("You must use normalized vector")]]
|
||||
@@ -269,11 +262,7 @@ namespace omath
|
||||
|
||||
if (bottom == static_cast<Type>(0))
|
||||
return std::unexpected(Vector3Error::IMPOSSIBLE_BETWEEN_ANGLE);
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(gcem::acos(dot(other) / bottom));
|
||||
#else
|
||||
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(std::acos(dot(other) / bottom));
|
||||
#endif
|
||||
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(internal::acos(dot(other) / bottom));
|
||||
}
|
||||
|
||||
[[nodiscard("You must use perpendicularity check result")]]
|
||||
|
||||
@@ -73,45 +73,25 @@ namespace omath
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type sin() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::sin(as_radians());
|
||||
#else
|
||||
return std::sin(as_radians());
|
||||
|
||||
#endif
|
||||
return internal::sin(as_radians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type cos() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::cos(as_radians());
|
||||
#else
|
||||
return std::cos(as_radians());
|
||||
|
||||
#endif
|
||||
return internal::cos(as_radians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type tan() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::tan(as_radians());
|
||||
#else
|
||||
return std::tan(as_radians());
|
||||
|
||||
#endif
|
||||
return internal::tan(as_radians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
OMATH_CONSTEXPR Type atan() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::atan(as_radians());
|
||||
#else
|
||||
return std::atan(as_radians());
|
||||
|
||||
#endif
|
||||
return internal::atan(as_radians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
||||
@@ -25,23 +25,25 @@ namespace omath::angles
|
||||
|
||||
template<class Type>
|
||||
requires std::is_floating_point_v<Type>
|
||||
[[nodiscard]] Type horizontal_fov_to_vertical(const Type& horizontal_fov, const Type& aspect) noexcept
|
||||
[[nodiscard]] OMATH_CONSTEXPR Type horizontal_fov_to_vertical(const Type& horizontal_fov,
|
||||
const Type& aspect) noexcept
|
||||
{
|
||||
const auto fov_rad = degrees_to_radians(horizontal_fov);
|
||||
|
||||
const auto vert_fov = static_cast<Type>(2) * std::atan(std::tan(fov_rad / static_cast<Type>(2)) / aspect);
|
||||
const auto vert_fov = static_cast<Type>(2) * internal::atan(internal::tan(fov_rad / static_cast<Type>(2)) / aspect);
|
||||
|
||||
return radians_to_degrees(vert_fov);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
requires std::is_floating_point_v<Type>
|
||||
[[nodiscard]] Type vertical_fov_to_horizontal(const Type& vertical_fov, const Type& aspect) noexcept
|
||||
[[nodiscard]] OMATH_CONSTEXPR Type vertical_fov_to_horizontal(const Type& vertical_fov,
|
||||
const Type& aspect) noexcept
|
||||
{
|
||||
const auto fov_as_radians = degrees_to_radians(vertical_fov);
|
||||
|
||||
const auto horizontal_fov =
|
||||
static_cast<Type>(2) * std::atan(std::tan(fov_as_radians / static_cast<Type>(2)) * aspect);
|
||||
static_cast<Type>(2) * internal::atan(internal::tan(fov_as_radians / static_cast<Type>(2)) * aspect);
|
||||
|
||||
return radians_to_degrees(horizontal_fov);
|
||||
}
|
||||
@@ -55,11 +57,7 @@ namespace omath::angles
|
||||
|
||||
const Type range = max - min;
|
||||
|
||||
#ifdef OMATH_USE_GCEM
|
||||
Type wrapped_angle = gcem::fmod(angle - min, range);
|
||||
#else
|
||||
Type wrapped_angle = std::fmod(angle - min, range);
|
||||
#endif
|
||||
Type wrapped_angle = internal::fmod(angle - min, range);
|
||||
|
||||
if (wrapped_angle < 0)
|
||||
wrapped_angle += range;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace omath
|
||||
RollType roll;
|
||||
|
||||
[[nodiscard]]
|
||||
Vector3<ArithmeticType> as_vector3() const
|
||||
constexpr Vector3<ArithmeticType> as_vector3() const
|
||||
{
|
||||
return {pitch.as_degrees(), yaw.as_degrees(), roll.as_degrees()};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user