diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 83ef890..56da810 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -47,7 +47,7 @@ add_executable (xna WIN32 "common/color.cpp" "common/collision.cpp" "common/gjk.cpp" -"common/numerics.cpp") +"common/numerics.cpp" "common/packedvalue.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/common/packedvalue.cpp b/framework/common/packedvalue.cpp new file mode 100644 index 0000000..170888e --- /dev/null +++ b/framework/common/packedvalue.cpp @@ -0,0 +1,38 @@ +#include "common/packedvalue.hpp" + +namespace xna { + Uint PackUtils::PackUnsigned(float bitmask, float value) { + return static_cast(ClampAndRound(value, 0.0f, bitmask)); + } + + Uint PackUtils::PackSigned(Uint bitmask, float value) { + const auto max = static_cast(bitmask >> 1); + const auto min = -max - 1.0F; + + return static_cast(ClampAndRound(value, min, max)) & bitmask; + } + + Uint PackUtils::PackUNorm(float bitmask, float value) { + value *= bitmask; + return static_cast(ClampAndRound(value, 0.0f, bitmask)); + } + + Uint PackUtils::PackSNorm(Uint bitmask, float value) { + const auto max = static_cast(bitmask >> 1); + value *= max; + return static_cast(ClampAndRound(value, -max, max)) & bitmask; + } + + double PackUtils::ClampAndRound(float value, float min, float max) { + if (isnan(value)) + return 0.0; + + if (isinf(value)) + return value < 0 ? static_cast(min) : static_cast(max); + + if (value < min) + return static_cast(min); + + return value > max ? static_cast(max) : std::round(static_cast(value)); + } +} \ No newline at end of file diff --git a/inc/common/packedvalue.hpp b/inc/common/packedvalue.hpp index 24e24bc..306b0e1 100644 --- a/inc/common/packedvalue.hpp +++ b/inc/common/packedvalue.hpp @@ -17,33 +17,12 @@ namespace xna { virtual void PackedValue(T const& value) = 0; }; - struct PackUtils { - static Uint PackUnsigned(float bitmask, float value) { - return static_cast(ClampAndRound(value, 0.0f, bitmask)); - } - - static Uint PackSigned(Uint bitmask, float value) { - const auto max = static_cast(bitmask >> 1); - const auto min = -max - 1.0F; - - return static_cast(ClampAndRound(value, min, max)) & bitmask; - } - - static Uint PackUNorm(float bitmask, float value) { - value *= bitmask; - return static_cast(ClampAndRound(value, 0.0f, bitmask)); - } + struct PackUtils { static constexpr float UnpackUNorm(Uint bitmask, Uint value) { value &= bitmask; return static_cast(value) / static_cast(bitmask); - } - - static Uint PackSNorm(Uint bitmask, float value) { - const auto max = static_cast(bitmask >> 1); - value *= max; - return static_cast(ClampAndRound(value, -max, max)) & bitmask; - } + } static constexpr float UnpackSNorm(Uint bitmask, Uint value) { const auto num1 = (bitmask + 1U) >> 1; @@ -66,18 +45,11 @@ namespace xna { return static_cast(value) / num2; } - static double ClampAndRound(float value, float min, float max) { - if (isnan(value)) - return 0.0; - - if (isinf(value)) - return value < 0 ? static_cast(min) : static_cast(max); - - if (value < min) - return static_cast(min); - - return value > max ? static_cast(max) : std::round(static_cast(value)); - } + static Uint PackUnsigned(float bitmask, float value); + static Uint PackSigned(Uint bitmask, float value); + static Uint PackUNorm(float bitmask, float value); + static Uint PackSNorm(Uint bitmask, float value); + static double ClampAndRound(float value, float min, float max); }; }