104 lines
3.2 KiB
C++
104 lines
3.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
|
|
|
|
#include "Math.hpp"
|
|
#include "CoordinateSystem.hpp"
|
|
|
|
namespace OpenVulkano::Math
|
|
{
|
|
class CoordinateSystemConverter
|
|
{
|
|
inline static Math::Matrix4i ROT_XP90 = { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1 };
|
|
inline static Math::Matrix4i ROT_XN90 = { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1 };
|
|
CoordinateSystem from, to;
|
|
|
|
public:
|
|
constexpr CoordinateSystemConverter(CoordinateSystem from, CoordinateSystem to) : from(from), to(to) {}
|
|
|
|
template<typename T, glm::qualifier Q>
|
|
[[nodiscard]] Vector<3, T, Q> Convert(const Vector<3, T, Q>& v) const
|
|
{
|
|
if (from == to) return v;
|
|
return ConvertHandedness(ConvertUp(v));
|
|
}
|
|
|
|
template<typename T, glm::qualifier Q>
|
|
[[nodiscard]] Vector<4, T, Q> Convert(const Vector<4, T, Q>& v) const
|
|
{
|
|
if (from == to) return v;
|
|
return { ConvertHandedness(ConvertUp(reinterpret_cast<const glm::vec<3,T,Q>&>(v))), v.w };
|
|
}
|
|
|
|
template<typename T, glm::qualifier Q>
|
|
[[nodiscard]] Matrix<3, T, Q> Convert(const Matrix<3, T, Q>& mat) const
|
|
{
|
|
if (from == to) return mat;
|
|
return ConvertHandedness(ConvertUp(mat));
|
|
}
|
|
|
|
template<typename T, glm::qualifier Q>
|
|
[[nodiscard]] Matrix<4, T, Q> Convert(const Matrix<4, T, Q>& mat) const
|
|
{
|
|
if (from == to) return mat;
|
|
return ConvertHandedness(ConvertUp(mat));
|
|
}
|
|
|
|
private:
|
|
// Conversion functions
|
|
template<typename T, glm::qualifier Q>
|
|
[[nodiscard]] Vector<3, T, Q> ConvertHandedness(const Vector<3, T, Q>& v) const
|
|
{
|
|
if (from.GetHandedness() == to.GetHandedness()) return v;
|
|
if (to == CoordinateSystem::UpAxis::Y)
|
|
return { v.x, v.y, -v.z };
|
|
return { v.x, -v.y, v.z };
|
|
}
|
|
|
|
template<typename T, glm::qualifier Q>
|
|
[[nodiscard]] Vector<3, T, Q> ConvertUp(const Vector<3, T, Q>& v) const
|
|
{
|
|
if (from.GetUpAxis() == to.GetUpAxis()) return v;
|
|
if (from.GetUpAxis() == CoordinateSystem::UpAxis::Y)
|
|
return { v.x, -v.z, v.y };
|
|
return { v.x, v.z, -v.y };
|
|
}
|
|
|
|
template<int S, typename T, glm::qualifier Q>
|
|
[[nodiscard]] Matrix<S, T, Q> ConvertHandedness(Matrix<S, T, Q> mat) const
|
|
{
|
|
constexpr int AXIS_Y = 1;
|
|
constexpr int AXIS_Z = 2;
|
|
if (from.GetHandedness() == to.GetHandedness()) return mat;
|
|
if (to == CoordinateSystem::UpAxis::Y)
|
|
for(int i = 0; i < S; i++) mat[i][AXIS_Z] = -mat[i][AXIS_Z];
|
|
else
|
|
for(int i = 0; i < S; i++) mat[i][AXIS_Y] = -mat[i][AXIS_Y];
|
|
return mat;
|
|
}
|
|
|
|
template<int S, typename T, glm::qualifier Q>
|
|
[[nodiscard]] Matrix<S, T, Q> ConvertUp(const Matrix<S, T, Q>& mat) const
|
|
{
|
|
if (from.GetUpAxis() == to.GetUpAxis()) return mat;
|
|
Matrix4i* conv;
|
|
Matrix4i* inverse;
|
|
if (from.GetUpAxis() == CoordinateSystem::UpAxis::Y && to.GetUpAxis() == CoordinateSystem::UpAxis::Z)
|
|
{
|
|
conv = &ROT_XP90;
|
|
inverse = &ROT_XN90;
|
|
}
|
|
else if (from.GetUpAxis() == CoordinateSystem::UpAxis::Z && to.GetUpAxis() == CoordinateSystem::UpAxis::Y)
|
|
{
|
|
conv = &ROT_XN90;
|
|
inverse = &ROT_XP90;
|
|
}
|
|
|
|
return Matrix<S, T, Q>(*conv) * mat * Matrix<S, T, Q>(*inverse);
|
|
}
|
|
};
|
|
} |