Files
OpenVulkano/openVulkanoCpp/Math/Math.hpp
2025-10-18 21:22:11 +02:00

245 lines
7.8 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/extended_min_max.hpp>
#include <algorithm>
#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 tvec3<T, Q>& vec)
{
return std::max(vec.x, std::max(vec.y, vec.z));
}
template<typename T, qualifier Q>
T maxVal(const 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 tvec3<T, Q>& vec)
{
return std::min(vec.x, std::min(vec.y, vec.z));
}
template<typename T, qualifier Q>
T minVal(const tvec4<T, Q>& vec)
{
return std::min(std::min(vec.x, vec.y), std::min(vec.z, vec.w));
}
}
template<int S, typename T, glm::qualifier Q> using Matrix = glm::mat<S, S, T, Q>;
template<typename T> using Matrix2_SIMD = Matrix<2, T, glm::aligned>;
template<typename T> using Matrix3_SIMD = Matrix<3, T, glm::aligned>;
template<typename T> using Matrix4_SIMD = Matrix<4, T, glm::aligned>;
template<typename T> using Matrix2 = Matrix<2, T, glm::packed>;
template<typename T> using Matrix3 = Matrix<3, 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<int S, typename T, glm::qualifier Q> using Vector = glm::vec<S, T, Q>;
template<typename T> using Vector2_SIMD = Vector<2, T, glm::aligned>;
template<typename T> using Vector3_SIMD = Vector<3, T, glm::aligned>;
template<typename T> using Vector4_SIMD = Vector<4, T, glm::aligned>;
template<typename T> using Vector2 = Vector<2, T, glm::packed>;
template<typename T> using Vector3 = Vector<3, 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;
}
namespace glm
{
template<length_t L, typename T, typename F, qualifier Q>
requires (std::is_integral_v<T> && std::is_floating_point_v<F>)
vec<L, F, Q> operator / (const F lhs, const vec<L, T, Q>& rhs)
{
return lhs / glm::vec<L, F, Q>(rhs);
}
template<length_t L, typename T, typename F, qualifier Q>
requires (std::is_integral_v<T> && std::is_floating_point_v<F>)
vec<L, F, Q> operator / (const vec<L, F, Q>& lhs, const T rhs)
{
return lhs / static_cast<F>(rhs);
}
template<length_t L, typename T, typename F, qualifier Q>
requires (std::is_integral_v<T> && std::is_floating_point_v<F>)
vec<L, F, Q> operator * (const F lhs, const vec<L, T, Q>& rhs)
{
return lhs * glm::vec<L, F, Q>(rhs);
}
template<length_t L, typename F, typename T, qualifier Q>
requires (std::is_integral_v<T> && std::is_floating_point_v<F>)
vec<L, F, Q> operator * (const vec<L, F, Q>& lhs, const T rhs)
{
return lhs * static_cast<F>(rhs);
}
template<typename T, qualifier Q1, qualifier Q2>
vec<3, T, Q2> operator * (const mat<4, 4, T, Q1>& mat, const vec<3, T, Q2>& vec)
{
::glm::vec<4, T, Q1> v4(vec.x, vec.y, vec.z, 1);
return { mat * v4 };
}
}