1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00
xn65/includes/xna/common/packedvalue.hpp

55 lines
1.4 KiB
C++
Raw Normal View History

2024-04-14 16:11:15 -03:00
#ifndef CXNA_COMMON_PACKEDVECTOR_HPP
#define CXNA_COMMON_PACKEDVECTOR_HPP
2024-05-18 16:22:00 -03:00
#include "numerics.hpp"
2024-04-14 16:11:15 -03:00
#include <cmath>
namespace xna {
class IPackedVector {
virtual Vector4 ToVector4() const = 0;
virtual void PackFromVector4(Vector4 const& vector) = 0;
};
template <typename T>
class IPackedVectorT {
virtual T PackedValue() const = 0;
virtual void PackedValue(T const& value) = 0;
};
2024-05-18 18:14:11 -03:00
struct PackUtils {
2024-04-14 16:11:15 -03:00
2024-11-11 09:58:40 -03:00
static constexpr float UnpackUNorm(uint32_t bitmask, uint32_t value) {
2024-04-14 16:11:15 -03:00
value &= bitmask;
return static_cast<float>(value) / static_cast<float>(bitmask);
2024-05-18 18:14:11 -03:00
}
2024-04-14 16:11:15 -03:00
2024-11-11 09:58:40 -03:00
static constexpr float UnpackSNorm(uint32_t bitmask, uint32_t value) {
2024-04-14 16:11:15 -03:00
const auto num1 = (bitmask + 1U) >> 1;
2024-11-11 09:58:40 -03:00
const auto ivalue = static_cast<int32_t>(value);
const auto inum1 = static_cast<int32_t>(num1);
const auto ibitmask = static_cast<int32_t>(bitmask);
2024-04-14 16:11:15 -03:00
if ((ivalue & inum1) != 0) {
if ((ivalue & ibitmask) == inum1)
return -1.0f;
value |= ~bitmask;
}
else
value &= bitmask;
const auto num2 = static_cast<float>(bitmask >> 1);
2024-11-11 09:58:40 -03:00
return static_cast<int32_t>(value) / num2;
2024-04-14 16:11:15 -03:00
}
2024-11-11 09:58:40 -03:00
static uint32_t PackUnsigned(float bitmask, float value);
static uint32_t PackSigned(uint32_t bitmask, float value);
static uint32_t PackUNorm(float bitmask, float value);
static uint32_t PackSNorm(uint32_t bitmask, float value);
2024-05-18 18:14:11 -03:00
static double ClampAndRound(float value, float min, float max);
2024-04-14 16:11:15 -03:00
};
}
#endif