#pragma once // Removed after upgrading to GLM 0.9.8 namespace gli{ namespace workaround{ namespace detail { union u3u3u2 { struct { uint x : 3; uint y : 3; uint z : 2; } data; uint8 pack; }; union u4u4 { struct { uint x : 4; uint y : 4; } data; uint8 pack; }; union u4u4u4u4 { struct { uint x : 4; uint y : 4; uint z : 4; uint w : 4; } data; uint16 pack; }; union u5u6u5 { struct { uint x : 5; uint y : 6; uint z : 5; } data; uint16 pack; }; union u5u5u5u1 { struct { uint x : 5; uint y : 5; uint z : 5; uint w : 1; } data; uint16 pack; }; union u9u9u9e5 { struct { uint x : 9; uint y : 9; uint z : 9; uint w : 5; } data; uint32 pack; }; template class vecType, bool isInteger, bool signedType> struct compute_compNormalize {}; template class vecType> struct compute_compNormalize { GLM_FUNC_QUALIFIER static vecType call(vecType const & v) { floatType const Min = static_cast(std::numeric_limits::min()); floatType const Max = static_cast(std::numeric_limits::max()); return (vecType(v) - Min) / (Max - Min) * static_cast(2) - static_cast(1); } }; template class vecType> struct compute_compNormalize { GLM_FUNC_QUALIFIER static vecType call(vecType const & v) { return vecType(v) / static_cast(std::numeric_limits::max()); } }; template class vecType> struct compute_compNormalize { GLM_FUNC_QUALIFIER static vecType call(vecType const & v) { return v; } }; template class vecType, bool isInteger, bool signedType> struct compute_compScale {}; template class vecType> struct compute_compScale { GLM_FUNC_QUALIFIER static vecType call(vecType const & v) { floatType const Max = static_cast(std::numeric_limits::max()) + static_cast(0.5); vecType const Scaled(v * Max); vecType const Result(Scaled - static_cast(0.5)); return Result; } }; template class vecType> struct compute_compScale { GLM_FUNC_QUALIFIER static vecType call(vecType const & v) { return vecType(vecType(v) * static_cast(std::numeric_limits::max())); } }; template class vecType> struct compute_compScale { GLM_FUNC_QUALIFIER static vecType call(vecType const & v) { return v; } }; template class vecType> struct compute_half {}; template struct compute_half { GLM_FUNC_QUALIFIER static tvec1 pack(tvec1 const & v) { int16 const Unpacked(glm::detail::toFloat16(v.x)); return tvec1(reinterpret_cast(Unpacked)); } GLM_FUNC_QUALIFIER static tvec1 unpack(tvec1 const & v) { return tvec1(glm::detail::toFloat32(reinterpret_cast(v.x))); } }; template struct compute_half { GLM_FUNC_QUALIFIER static tvec2 pack(tvec2 const & v) { tvec2 const Unpacked(glm::detail::toFloat16(v.x), glm::detail::toFloat16(v.y)); return tvec2( reinterpret_cast(Unpacked.x), reinterpret_cast(Unpacked.y)); } GLM_FUNC_QUALIFIER static tvec2 unpack(tvec2 const & v) { return tvec2( glm::detail::toFloat32(reinterpret_cast(v.x)), glm::detail::toFloat32(reinterpret_cast(v.y))); } }; template struct compute_half { GLM_FUNC_QUALIFIER static tvec3 pack(tvec3 const & v) { tvec3 const Unpacked(glm::detail::toFloat16(v.x), glm::detail::toFloat16(v.y), glm::detail::toFloat16(v.z)); return tvec3( reinterpret_cast(Unpacked.x), reinterpret_cast(Unpacked.y), reinterpret_cast(Unpacked.z)); } GLM_FUNC_QUALIFIER static tvec3 unpack(tvec3 const & v) { return tvec3( glm::detail::toFloat32(reinterpret_cast(v.x)), glm::detail::toFloat32(reinterpret_cast(v.y)), glm::detail::toFloat32(reinterpret_cast(v.z))); } }; template struct compute_half { GLM_FUNC_QUALIFIER static tvec4 pack(tvec4 const & v) { tvec4 const Unpacked(glm::detail::toFloat16(v.x), glm::detail::toFloat16(v.y), glm::detail::toFloat16(v.z), glm::detail::toFloat16(v.w)); return tvec4( reinterpret_cast(Unpacked.x), reinterpret_cast(Unpacked.y), reinterpret_cast(Unpacked.z), reinterpret_cast(Unpacked.w)); } GLM_FUNC_QUALIFIER static tvec4 unpack(tvec4 const & v) { return tvec4( glm::detail::toFloat32(reinterpret_cast(v.x)), glm::detail::toFloat32(reinterpret_cast(v.y)), glm::detail::toFloat32(reinterpret_cast(v.z)), glm::detail::toFloat32(reinterpret_cast(v.w))); } }; }//namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType compNormalize(vecType const & v) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'compNormalize' accepts only floating-point types for 'floatType' template parameter"); return detail::compute_compNormalize::is_integer, std::numeric_limits::is_signed>::call(v); } template class vecType> GLM_FUNC_QUALIFIER vecType compScale(vecType const & v) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'compScale' accepts only floating-point types for 'floatType' template parameter"); return detail::compute_compScale::is_integer, std::numeric_limits::is_signed>::call(v); } template class vecType> GLM_FUNC_QUALIFIER vecType packUnorm(vecType const & v) { GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); return vecType(round(clamp(v, static_cast(0), static_cast(1)) * static_cast(std::numeric_limits::max()))); } template class vecType> GLM_FUNC_QUALIFIER vecType unpackUnorm(vecType const & v) { GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); return vecType(v) * (static_cast(1) / static_cast(std::numeric_limits::max())); } GLM_FUNC_QUALIFIER uint8 packUnorm2x3_1x2(vec3 const & v) { u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(7.f, 7.f, 3.f))); detail::u3u3u2 Result; Result.data.x = Unpack.x; Result.data.y = Unpack.y; Result.data.z = Unpack.z; return Result.pack; } GLM_FUNC_QUALIFIER vec3 unpackUnorm2x3_1x2(uint8 v) { vec3 const ScaleFactor(1.f / 7.f, 1.f / 7.f, 1.f / 3.f); detail::u3u3u2 Unpack; Unpack.pack = v; return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor; } GLM_FUNC_QUALIFIER uint8 packUnorm2x4(vec2 const & v) { u32vec2 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f)); detail::u4u4 Result; Result.data.x = Unpack.x; Result.data.y = Unpack.y; return Result.pack; } GLM_FUNC_QUALIFIER vec2 unpackUnorm2x4(uint8 v) { float const ScaleFactor(1.f / 15.f); detail::u4u4 Unpack; Unpack.pack = v; return vec2(Unpack.data.x, Unpack.data.y) * ScaleFactor; } GLM_FUNC_QUALIFIER uint16 packUnorm4x4(vec4 const & v) { u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f)); detail::u4u4u4u4 Result; Result.data.x = Unpack.x; Result.data.y = Unpack.y; Result.data.z = Unpack.z; Result.data.w = Unpack.w; return Result.pack; } GLM_FUNC_QUALIFIER vec4 unpackUnorm4x4(uint16 v) { float const ScaleFactor(1.f / 15.f); detail::u4u4u4u4 Unpack; Unpack.pack = v; return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor; } GLM_FUNC_QUALIFIER uint16 packUnorm3x5_1x1(vec4 const & v) { u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(15.f, 15.f, 15.f, 1.f))); detail::u5u5u5u1 Result; Result.data.x = Unpack.x; Result.data.y = Unpack.y; Result.data.z = Unpack.z; Result.data.w = Unpack.w; return Result.pack; } GLM_FUNC_QUALIFIER vec4 unpackUnorm3x5_1x1(uint16 v) { vec4 const ScaleFactor(1.f / 15.f, 1.f / 15.f, 1.f / 15.f, 1.f); detail::u5u5u5u1 Unpack; Unpack.pack = v; return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor; } GLM_FUNC_QUALIFIER uint16 packUnorm1x5_1x6_1x5(vec3 const & v) { u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(15.f, 31.f, 15.f))); detail::u5u6u5 Result; Result.data.x = Unpack.x; Result.data.y = Unpack.y; Result.data.z = Unpack.z; return Result.pack; } GLM_FUNC_QUALIFIER vec3 unpackUnorm1x5_1x6_1x5(uint16 v) { vec3 const ScaleFactor(1.f / 15.f, 1.f / 31.f, 1.f / 15.f); detail::u5u6u5 Unpack; Unpack.pack = v; return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor; } GLM_FUNC_QUALIFIER uint32 packF3x9_E1x5(vec3 const & v) { float const SharedExpMax = (pow(2.0f, 9.0f - 1.0f) / pow(2.0f, 9.0f)) * pow(2.0f, 31.f - 15.f); vec3 const Color = clamp(v, 0.0f, SharedExpMax); float const MaxColor = max(Color.x, max(Color.y, Color.z)); float const ExpSharedP = max(-15.f - 1.f, floor(log2(MaxColor))) + 1.0f + 15.f; float const MaxShared = floor(MaxColor / pow(2.0f, (ExpSharedP - 16.f - 9.f)) + 0.5f); float const ExpShared = MaxShared == pow(2.0f, 9.0f) ? ExpSharedP + 1.0f : ExpSharedP; uvec3 const ColorComp(floor(Color / pow(2.f, (ExpShared - 15.f - 9.f)) + 0.5f)); detail::u9u9u9e5 Unpack; Unpack.data.x = ColorComp.x; Unpack.data.y = ColorComp.y; Unpack.data.z = ColorComp.z; Unpack.data.w = uint(ExpShared); return Unpack.pack; } GLM_FUNC_QUALIFIER vec3 unpackF3x9_E1x5(uint32 v) { detail::u9u9u9e5 Unpack; Unpack.pack = v; return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, Unpack.data.w - 15.f - 9.f); } template class vecType> GLM_FUNC_QUALIFIER vecType packHalf(vecType const & v) { return detail::compute_half::pack(v); } template class vecType> GLM_FUNC_QUALIFIER vecType unpackHalf(vecType const & v) { return detail::compute_half::unpack(v); } }//namespace workaround }//namespace gli