mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 07:03:25 +00:00
added new class
This commit is contained in:
156
include/omath/Angle.hpp
Normal file
156
include/omath/Angle.hpp
Normal file
@@ -0,0 +1,156 @@
|
||||
//
|
||||
// Created by Orange on 11/30/2024.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "omath/Angles.hpp"
|
||||
|
||||
|
||||
namespace omath
|
||||
{
|
||||
enum class AngleFlags
|
||||
{
|
||||
Normalized = 0,
|
||||
Clamped = 1,
|
||||
};
|
||||
|
||||
template<class Type, Type min = 0, Type max = 360, AngleFlags flags = AngleFlags::Normalized>
|
||||
requires std::is_arithmetic_v<Type>
|
||||
class Angle
|
||||
{
|
||||
Type m_angle;
|
||||
public:
|
||||
|
||||
constexpr explicit Angle(const Type& degrees)
|
||||
{
|
||||
if constexpr (flags == AngleFlags::Normalized)
|
||||
m_angle = angles::WrapAngle(degrees, min, max);
|
||||
|
||||
else if constexpr (flags == AngleFlags::Clamped)
|
||||
m_angle = std::clamp(degrees, min, max);
|
||||
else
|
||||
{
|
||||
static_assert(false);
|
||||
std::unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr static Angle FromDegrees(const Type& degrees)
|
||||
{
|
||||
return {degrees};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr static Angle FromRadians(const Type& degrees)
|
||||
{
|
||||
return {angles::RadiansToDegrees(degrees)};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const Type& operator*() const
|
||||
{
|
||||
return m_angle;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Type& operator*()
|
||||
{
|
||||
return m_angle;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const Type& Value() const
|
||||
{
|
||||
return **std::as_const(this);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Type& Value()
|
||||
{
|
||||
return **this;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Type AsRadians() const
|
||||
{
|
||||
return angles::RadiansToDegrees(m_angle);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Type Sin() const
|
||||
{
|
||||
return std::sin(AsRadians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Type Cos() const
|
||||
{
|
||||
return std::sin(AsRadians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Type Tan() const
|
||||
{
|
||||
return std::tan(AsRadians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Type Atan() const
|
||||
{
|
||||
return std::atan(AsRadians());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Type Cot() const
|
||||
{
|
||||
return Cos() / Sin();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Angle& operator+=(const Type& other)
|
||||
{
|
||||
if constexpr (flags == AngleFlags::Normalized)
|
||||
m_angle = angles::WrapAngle(m_angle + other, min, max);
|
||||
|
||||
else if constexpr (flags == AngleFlags::Clamped)
|
||||
m_angle = std::clamp(m_angle + other, min, max);
|
||||
else
|
||||
{
|
||||
static_assert(false);
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Angle& operator-=(const Type& other)
|
||||
{
|
||||
return operator+=(-other);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Angle& operator+(const Type& other)
|
||||
{
|
||||
if constexpr (flags == AngleFlags::Normalized)
|
||||
return {angles::WrapAngle(m_angle + other, min, max)};
|
||||
|
||||
else if constexpr (flags == AngleFlags::Clamped)
|
||||
return {std::clamp(m_angle + other, min, max)};
|
||||
|
||||
else
|
||||
static_assert(false);
|
||||
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Angle& operator-(const Type& other)
|
||||
{
|
||||
return operator+(-other);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
@@ -4,21 +4,23 @@
|
||||
|
||||
#pragma once
|
||||
#include <numbers>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
namespace omath::angles
|
||||
{
|
||||
template<class type>
|
||||
requires std::is_floating_point_v<type>
|
||||
[[nodiscard]] constexpr float RadiansToDegrees(const type& radians)
|
||||
template<class Type>
|
||||
requires std::is_floating_point_v<Type>
|
||||
[[nodiscard]] constexpr float RadiansToDegrees(const Type& radians)
|
||||
{
|
||||
return radians * (type(180) / std::numbers::pi_v<type>);
|
||||
return radians * (Type(180) / std::numbers::pi_v<Type>);
|
||||
}
|
||||
|
||||
template<class type>
|
||||
requires std::is_floating_point_v<type>
|
||||
[[nodiscard]] constexpr float DegreesToRadians(const type& degrees)
|
||||
template<class Type>
|
||||
requires std::is_floating_point_v<Type>
|
||||
[[nodiscard]] constexpr float DegreesToRadians(const Type& degrees)
|
||||
{
|
||||
return degrees * (std::numbers::pi_v<type> / type(180));
|
||||
return degrees * (std::numbers::pi_v<Type> / Type(180));
|
||||
}
|
||||
|
||||
template<class type>
|
||||
@@ -32,14 +34,31 @@ namespace omath::angles
|
||||
return RadiansToDegrees(vertFov);
|
||||
}
|
||||
|
||||
template<class type>
|
||||
requires std::is_floating_point_v<type>
|
||||
[[nodiscard]] type VerticalFovToHorizontal(const type& vertFov, const type& aspect)
|
||||
template<class Type>
|
||||
requires std::is_floating_point_v<Type>
|
||||
[[nodiscard]] Type VerticalFovToHorizontal(const Type& vertFov, const Type& aspect)
|
||||
{
|
||||
const auto fovRad = DegreesToRadians(vertFov);
|
||||
|
||||
const auto horFov = type(2) * std::atan(std::tan(fovRad / type(2)) * aspect);
|
||||
const auto horFov = Type(2) * std::atan(std::tan(fovRad / Type(2)) * aspect);
|
||||
|
||||
return RadiansToDegrees(horFov);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
requires std::is_arithmetic_v<Type>
|
||||
[[nodiscard]] Type WrapAngle(const Type& angle, const Type& min, const Type& max)
|
||||
{
|
||||
if (angle <= max && angle >= min)
|
||||
return angle;
|
||||
|
||||
const Type range = max - min;
|
||||
|
||||
Type wrappedAngle = std::fmod(angle - min, range);
|
||||
|
||||
if (wrappedAngle < 0)
|
||||
wrappedAngle += range;
|
||||
|
||||
return wrappedAngle + min;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace omath
|
||||
};
|
||||
|
||||
template<size_t Rows = 0, size_t Columns = 0, class Type = float, MatStoreType StoreType = MatStoreType::ROW_MAJOR>
|
||||
requires (std::is_floating_point_v<Type> || std::is_integral_v<Type>)
|
||||
requires std::is_arithmetic_v<Type>
|
||||
class Mat final
|
||||
{
|
||||
public:
|
||||
@@ -34,7 +34,7 @@ namespace omath
|
||||
Clear();
|
||||
}
|
||||
|
||||
constexpr Mat(const std::initializer_list<std::initializer_list<Type>>& rows)
|
||||
constexpr Mat(const std::initializer_list<std::initializer_list<Type> >& rows)
|
||||
{
|
||||
if (rows.size() != Rows)
|
||||
throw std::invalid_argument("Initializer list rows size does not match template parameter Rows");
|
||||
@@ -59,12 +59,12 @@ namespace omath
|
||||
std::copy_n(rawData, Rows * Columns, m_data.begin());
|
||||
}
|
||||
|
||||
constexpr Mat(const Mat &other) noexcept
|
||||
constexpr Mat(const Mat& other) noexcept
|
||||
{
|
||||
m_data = other.m_data;
|
||||
}
|
||||
|
||||
constexpr Mat(Mat &&other) noexcept
|
||||
constexpr Mat(Mat&& other) noexcept
|
||||
{
|
||||
m_data = std::move(other.m_data);
|
||||
}
|
||||
@@ -87,7 +87,7 @@ namespace omath
|
||||
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)
|
||||
throw std::out_of_range("Index out of range");
|
||||
@@ -105,9 +105,9 @@ namespace omath
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Type &At(const size_t rowIndex, const size_t columnIndex)
|
||||
[[nodiscard]] constexpr Type& At(const size_t rowIndex, const size_t columnIndex)
|
||||
{
|
||||
return const_cast<Type &>(std::as_const(*this).At(rowIndex, columnIndex));
|
||||
return const_cast<Type&>(std::as_const(*this).At(rowIndex, columnIndex));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -126,14 +126,15 @@ namespace omath
|
||||
Set(0);
|
||||
}
|
||||
|
||||
constexpr void Set(const Type &value) noexcept
|
||||
constexpr void Set(const Type& value) noexcept
|
||||
{
|
||||
std::ranges::fill(m_data, value);
|
||||
}
|
||||
|
||||
// Operator overloading for multiplication with another Mat
|
||||
template<size_t OtherColumns>
|
||||
constexpr Mat<Rows, OtherColumns, Type, StoreType> operator*(const Mat<Columns, OtherColumns, Type, StoreType> &other) const
|
||||
constexpr Mat<Rows, OtherColumns, Type, StoreType> operator*(
|
||||
const Mat<Columns, OtherColumns, Type, StoreType>& other) const
|
||||
{
|
||||
Mat<Rows, OtherColumns, Type, StoreType> result;
|
||||
|
||||
@@ -148,7 +149,7 @@ namespace omath
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr Mat &operator*=(const Type &f) noexcept
|
||||
constexpr Mat& operator*=(const Type& f) noexcept
|
||||
{
|
||||
for (size_t i = 0; i < Rows; ++i)
|
||||
for (size_t j = 0; j < Columns; ++j)
|
||||
@@ -157,19 +158,20 @@ namespace omath
|
||||
}
|
||||
|
||||
template<size_t OtherColumns>
|
||||
constexpr Mat<Rows, OtherColumns, Type, StoreType> operator*=(const Mat<Columns, OtherColumns, Type, StoreType> &other)
|
||||
constexpr Mat<Rows, OtherColumns, Type, StoreType> operator*=(
|
||||
const Mat<Columns, OtherColumns, Type, StoreType>& other)
|
||||
{
|
||||
return *this = *this * other;
|
||||
}
|
||||
|
||||
constexpr Mat operator*(const Type &f) const noexcept
|
||||
constexpr Mat operator*(const Type& f) const noexcept
|
||||
{
|
||||
Mat result(*this);
|
||||
result *= f;
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr Mat &operator/=(const Type &f) noexcept
|
||||
constexpr Mat& operator/=(const Type& f) noexcept
|
||||
{
|
||||
for (size_t i = 0; i < Rows; ++i)
|
||||
for (size_t j = 0; j < Columns; ++j)
|
||||
@@ -177,14 +179,14 @@ namespace omath
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Mat operator/(const Type &f) const noexcept
|
||||
constexpr Mat operator/(const Type& f) const noexcept
|
||||
{
|
||||
Mat result(*this);
|
||||
result /= f;
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr Mat &operator=(const Mat &other) noexcept
|
||||
constexpr Mat& operator=(const Mat& other) noexcept
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
@@ -194,7 +196,7 @@ namespace omath
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Mat &operator=(Mat &&other) noexcept
|
||||
constexpr Mat& operator=(Mat&& other) noexcept
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
@@ -260,15 +262,15 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const std::array<Type, Rows*Columns>& RawArray() const
|
||||
constexpr const std::array<Type, Rows * Columns>& RawArray() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr std::array<Type, Rows*Columns>& RawArray()
|
||||
constexpr std::array<Type, Rows * Columns>& RawArray()
|
||||
{
|
||||
return const_cast<std::array<Type, Rows*Columns>>(std::as_const(*this).RawArray());
|
||||
return const_cast<std::array<Type, Rows * Columns>>(std::as_const(*this).RawArray());
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -289,20 +291,20 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool operator==(const Mat & mat) const
|
||||
bool operator==(const Mat& mat) const
|
||||
{
|
||||
return m_data == mat.m_data;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool operator!=(const Mat & mat) const
|
||||
bool operator!=(const Mat& mat) const
|
||||
{
|
||||
return !operator==(mat);
|
||||
}
|
||||
|
||||
// Static methods that return fixed-size matrices
|
||||
[[nodiscard]]
|
||||
constexpr static Mat<4, 4> ToScreenMat(const Type &screenWidth, const Type &screenHeight) noexcept
|
||||
constexpr static Mat<4, 4> ToScreenMat(const Type& screenWidth, const Type& screenHeight) noexcept
|
||||
{
|
||||
return
|
||||
{
|
||||
@@ -314,7 +316,7 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr static Mat<4, 4> TranslationMat(const Vector3 &diff) noexcept
|
||||
constexpr static Mat<4, 4> TranslationMat(const Vector3& diff) noexcept
|
||||
{
|
||||
return
|
||||
{
|
||||
@@ -326,24 +328,24 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr static Mat<4, 4> OrientationMat(const Vector3 &forward, const Vector3 &right,
|
||||
const Vector3 &up) noexcept
|
||||
constexpr static Mat<4, 4> OrientationMat(const Vector3& forward, const Vector3& right,
|
||||
const Vector3& up) noexcept
|
||||
{
|
||||
return
|
||||
{
|
||||
{right.x, up.x, forward.x, 0},
|
||||
{right.y, up.y, forward.y, 0},
|
||||
{right.z, up.z, forward.z, 0},
|
||||
{0, 0, 0, 1},
|
||||
{0, 0, 0, 1},
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr static Mat<4, 4> ProjectionMat(const Type &fieldOfView, const Type &aspectRatio,
|
||||
const Type &near, const Type &far, const Type &lensZoom) noexcept
|
||||
constexpr static Mat<4, 4> ProjectionMat(const Type& fieldOfView, const Type& aspectRatio,
|
||||
const Type& near, const Type& far, const Type& lensZoom) noexcept
|
||||
{
|
||||
const Type &fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2);
|
||||
const Type &frustumHeight = far - near;
|
||||
const Type& fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2);
|
||||
const Type& frustumHeight = far - near;
|
||||
|
||||
return
|
||||
{
|
||||
@@ -355,13 +357,13 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr static Mat<4, 1> MatRowFromVector(const Vector3 &vector) noexcept
|
||||
constexpr static Mat<4, 1> MatRowFromVector(const Vector3& vector) noexcept
|
||||
{
|
||||
return {{vector.x, vector.y, vector.z, 1}};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr static Mat<1, 4> MatColumnFromVector(const Vector3 &vector) noexcept
|
||||
constexpr static Mat<1, 4> MatColumnFromVector(const Vector3& vector) noexcept
|
||||
{
|
||||
return
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace omath
|
||||
{
|
||||
public:
|
||||
Triangle3d(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3);
|
||||
|
||||
Vector3 m_vertex1;
|
||||
Vector3 m_vertex2;
|
||||
Vector3 m_vertex3;
|
||||
@@ -29,4 +30,4 @@ namespace omath
|
||||
[[nodiscard]]
|
||||
Vector3 SideBVector() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
35
include/omath/ViewAngles.hpp
Normal file
35
include/omath/ViewAngles.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Created by Orange on 11/30/2024.
|
||||
//
|
||||
#pragma once
|
||||
#include <type_traits>
|
||||
#include <__algorithm/clamp.h>
|
||||
|
||||
#include "omath/Angles.hpp"
|
||||
|
||||
|
||||
namespace omath
|
||||
{
|
||||
template<class Type, Type min = 0, Type max = 360>
|
||||
requires std::is_arithmetic_v<Type>
|
||||
class ViewAngles
|
||||
{
|
||||
Type pitch;
|
||||
Type yaw;
|
||||
Type roll;
|
||||
|
||||
constexpr void SetPitch(const Type& newPitch)
|
||||
{
|
||||
pitch = std::clamp(newPitch, min, max);
|
||||
}
|
||||
void SetYaw(const Type& newYaw)
|
||||
{
|
||||
yaw = std::clamp(newYaw, min, max);
|
||||
}
|
||||
void SetRoll(const Type& newRoll)
|
||||
{
|
||||
roll = angles::WrapAngle(newRoll, min, max);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
@@ -12,6 +12,7 @@ namespace omath::source
|
||||
constexpr Vector3 kAbsForward = {1, 0, 0};
|
||||
|
||||
|
||||
|
||||
template<class Type> requires std::is_floating_point_v<Type> || std::is_integral_v<Type>
|
||||
[[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix(
|
||||
const float fieldOfView, const Type &aspectRatio, const Type &near, const Type &far)
|
||||
@@ -26,4 +27,6 @@ namespace omath::source
|
||||
{0, 0, 1, 0},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user