mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-14 15:33:26 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d1d06c24ca | |||
| 169011e238 | |||
| 934ca0da0a | |||
| 4200ef63a6 | |||
| 58e2c3b5b7 | |||
|
|
c3202a3bc3 | ||
|
|
39ab9d065d | ||
|
|
ed372a1c78 |
@@ -5,9 +5,10 @@ project(omath VERSION 1.0.1 LANGUAGES CXX)
|
|||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
|
||||||
option(OMATH_BUILD_TESTS "Build unit tests" ON)
|
option(OMATH_BUILD_TESTS "Build unit tests" OFF)
|
||||||
option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force compiler to treat them as errors" ON)
|
option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force compiler to treat them as errors" ON)
|
||||||
option(OMATH_BUILD_AS_SHARED_LIBRARY "Build Omath as .so or .dll" OFF)
|
option(OMATH_BUILD_AS_SHARED_LIBRARY "Build Omath as .so or .dll" OFF)
|
||||||
|
option(OMATH_USE_AVX2 "Omath will use AVX2 to boost performance" ON)
|
||||||
|
|
||||||
|
|
||||||
if (OMATH_BUILD_AS_SHARED_LIBRARY)
|
if (OMATH_BUILD_AS_SHARED_LIBRARY)
|
||||||
@@ -24,9 +25,15 @@ set_target_properties(omath PROPERTIES
|
|||||||
CXX_STANDARD 23
|
CXX_STANDARD 23
|
||||||
CXX_STANDARD_REQUIRED ON)
|
CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_compile_options(omath PRIVATE -mavx2 -mfma)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_compile_features(omath PUBLIC cxx_std_23)
|
target_compile_features(omath PUBLIC cxx_std_23)
|
||||||
|
|
||||||
|
if (OMATH_USE_AVX2)
|
||||||
|
target_compile_definitions(omath PUBLIC OMATH_USE_AVX2)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(source)
|
add_subdirectory(source)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace omath
|
|||||||
class Angle
|
class Angle
|
||||||
{
|
{
|
||||||
Type m_angle;
|
Type m_angle;
|
||||||
constexpr Angle(const Type& degrees)
|
constexpr explicit Angle(const Type& degrees)
|
||||||
{
|
{
|
||||||
if constexpr (flags == AngleFlags::Normalized)
|
if constexpr (flags == AngleFlags::Normalized)
|
||||||
m_angle = angles::WrapAngle(degrees, min, max);
|
m_angle = angles::WrapAngle(degrees, min, max);
|
||||||
@@ -36,7 +36,7 @@ namespace omath
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr static Angle FromDegrees(const Type& degrees)
|
constexpr static Angle FromDegrees(const Type& degrees)
|
||||||
{
|
{
|
||||||
return {degrees};
|
return Angle{degrees};
|
||||||
}
|
}
|
||||||
constexpr Angle() : m_angle(0)
|
constexpr Angle() : m_angle(0)
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ namespace omath
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr static Angle FromRadians(const Type& degrees)
|
constexpr static Angle FromRadians(const Type& degrees)
|
||||||
{
|
{
|
||||||
return {angles::RadiansToDegrees<Type>(degrees)};
|
return Angle{angles::RadiansToDegrees<Type>(degrees)};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@@ -146,7 +146,7 @@ namespace omath
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Angle operator-() const
|
constexpr Angle operator-() const
|
||||||
{
|
{
|
||||||
return {-m_angle};
|
return Angle{-m_angle};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,11 +34,13 @@ namespace omath
|
|||||||
class Mat final
|
class Mat final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
constexpr Mat()
|
constexpr Mat() noexcept
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
constexpr static MatStoreType GetStoreOrdering()
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr static MatStoreType GetStoreOrdering() noexcept
|
||||||
{
|
{
|
||||||
return StoreType;
|
return StoreType;
|
||||||
}
|
}
|
||||||
@@ -72,6 +74,7 @@ namespace omath
|
|||||||
m_data = other.m_data;
|
m_data = other.m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr Type& operator[](const size_t row, const size_t col)
|
constexpr Type& operator[](const size_t row, const size_t col)
|
||||||
{
|
{
|
||||||
return At(row, col);
|
return At(row, col);
|
||||||
@@ -100,7 +103,8 @@ namespace omath
|
|||||||
return {Rows, Columns};
|
return {Rows, Columns};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr const Type& At(const size_t rowIndex, const size_t columnIndex) const
|
[[nodiscard]]
|
||||||
|
constexpr const Type& At(const size_t rowIndex, const size_t columnIndex) const
|
||||||
{
|
{
|
||||||
if (rowIndex >= Rows || columnIndex >= Columns)
|
if (rowIndex >= Rows || columnIndex >= Columns)
|
||||||
throw std::out_of_range("Index out of range");
|
throw std::out_of_range("Index out of range");
|
||||||
@@ -177,6 +181,7 @@ namespace omath
|
|||||||
return *this = *this * other;
|
return *this = *this * other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr Mat operator*(const Type& f) const noexcept
|
constexpr Mat operator*(const Type& f) const noexcept
|
||||||
{
|
{
|
||||||
Mat result(*this);
|
Mat result(*this);
|
||||||
@@ -192,6 +197,7 @@ namespace omath
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr Mat operator/(const Type& f) const noexcept
|
constexpr Mat operator/(const Type& f) const noexcept
|
||||||
{
|
{
|
||||||
Mat result(*this);
|
Mat result(*this);
|
||||||
|
|||||||
@@ -6,6 +6,16 @@
|
|||||||
|
|
||||||
namespace omath
|
namespace omath
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
|\
|
||||||
|
| \
|
||||||
|
a | \ hypot
|
||||||
|
| \
|
||||||
|
-----
|
||||||
|
b
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
template<class Vector>
|
template<class Vector>
|
||||||
class Triangle final
|
class Triangle final
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -110,45 +110,45 @@ namespace omath
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr float DistToSqr(const Vector3& vOther) const
|
[[nodiscard]] constexpr Type DistToSqr(const Vector3& vOther) const
|
||||||
{
|
{
|
||||||
return (*this - vOther).LengthSqr();
|
return (*this - vOther).LengthSqr();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr float Dot(const Vector3& vOther) const
|
[[nodiscard]] constexpr Type Dot(const Vector3& vOther) const
|
||||||
{
|
{
|
||||||
return Vector2<Type>::Dot(vOther) + z * vOther.z;
|
return Vector2<Type>::Dot(vOther) + z * vOther.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
[[nodiscard]] constexpr float Length() const
|
[[nodiscard]] constexpr Type Length() const
|
||||||
{
|
{
|
||||||
return std::hypot(x, y, z);
|
return std::hypot(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr float Length2D() const
|
[[nodiscard]] constexpr Type Length2D() const
|
||||||
{
|
{
|
||||||
return Vector2::Length();
|
return Vector2::Length();
|
||||||
}
|
}
|
||||||
[[nodiscard]] float DistTo(const Vector3& vOther) const
|
[[nodiscard]] Type DistTo(const Vector3& vOther) const
|
||||||
{
|
{
|
||||||
return (*this - vOther).Length();
|
return (*this - vOther).Length();
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr Vector3 Normalized() const
|
[[nodiscard]] constexpr Vector3 Normalized() const
|
||||||
{
|
{
|
||||||
const float length = this->Length();
|
const Type length = this->Length();
|
||||||
|
|
||||||
return length != 0 ? *this / length : *this;
|
return length != 0 ? *this / length : *this;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] float Length() const
|
[[nodiscard]] Type Length() const
|
||||||
{
|
{
|
||||||
return std::hypot(this->x, this->y, z);
|
return std::hypot(this->x, this->y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Vector3 Normalized() const
|
[[nodiscard]] Vector3 Normalized() const
|
||||||
{
|
{
|
||||||
const float length = this->Length();
|
const Type length = this->Length();
|
||||||
|
|
||||||
return length != 0 ? *this / length : *this;
|
return length != 0 ? *this / length : *this;
|
||||||
}
|
}
|
||||||
@@ -158,14 +158,14 @@ namespace omath
|
|||||||
return Vector2<Type>::Length();
|
return Vector2<Type>::Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] float DistTo(const Vector3& vOther) const
|
[[nodiscard]] Type DistTo(const Vector3& vOther) const
|
||||||
{
|
{
|
||||||
return (*this - vOther).Length();
|
return (*this - vOther).Length();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] constexpr float LengthSqr() const
|
[[nodiscard]] constexpr Type LengthSqr() const
|
||||||
{
|
{
|
||||||
return Vector2<Type>::LengthSqr() + z * z;
|
return Vector2<Type>::LengthSqr() + z * z;
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ namespace omath
|
|||||||
this->x * v.y - this->y * v.x
|
this->x * v.y - this->y * v.x
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr float Sum() const
|
[[nodiscard]] constexpr Type Sum() const
|
||||||
{
|
{
|
||||||
return Sum2D() + z;
|
return Sum2D() + z;
|
||||||
}
|
}
|
||||||
@@ -238,12 +238,12 @@ namespace omath
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr float Sum2D() const
|
[[nodiscard]] constexpr Type Sum2D() const
|
||||||
{
|
{
|
||||||
return Vector2<Type>::Sum();
|
return Vector2<Type>::Sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr std::tuple<float, float, float> AsTuple() const
|
[[nodiscard]] constexpr std::tuple<Type, Type, Type> AsTuple() const
|
||||||
{
|
{
|
||||||
return std::make_tuple(this->x, this->y, z);
|
return std::make_tuple(this->x, this->y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace omath
|
|||||||
return Vector3<Type>::LengthSqr() + w * w;
|
return Vector3<Type>::LengthSqr() + w * w;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr float Dot(const Vector4& vOther) const
|
[[nodiscard]] constexpr Type Dot(const Vector4& vOther) const
|
||||||
{
|
{
|
||||||
return Vector3<Type>::Dot(vOther) + w * vOther.w;
|
return Vector3<Type>::Dot(vOther) + w * vOther.w;
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ namespace omath
|
|||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
constexpr Vector4& Clamp(const float min, const float max)
|
constexpr Vector4& Clamp(const Type& min, const Type& max)
|
||||||
{
|
{
|
||||||
this->x = std::clamp(this->x, min, max);
|
this->x = std::clamp(this->x, min, max);
|
||||||
this->y = std::clamp(this->y, min, max);
|
this->y = std::clamp(this->y, min, max);
|
||||||
@@ -126,7 +126,7 @@ namespace omath
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Vector4 operator*(const float scalar) const
|
constexpr Vector4 operator*(const Type& scalar) const
|
||||||
{
|
{
|
||||||
return {this->x * scalar, this->y * scalar, this->z * scalar, w * scalar};
|
return {this->x * scalar, this->y * scalar, this->z * scalar, w * scalar};
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ namespace omath
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Vector4 operator/(const float scalar) const
|
constexpr Vector4 operator/(const Type& scalar) const
|
||||||
{
|
{
|
||||||
return {this->x / scalar, this->y / scalar, this->z / scalar, w / scalar};
|
return {this->x / scalar, this->y / scalar, this->z / scalar, w / scalar};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace omath::projection
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
protected:
|
||||||
virtual void LookAt(const Vector3<float>& target) = 0;
|
virtual void LookAt(const Vector3<float>& target) = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual Mat4x4Type CalcViewMatrix() const = 0;
|
[[nodiscard]] virtual Mat4x4Type CalcViewMatrix() const = 0;
|
||||||
@@ -49,41 +49,44 @@ namespace omath::projection
|
|||||||
{
|
{
|
||||||
return CalcProjectionMatrix() * CalcViewMatrix();
|
return CalcProjectionMatrix() * CalcViewMatrix();
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
|
|
||||||
|
[[nodiscard]] const Mat4x4Type& GetViewProjectionMatrix() const
|
||||||
|
{
|
||||||
|
if (!m_viewProjectionMatrix.has_value())
|
||||||
|
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
||||||
|
|
||||||
|
return m_viewProjectionMatrix.value();
|
||||||
|
}
|
||||||
|
|
||||||
void SetFieldOfView(const FieldOfView& fov)
|
void SetFieldOfView(const FieldOfView& fov)
|
||||||
{
|
{
|
||||||
m_fieldOfView = fov;
|
m_fieldOfView = fov;
|
||||||
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNearPlane(const float near)
|
void SetNearPlane(const float near)
|
||||||
{
|
{
|
||||||
m_nearPlaneDistance = near;
|
m_nearPlaneDistance = near;
|
||||||
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFarPlane(const float far)
|
void SetFarPlane(const float far)
|
||||||
{
|
{
|
||||||
m_farPlaneDistance = far;
|
m_farPlaneDistance = far;
|
||||||
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetViewAngles(const ViewAnglesType& viewAngles)
|
void SetViewAngles(const ViewAnglesType& viewAngles)
|
||||||
{
|
{
|
||||||
m_viewAngles = viewAngles;
|
m_viewAngles = viewAngles;
|
||||||
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetOrigin(const Vector3<float>& origin)
|
void SetOrigin(const Vector3<float>& origin)
|
||||||
{
|
{
|
||||||
m_origin = origin;
|
m_origin = origin;
|
||||||
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetViewPort(const ViewPort& viewPort)
|
void SetViewPort(const ViewPort& viewPort)
|
||||||
{
|
{
|
||||||
m_viewPort = viewPort;
|
m_viewPort = viewPort;
|
||||||
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const FieldOfView& GetFieldOfView() const
|
[[nodiscard]] const FieldOfView& GetFieldOfView() const
|
||||||
@@ -113,10 +116,9 @@ namespace omath::projection
|
|||||||
|
|
||||||
[[nodiscard]] std::expected<Vector3<float>, Error> WorldToScreen(const Vector3<float>& worldPosition) const
|
[[nodiscard]] std::expected<Vector3<float>, Error> WorldToScreen(const Vector3<float>& worldPosition) const
|
||||||
{
|
{
|
||||||
if (!m_viewProjectionMatrix.has_value())
|
const auto& viewProjMatrix = GetViewProjectionMatrix();
|
||||||
m_viewProjectionMatrix = CalcViewProjectionMatrix();
|
|
||||||
|
|
||||||
auto projected = m_viewProjectionMatrix.value() * MatColumnFromVector<float, Mat4x4Type::GetStoreOrdering()>(worldPosition);
|
auto projected = viewProjMatrix * MatColumnFromVector<float, Mat4x4Type::GetStoreOrdering()>(worldPosition);
|
||||||
|
|
||||||
if (projected.At(3, 0) == 0.0f)
|
if (projected.At(3, 0) == 0.0f)
|
||||||
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
|
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
|
||||||
|
|||||||
@@ -2,13 +2,15 @@
|
|||||||
// Created by Vlad on 2/23/2025.
|
// Created by Vlad on 2/23/2025.
|
||||||
//
|
//
|
||||||
#include "omath/projectile_prediction/ProjPredEngineAVX2.hpp"
|
#include "omath/projectile_prediction/ProjPredEngineAVX2.hpp"
|
||||||
|
#include "source_location"
|
||||||
|
|
||||||
namespace omath::projectile_prediction
|
namespace omath::projectile_prediction
|
||||||
{
|
{
|
||||||
std::optional<Vector3<float>> ProjPredEngineAVX2::MaybeCalculateAimPoint(const Projectile& projectile,
|
std::optional<Vector3<float>>
|
||||||
const Target& target) const
|
ProjPredEngineAVX2::MaybeCalculateAimPoint([[maybe_unused]] const Projectile& projectile,
|
||||||
|
[[maybe_unused]] const Target& target) const
|
||||||
{
|
{
|
||||||
|
#ifdef OMATH_USE_AVX2
|
||||||
const float bulletGravity = m_gravityConstant * projectile.m_gravityScale;
|
const float bulletGravity = m_gravityConstant * projectile.m_gravityScale;
|
||||||
const float v0 = projectile.m_launchSpeed;
|
const float v0 = projectile.m_launchSpeed;
|
||||||
const float v0Sqr = v0 * v0;
|
const float v0Sqr = v0 * v0;
|
||||||
@@ -106,12 +108,13 @@ namespace omath::projectile_prediction
|
|||||||
}
|
}
|
||||||
ProjPredEngineAVX2::ProjPredEngineAVX2(const float gravityConstant, const float simulationTimeStep,
|
ProjPredEngineAVX2::ProjPredEngineAVX2(const float gravityConstant, const float simulationTimeStep,
|
||||||
const float maximumSimulationTime) :
|
const float maximumSimulationTime) :
|
||||||
m_gravityConstant(gravityConstant), m_simulationTimeStep(maximumSimulationTime),
|
m_gravityConstant(gravityConstant), m_simulationTimeStep(simulationTimeStep),
|
||||||
m_maximumSimulationTime(simulationTimeStep)
|
m_maximumSimulationTime(maximumSimulationTime)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
std::optional<float> ProjPredEngineAVX2::CalculatePitch(const Vector3<float>& projOrigin, const Vector3<float>& targetPos,
|
std::optional<float> ProjPredEngineAVX2::CalculatePitch(const Vector3<float>& projOrigin,
|
||||||
const float bulletGravity, const float v0, const float time)
|
const Vector3<float>& targetPos, const float bulletGravity,
|
||||||
|
const float v0, const float time)
|
||||||
{
|
{
|
||||||
if (time <= 0.0f)
|
if (time <= 0.0f)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -134,5 +137,9 @@ namespace omath::projectile_prediction
|
|||||||
const float d = std::sqrt(dSqr);
|
const float d = std::sqrt(dSqr);
|
||||||
const float tanTheta = term / d;
|
const float tanTheta = term / d;
|
||||||
return angles::RadiansToDegrees(std::atan(tanTheta));
|
return angles::RadiansToDegrees(std::atan(tanTheta));
|
||||||
|
#else
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::format("{} AVX2 feature is not enabled!", std::source_location::current().function_name()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} // namespace omath::projectile_prediction
|
} // namespace omath::projectile_prediction
|
||||||
|
|||||||
Reference in New Issue
Block a user