Files
OpenVulkano/openVulkanoCpp/Math/Math.hpp
2025-03-02 22:41:14 +01:00

222 lines
7.2 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#define GLM_FORECE_DEPTH_ZERO_TO_ONE // TODO handle this better
#include <glm/glm.hpp>
#include <glm/gtc/type_aligned.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/matrix_decompose.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/intersect.hpp>
#include <glm/gtx/io.hpp>
#include <numbers>
namespace OpenVulkano::Math
{
namespace Utils
{
using namespace glm;
template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
constexpr T Radians(T degree)
{
constexpr T CONVERSION = std::numbers::pi_v<T> / 180.0;
return degree * CONVERSION;
}
template<typename T>
constexpr T Square(T val)
{
return val * val;
}
// Ensures that a given angle is between 0 and 2 pi
template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
constexpr T NormalizeAngleRad(T angle)
{
constexpr T PIX2 = 2 * std::numbers::pi;
while (angle < 0)
{
angle += PIX2;
}
while (angle >= PIX2)
{
angle -= PIX2;
}
return angle;
}
template<typename T>
constexpr void SortPair(T& e1, T& e2)
{
if (e1 > e2) std::swap(e1, e2);
}
template<typename T, qualifier Q>
T maxVal(const glm::tvec3<T, Q>& vec)
{
return std::max(vec.x, std::max(vec.y, vec.z));
}
template<typename T, qualifier Q>
T maxVal(const glm::tvec4<T, Q>& vec)
{
return std::max(std::max(vec.x, vec.y), std::max(vec.z, vec.w));
}
template<typename T, qualifier Q>
T minVal(const glm::tvec3<T, Q>& vec)
{
return std::min(vec.x, std::min(vec.y, vec.z));
}
template<typename T, qualifier Q>
T minVal(const glm::tvec4<T, Q>& vec)
{
return std::min(std::min(vec.x, vec.y), std::min(vec.z, vec.w));
}
}
template<typename T> using Matrix2_SIMD = glm::tmat2x2<T, glm::aligned>;
template<typename T> using Matrix3_SIMD = glm::tmat3x3<T, glm::aligned>;
template<typename T> using Matrix4_SIMD = glm::tmat4x4<T, glm::aligned>;
template<typename T> using Matrix2 = glm::tmat2x2<T, glm::packed>;
template<typename T> using Matrix3 = glm::tmat3x3<T, glm::packed>;
template<typename T> using Matrix4 = Matrix4_SIMD<T>;
//template<typename T> using Matrix4 = glm::tmat4x4<T, glm::packed>;
typedef Matrix2<float> Matrix2f;
typedef Matrix2<double> Matrix2d;
typedef Matrix2<int32_t> Matrix2i;
typedef Matrix2<int64_t> Matrix2l;
typedef Matrix3<float> Matrix3f;
typedef Matrix3<double> Matrix3d;
typedef Matrix3<int32_t> Matrix3i;
typedef Matrix3<int64_t> Matrix3l;
typedef Matrix4<float> Matrix4f;
typedef Matrix4<double> Matrix4d;
typedef Matrix4<int32_t> Matrix4i;
typedef Matrix4<int64_t> Matrix4l;
typedef Matrix2_SIMD<float> Matrix2f_SIMD;
typedef Matrix2_SIMD<double> Matrix2d_SIMD;
typedef Matrix2_SIMD<int32_t> Matrix2i_SIMD;
typedef Matrix2_SIMD<int64_t> Matrix2l_SIMD;
typedef Matrix3_SIMD<float> Matrix3f_SIMD;
typedef Matrix3_SIMD<double> Matrix3d_SIMD;
typedef Matrix3_SIMD<int32_t> Matrix3i_SIMD;
typedef Matrix3_SIMD<int64_t> Matrix3l_SIMD;
typedef Matrix4_SIMD<float> Matrix4f_SIMD;
typedef Matrix4_SIMD<double> Matrix4d_SIMD;
typedef Matrix4_SIMD<int32_t> Matrix4i_SIMD;
typedef Matrix4_SIMD<int64_t> Matrix4l_SIMD;
template<typename T> using Vector2_SIMD = glm::tvec2<T, glm::aligned>;
template<typename T> using Vector3_SIMD = glm::tvec3<T, glm::aligned>;
template<typename T> using Vector4_SIMD = glm::tvec4<T, glm::aligned>;
template<typename T> using Vector2 = glm::tvec2<T, glm::packed>;
template<typename T> using Vector3 = glm::tvec3<T, glm::packed>;
template<typename T> using Vector4 = Vector4_SIMD<T>;
//template<typename T> using Vector4 = glm::tvec4<T, glm::packed>;
typedef Vector2<float> Vector2f;
typedef Vector2<double> Vector2d;
typedef Vector2<int8_t> Vector2c;
typedef Vector2<int16_t> Vector2s;
typedef Vector2<int32_t> Vector2i;
typedef Vector2<int64_t> Vector2l;
typedef Vector2<uint8_t> Vector2uc;
typedef Vector2<uint16_t> Vector2us;
typedef Vector2<uint32_t> Vector2ui;
typedef Vector2<uint64_t> Vector2ul;
typedef Vector3<float> Vector3f;
typedef Vector3<double> Vector3d;
typedef Vector3<int8_t> Vector3c;
typedef Vector3<int16_t> Vector3s;
typedef Vector3<int32_t> Vector3i;
typedef Vector3<int64_t> Vector3l;
typedef Vector3<uint8_t> Vector3uc;
typedef Vector3<uint16_t> Vector3us;
typedef Vector3<uint32_t> Vector3ui;
typedef Vector3<uint64_t> Vector3ul;
typedef Vector4<float> Vector4f;
typedef Vector4<double> Vector4d;
typedef Vector4<int8_t> Vector4c;
typedef Vector4<int16_t> Vector4s;
typedef Vector4<int32_t> Vector4i;
typedef Vector4<int64_t> Vector4l;
typedef Vector4<uint8_t> Vector4uc;
typedef Vector4<uint16_t> Vector4us;
typedef Vector4<uint32_t> Vector4ui;
typedef Vector4<uint64_t> Vector4ul;
typedef Vector2_SIMD<float> Vector2f_SIMD;
typedef Vector2_SIMD<double> Vector2d_SIMD;
typedef Vector2_SIMD<int8_t> Vector2c_SIMD;
typedef Vector2_SIMD<int16_t> Vector2s_SIMD;
typedef Vector2_SIMD<int32_t> Vector2i_SIMD;
typedef Vector2_SIMD<int64_t> Vector2l_SIMD;
typedef Vector2_SIMD<uint8_t> Vector2uc_SIMD;
typedef Vector2_SIMD<uint16_t> Vector2us_SIMD;
typedef Vector2_SIMD<uint32_t> Vector2ui_SIMD;
typedef Vector2_SIMD<uint64_t> Vector2ul_SIMD;
typedef Vector3_SIMD<float> Vector3f_SIMD;
typedef Vector3_SIMD<double> Vector3d_SIMD;
typedef Vector3_SIMD<int8_t> Vector3c_SIMD;
typedef Vector3_SIMD<int16_t> Vector3s_SIMD;
typedef Vector3_SIMD<int32_t> Vector3i_SIMD;
typedef Vector3_SIMD<int64_t> Vector3l_SIMD;
typedef Vector3_SIMD<uint8_t> Vector3uc_SIMD;
typedef Vector3_SIMD<uint16_t> Vector3us_SIMD;
typedef Vector3_SIMD<uint32_t> Vector3ui_SIMD;
typedef Vector3_SIMD<uint64_t> Vector3ul_SIMD;
typedef Vector4_SIMD<float> Vector4f_SIMD;
typedef Vector4_SIMD<double> Vector4d_SIMD;
typedef Vector4_SIMD<int8_t> Vector4c_SIMD;
typedef Vector4_SIMD<int16_t> Vector4s_SIMD;
typedef Vector4_SIMD<int32_t> Vector4i_SIMD;
typedef Vector4_SIMD<int64_t> Vector4l_SIMD;
typedef Vector4_SIMD<uint8_t> Vector4uc_SIMD;
typedef Vector4_SIMD<uint16_t> Vector4us_SIMD;
typedef Vector4_SIMD<uint32_t> Vector4ui_SIMD;
typedef Vector4_SIMD<uint64_t> Vector4ul_SIMD;
template<typename T> using Quaternion = glm::tquat<T, glm::aligned>;
typedef Quaternion<float> QuaternionF;
typedef Quaternion<double> QuaternionD;
typedef Quaternion<int> QuaternionI;
}
template<glm::length_t L, typename T, glm::qualifier Q, typename = std::enable_if_t<std::is_integral_v<T>>>
glm::vec<L, float, Q> operator / (const float lhs, const glm::vec<L, T, Q>& rhs)
{
return lhs / glm::vec<L, float, Q>(rhs);
}
template<glm::length_t L, typename T, glm::qualifier Q, typename = std::enable_if_t<std::is_integral_v<T>>>
glm::vec<L, float, Q> operator * (const float lhs, const glm::vec<L, T, Q>& rhs)
{
return lhs * glm::vec<L, float, Q>(rhs);
}
template<glm::length_t L, typename T, glm::qualifier Q, typename = std::enable_if_t<std::is_integral_v<T>>>
glm::vec<L, float, Q> operator * (const glm::vec<L, float, Q>& lhs, const T rhs)
{
return lhs * static_cast<float>(rhs);
}