Add CoordinateSystem enum
This commit is contained in:
65
openVulkanoCpp/Math/CoordinateSystem.hpp
Normal file
65
openVulkanoCpp/Math/CoordinateSystem.hpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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 <optional>
|
||||||
|
#include <magic_enum/magic_enum.hpp>
|
||||||
|
|
||||||
|
namespace OpenVulkano::Math
|
||||||
|
{
|
||||||
|
class CoordinateSystem final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum System: uint8_t
|
||||||
|
{
|
||||||
|
RIGHT_HANDED_Y_UP = 0,
|
||||||
|
RIGHT_HANDED_Z_UP,
|
||||||
|
LEFT_HANDED_Y_UP,
|
||||||
|
LEFT_HANDED_Z_UP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Handedness: uint8_t { Right = 0, Left };
|
||||||
|
|
||||||
|
enum class UpAxis: uint8_t { Y, Z };
|
||||||
|
|
||||||
|
constexpr CoordinateSystem(System system = RIGHT_HANDED_Y_UP): m_system(system) {}
|
||||||
|
|
||||||
|
constexpr CoordinateSystem(Handedness handedness, UpAxis up): m_system(static_cast<System>(static_cast<uint8_t>(handedness) << 1 | static_cast<uint8_t>(up))) {}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr std::string_view GetName() const
|
||||||
|
{
|
||||||
|
return magic_enum::enum_name(m_system);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr static std::optional<CoordinateSystem> GetFromName(std::string_view name)
|
||||||
|
{
|
||||||
|
auto result = magic_enum::enum_cast<System>(name);
|
||||||
|
if (result.has_value()) return CoordinateSystem(result.value());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr Handedness GetHandedness() const { return static_cast<Handedness>(m_system >> 1); }
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr UpAxis GetUpAxis() const { return static_cast<UpAxis>(m_system & 1); }
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr operator System() const { return m_system; }
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr operator Handedness() const { return GetHandedness(); }
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr operator UpAxis() const { return GetUpAxis(); }
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr auto operator <=>(const CoordinateSystem& other) const { return m_system <=> other.m_system; }
|
||||||
|
[[nodiscard]] constexpr auto operator <=>(const System& other) const { return m_system <=> other; }
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool operator ==(const CoordinateSystem& other) const { return m_system == other.m_system; }
|
||||||
|
[[nodiscard]] constexpr bool operator ==(const System& other) const { return m_system == other; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
System m_system;
|
||||||
|
};
|
||||||
|
}
|
||||||
108
tests/Math/CoordinateSystemTest.cpp
Normal file
108
tests/Math/CoordinateSystemTest.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Math/CoordinateSystem.hpp"
|
||||||
|
#include <catch2/catch_all.hpp>
|
||||||
|
|
||||||
|
using namespace OpenVulkano::Math;
|
||||||
|
using Catch::Approx;
|
||||||
|
|
||||||
|
TEST_CASE("CoordinateSystem - Construction", "[CoordinateSystem]")
|
||||||
|
{
|
||||||
|
SECTION("Default constructor creates RIGHT_HANDED_Y_UP")
|
||||||
|
{
|
||||||
|
CoordinateSystem cs;
|
||||||
|
REQUIRE(cs == CoordinateSystem::RIGHT_HANDED_Y_UP);
|
||||||
|
REQUIRE(cs.GetHandedness() == CoordinateSystem::Handedness::Right);
|
||||||
|
REQUIRE(cs.GetUpAxis() == CoordinateSystem::UpAxis::Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Construct from System enum")
|
||||||
|
{
|
||||||
|
CoordinateSystem cs1(CoordinateSystem::RIGHT_HANDED_Y_UP);
|
||||||
|
REQUIRE(cs1.GetHandedness() == CoordinateSystem::Handedness::Right);
|
||||||
|
REQUIRE(cs1.GetUpAxis() == CoordinateSystem::UpAxis::Y);
|
||||||
|
|
||||||
|
CoordinateSystem cs2(CoordinateSystem::RIGHT_HANDED_Z_UP);
|
||||||
|
REQUIRE(cs2.GetHandedness() == CoordinateSystem::Handedness::Right);
|
||||||
|
REQUIRE(cs2.GetUpAxis() == CoordinateSystem::UpAxis::Z);
|
||||||
|
|
||||||
|
CoordinateSystem cs3(CoordinateSystem::LEFT_HANDED_Y_UP);
|
||||||
|
REQUIRE(cs3.GetHandedness() == CoordinateSystem::Handedness::Left);
|
||||||
|
REQUIRE(cs3.GetUpAxis() == CoordinateSystem::UpAxis::Y);
|
||||||
|
|
||||||
|
CoordinateSystem cs4(CoordinateSystem::LEFT_HANDED_Z_UP);
|
||||||
|
REQUIRE(cs4.GetHandedness() == CoordinateSystem::Handedness::Left);
|
||||||
|
REQUIRE(cs4.GetUpAxis() == CoordinateSystem::UpAxis::Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Construct from Handedness and UpAxis")
|
||||||
|
{
|
||||||
|
CoordinateSystem cs1(CoordinateSystem::Handedness::Right, CoordinateSystem::UpAxis::Y);
|
||||||
|
REQUIRE(cs1 == CoordinateSystem::RIGHT_HANDED_Y_UP);
|
||||||
|
|
||||||
|
CoordinateSystem cs2(CoordinateSystem::Handedness::Right, CoordinateSystem::UpAxis::Z);
|
||||||
|
REQUIRE(cs2 == CoordinateSystem::RIGHT_HANDED_Z_UP);
|
||||||
|
|
||||||
|
CoordinateSystem cs3(CoordinateSystem::Handedness::Left, CoordinateSystem::UpAxis::Y);
|
||||||
|
REQUIRE(cs3 == CoordinateSystem::LEFT_HANDED_Y_UP);
|
||||||
|
|
||||||
|
CoordinateSystem cs4(CoordinateSystem::Handedness::Left, CoordinateSystem::UpAxis::Z);
|
||||||
|
REQUIRE(cs4 == CoordinateSystem::LEFT_HANDED_Z_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("CoordinateSystem - Name conversion", "[CoordinateSystem]")
|
||||||
|
{
|
||||||
|
SECTION("GetName returns correct string representation")
|
||||||
|
{
|
||||||
|
REQUIRE(CoordinateSystem(CoordinateSystem::RIGHT_HANDED_Y_UP).GetName() == "RIGHT_HANDED_Y_UP");
|
||||||
|
REQUIRE(CoordinateSystem(CoordinateSystem::RIGHT_HANDED_Z_UP).GetName() == "RIGHT_HANDED_Z_UP");
|
||||||
|
REQUIRE(CoordinateSystem(CoordinateSystem::LEFT_HANDED_Y_UP).GetName() == "LEFT_HANDED_Y_UP");
|
||||||
|
REQUIRE(CoordinateSystem(CoordinateSystem::LEFT_HANDED_Z_UP).GetName() == "LEFT_HANDED_Z_UP");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("GetFromName parses valid names")
|
||||||
|
{
|
||||||
|
auto cs1 = CoordinateSystem::GetFromName("RIGHT_HANDED_Y_UP");
|
||||||
|
REQUIRE(cs1.has_value());
|
||||||
|
REQUIRE(cs1.value() == CoordinateSystem::RIGHT_HANDED_Y_UP);
|
||||||
|
|
||||||
|
auto cs2 = CoordinateSystem::GetFromName("LEFT_HANDED_Z_UP");
|
||||||
|
REQUIRE(cs2.has_value());
|
||||||
|
REQUIRE(cs2.value() == CoordinateSystem::LEFT_HANDED_Z_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("GetFromName returns nullopt for invalid names")
|
||||||
|
{
|
||||||
|
REQUIRE_FALSE(CoordinateSystem::GetFromName("INVALID_NAME").has_value());
|
||||||
|
REQUIRE_FALSE(CoordinateSystem::GetFromName("").has_value());
|
||||||
|
REQUIRE_FALSE(CoordinateSystem::GetFromName("right_handed_y_up").has_value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("CoordinateSystem - Conversion operators", "[CoordinateSystem]")
|
||||||
|
{
|
||||||
|
CoordinateSystem cs(CoordinateSystem::LEFT_HANDED_Z_UP);
|
||||||
|
|
||||||
|
SECTION("Convert to System")
|
||||||
|
{
|
||||||
|
CoordinateSystem::System sys = cs;
|
||||||
|
REQUIRE(sys == CoordinateSystem::LEFT_HANDED_Z_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Convert to Handedness")
|
||||||
|
{
|
||||||
|
CoordinateSystem::Handedness hand = cs;
|
||||||
|
REQUIRE(hand == CoordinateSystem::Handedness::Left);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Convert to UpAxis")
|
||||||
|
{
|
||||||
|
CoordinateSystem::UpAxis up = cs;
|
||||||
|
REQUIRE(up == CoordinateSystem::UpAxis::Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user