From f65353071438138737b7608d2fe2a432125482eb Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 10 Aug 2024 13:54:46 +0200 Subject: [PATCH] chore: improve api for vector packing for models --- src/Common/Game/IW3/CommonIW3.cpp | 24 +-- src/Common/Game/IW3/CommonIW3.h | 12 +- src/Common/Game/IW4/CommonIW4.cpp | 24 +-- src/Common/Game/IW4/CommonIW4.h | 12 +- src/Common/Game/IW5/CommonIW5.cpp | 24 +-- src/Common/Game/IW5/CommonIW5.h | 12 +- src/Common/Game/T5/CommonT5.cpp | 24 +-- src/Common/Game/T5/CommonT5.h | 12 +- src/Common/Game/T6/CommonT6.cpp | 24 +-- src/Common/Game/T6/CommonT6.h | 12 +- src/Common/Utils/Pack.cpp | 139 +++++++++++------- src/Common/Utils/Pack.h | 24 +-- .../IW3/AssetDumpers/AssetDumperXModel.cpp | 19 +-- .../IW4/AssetDumpers/AssetDumperXModel.cpp | 19 +-- .../IW5/AssetDumpers/AssetDumperXModel.cpp | 19 +-- .../T5/AssetDumpers/AssetDumperXModel.cpp | 19 +-- .../T6/AssetDumpers/AssetDumperXModel.cpp | 21 +-- 17 files changed, 201 insertions(+), 239 deletions(-) diff --git a/src/Common/Game/IW3/CommonIW3.cpp b/src/Common/Game/IW3/CommonIW3.cpp index cea4d616..11775d52 100644 --- a/src/Common/Game/IW3/CommonIW3.cpp +++ b/src/Common/Game/IW3/CommonIW3.cpp @@ -4,32 +4,32 @@ using namespace IW3; -PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in) +PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2]) { - return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast(in))}; + return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)}; } -PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in) +PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3]) { - return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast(in))}; + return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)}; } -GfxColor Common::Vec4PackGfxColor(const vec4_t* in) +GfxColor Common::Vec4PackGfxColor(const float (&in)[4]) { - return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast(in))}; + return GfxColor{pack32::Vec4PackGfxColor(in)}; } -void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out) +void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]) { - Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast(out)); + pack32::Vec2UnpackTexCoordsVU(in.packed, out); } -void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out) +void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]) { - Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast(out)); + pack32::Vec3UnpackUnitVecScaleBased(in.packed, out); } -void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out) +void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]) { - Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast(out)); + pack32::Vec4UnpackGfxColor(in.packed, out); } diff --git a/src/Common/Game/IW3/CommonIW3.h b/src/Common/Game/IW3/CommonIW3.h index 068c1c6f..a01a6feb 100644 --- a/src/Common/Game/IW3/CommonIW3.h +++ b/src/Common/Game/IW3/CommonIW3.h @@ -21,11 +21,11 @@ namespace IW3 return result; } - static PackedTexCoords Vec2PackTexCoords(const vec2_t* in); - static PackedUnitVec Vec3PackUnitVec(const vec3_t* in); - static GfxColor Vec4PackGfxColor(const vec4_t* in); - static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out); - static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out); - static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out); + static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]); + static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]); + static GfxColor Vec4PackGfxColor(const float (&in)[4]); + static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]); + static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]); + static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]); }; } // namespace IW3 diff --git a/src/Common/Game/IW4/CommonIW4.cpp b/src/Common/Game/IW4/CommonIW4.cpp index 6a512836..de6cc73d 100644 --- a/src/Common/Game/IW4/CommonIW4.cpp +++ b/src/Common/Game/IW4/CommonIW4.cpp @@ -20,32 +20,32 @@ int Common::StringTable_HashString(const char* str) return result; } -PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in) +PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2]) { - return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast(in))}; + return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)}; } -PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in) +PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3]) { - return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast(in))}; + return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)}; } -GfxColor Common::Vec4PackGfxColor(const vec4_t* in) +GfxColor Common::Vec4PackGfxColor(const float (&in)[4]) { - return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast(in))}; + return GfxColor{pack32::Vec4PackGfxColor(in)}; } -void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out) +void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]) { - Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast(out)); + pack32::Vec2UnpackTexCoordsVU(in.packed, out); } -void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out) +void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]) { - Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast(out)); + pack32::Vec3UnpackUnitVecScaleBased(in.packed, out); } -void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out) +void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]) { - Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast(out)); + pack32::Vec4UnpackGfxColor(in.packed, out); } diff --git a/src/Common/Game/IW4/CommonIW4.h b/src/Common/Game/IW4/CommonIW4.h index 05287502..9aaff02c 100644 --- a/src/Common/Game/IW4/CommonIW4.h +++ b/src/Common/Game/IW4/CommonIW4.h @@ -28,11 +28,11 @@ namespace IW4 static int StringTable_HashString(const char* str); - static PackedTexCoords Vec2PackTexCoords(const vec2_t* in); - static PackedUnitVec Vec3PackUnitVec(const vec3_t* in); - static GfxColor Vec4PackGfxColor(const vec4_t* in); - static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out); - static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out); - static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out); + static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]); + static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]); + static GfxColor Vec4PackGfxColor(const float (&in)[4]); + static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]); + static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]); + static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]); }; } // namespace IW4 diff --git a/src/Common/Game/IW5/CommonIW5.cpp b/src/Common/Game/IW5/CommonIW5.cpp index ee552be2..79379dd4 100644 --- a/src/Common/Game/IW5/CommonIW5.cpp +++ b/src/Common/Game/IW5/CommonIW5.cpp @@ -20,32 +20,32 @@ int Common::StringTable_HashString(const char* str) return result; } -PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in) +PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2]) { - return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast(in))}; + return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)}; } -PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in) +PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3]) { - return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast(in))}; + return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)}; } -GfxColor Common::Vec4PackGfxColor(const vec4_t* in) +GfxColor Common::Vec4PackGfxColor(const float (&in)[4]) { - return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast(in))}; + return GfxColor{pack32::Vec4PackGfxColor(in)}; } -void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out) +void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]) { - Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast(out)); + pack32::Vec2UnpackTexCoordsVU(in.packed, out); } -void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out) +void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]) { - Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast(out)); + pack32::Vec3UnpackUnitVecScaleBased(in.packed, out); } -void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out) +void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]) { - Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast(out)); + pack32::Vec4UnpackGfxColor(in.packed, out); } diff --git a/src/Common/Game/IW5/CommonIW5.h b/src/Common/Game/IW5/CommonIW5.h index 7e12cc38..8347674c 100644 --- a/src/Common/Game/IW5/CommonIW5.h +++ b/src/Common/Game/IW5/CommonIW5.h @@ -9,11 +9,11 @@ namespace IW5 public: static int StringTable_HashString(const char* str); - static PackedTexCoords Vec2PackTexCoords(const vec2_t* in); - static PackedUnitVec Vec3PackUnitVec(const vec3_t* in); - static GfxColor Vec4PackGfxColor(const vec4_t* in); - static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out); - static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out); - static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out); + static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]); + static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]); + static GfxColor Vec4PackGfxColor(const float (&in)[4]); + static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]); + static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]); + static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]); }; } // namespace IW5 diff --git a/src/Common/Game/T5/CommonT5.cpp b/src/Common/Game/T5/CommonT5.cpp index 313843f2..979f0300 100644 --- a/src/Common/Game/T5/CommonT5.cpp +++ b/src/Common/Game/T5/CommonT5.cpp @@ -58,32 +58,32 @@ int Common::Com_HashString(const char* str, const int len) return result; } -PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in) +PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2]) { - return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast(in))}; + return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)}; } -PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in) +PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3]) { - return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast(in))}; + return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)}; } -GfxColor Common::Vec4PackGfxColor(const vec4_t* in) +GfxColor Common::Vec4PackGfxColor(const float (&in)[4]) { - return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast(in))}; + return GfxColor{pack32::Vec4PackGfxColor(in)}; } -void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out) +void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]) { - Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast(out)); + pack32::Vec2UnpackTexCoordsVU(in.packed, out); } -void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out) +void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]) { - Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast(out)); + pack32::Vec3UnpackUnitVecScaleBased(in.packed, out); } -void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out) +void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]) { - Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast(out)); + pack32::Vec4UnpackGfxColor(in.packed, out); } diff --git a/src/Common/Game/T5/CommonT5.h b/src/Common/Game/T5/CommonT5.h index 1be8add5..9cb67e29 100644 --- a/src/Common/Game/T5/CommonT5.h +++ b/src/Common/Game/T5/CommonT5.h @@ -11,11 +11,11 @@ namespace T5 static int Com_HashString(const char* str); static int Com_HashString(const char* str, int len); - static PackedTexCoords Vec2PackTexCoords(const vec2_t* in); - static PackedUnitVec Vec3PackUnitVec(const vec3_t* in); - static GfxColor Vec4PackGfxColor(const vec4_t* in); - static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out); - static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out); - static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out); + static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]); + static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]); + static GfxColor Vec4PackGfxColor(const float (&in)[4]); + static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]); + static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]); + static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]); }; } // namespace T5 diff --git a/src/Common/Game/T6/CommonT6.cpp b/src/Common/Game/T6/CommonT6.cpp index 744a3270..4c9287c5 100644 --- a/src/Common/Game/T6/CommonT6.cpp +++ b/src/Common/Game/T6/CommonT6.cpp @@ -58,32 +58,32 @@ int Common::Com_HashString(const char* str, const int len) return result; } -PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in) +PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2]) { - return PackedTexCoords{Pack32::Vec2PackTexCoords(in->v)}; + return PackedTexCoords{pack32::Vec2PackTexCoordsUV(in)}; } -PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in) +PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3]) { - return PackedUnitVec{Pack32::Vec3PackUnitVec(in->v)}; + return PackedUnitVec{pack32::Vec3PackUnitVecThirdBased(in)}; } -GfxColor Common::Vec4PackGfxColor(const vec4_t* in) +GfxColor Common::Vec4PackGfxColor(const float (&in)[4]) { - return GfxColor{Pack32::Vec4PackGfxColor(in->v)}; + return GfxColor{pack32::Vec4PackGfxColor(in)}; } -void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out) +void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]) { - Pack32::Vec2UnpackTexCoordsUV(in.packed, out->v); + pack32::Vec2UnpackTexCoordsUV(in.packed, out); } -void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out) +void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]) { - Pack32::Vec3UnpackUnitVecThirdBased(in.packed, out->v); + pack32::Vec3UnpackUnitVecThirdBased(in.packed, out); } -void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out) +void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]) { - Pack32::Vec4UnpackGfxColor(in.packed, out->v); + pack32::Vec4UnpackGfxColor(in.packed, out); } diff --git a/src/Common/Game/T6/CommonT6.h b/src/Common/Game/T6/CommonT6.h index 9e939f30..98e0cc6e 100644 --- a/src/Common/Game/T6/CommonT6.h +++ b/src/Common/Game/T6/CommonT6.h @@ -41,11 +41,11 @@ namespace T6 return result; } - static PackedTexCoords Vec2PackTexCoords(const vec2_t* in); - static PackedUnitVec Vec3PackUnitVec(const vec3_t* in); - static GfxColor Vec4PackGfxColor(const vec4_t* in); - static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out); - static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out); - static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out); + static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]); + static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]); + static GfxColor Vec4PackGfxColor(const float (&in)[4]); + static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]); + static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]); + static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]); }; } // namespace T6 diff --git a/src/Common/Utils/Pack.cpp b/src/Common/Utils/Pack.cpp index fbee907e..9008956f 100644 --- a/src/Common/Utils/Pack.cpp +++ b/src/Common/Utils/Pack.cpp @@ -4,6 +4,7 @@ #include #include +#include union PackUtil32 { @@ -14,70 +15,98 @@ union PackUtil32 uint8_t uc[4]; }; -uint32_t Pack32::Vec2PackTexCoords(const float* in) +namespace pack32 { - return static_cast(HalfFloat::ToHalf(in[0])) << 16 | HalfFloat::ToHalf(in[1]); -} + uint32_t Vec2PackTexCoordsUV(const float (&in)[2]) + { + return static_cast(HalfFloat::ToHalf(in[1])) << 16 | HalfFloat::ToHalf(in[0]); + } -uint32_t Pack32::Vec3PackUnitVec(const float* in) -{ - // TODO - return 0; -} + uint32_t Vec2PackTexCoordsVU(const float (&in)[2]) + { + return static_cast(HalfFloat::ToHalf(in[0])) << 16 | HalfFloat::ToHalf(in[1]); + } -uint32_t Pack32::Vec4PackGfxColor(const float* in) -{ - return static_cast(std::clamp(in[0], 0.0f, 1.0f) * 255.0f) | static_cast(std::clamp(in[1], 0.0f, 1.0f) * 255.0f) << 8 - | static_cast(std::clamp(in[2], 0.0f, 1.0f) * 255.0f) << 16 | static_cast(std::clamp(in[3], 0.0f, 1.0f) * 255.0f) << 24; -} + uint32_t Vec3PackUnitVecScaleBased(const float (&in)[3]) + { + // TODO: Implement + assert(false); + return 0; + } -void Pack32::Vec2UnpackTexCoordsUV(const uint32_t in, float* out) -{ - const auto inHiDw = static_cast((in >> 16) & UINT16_MAX); - const auto inLoDw = static_cast(in & UINT16_MAX); + uint32_t Vec3PackUnitVecThirdBased(const float (&in)[3]) + { + // This is based on the game's reversed code, the original code may have made a bit more sense + PackUtil32 x; + x.f = (in[0] - -24624.0939334638f) * 0.0001218318939208984f; + PackUtil32 y; + y.f = (in[1] - -24624.0939334638f) * 0.0001218318939208984f; + PackUtil32 z; + z.f = (in[2] - -24624.0939334638f) * 0.0001218318939208984f; - out[0] = HalfFloat::ToFloat(inLoDw); - out[1] = HalfFloat::ToFloat(inHiDw); -} + return x.u | y.u << 10u | z.u << 20u; + } -void Pack32::Vec2UnpackTexCoordsVU(const uint32_t in, float* out) -{ - const auto inHiDw = static_cast((in >> 16) & UINT16_MAX); - const auto inLoDw = static_cast(in & UINT16_MAX); + uint32_t Vec4PackGfxColor(const float (&in)[4]) + { + // clang-format off + return static_cast(std::clamp(in[0], 0.0f, 1.0f) * 255.0f) + | static_cast(std::clamp(in[1], 0.0f, 1.0f) * 255.0f) << 8 + | static_cast(std::clamp(in[2], 0.0f, 1.0f) * 255.0f) << 16 + | static_cast(std::clamp(in[3], 0.0f, 1.0f) * 255.0f) << 24; + // clang-format on + } - out[0] = HalfFloat::ToFloat(inHiDw); - out[1] = HalfFloat::ToFloat(inLoDw); -} + void Vec2UnpackTexCoordsUV(const uint32_t in, float (&out)[2]) + { + const auto inHiDw = static_cast((in >> 16) & std::numeric_limits::max()); + const auto inLoDw = static_cast(in & std::numeric_limits::max()); -void Pack32::Vec3UnpackUnitVecScaleBased(const uint32_t in, float* out) -{ - assert(out != nullptr); + out[0] = HalfFloat::ToFloat(inLoDw); + out[1] = HalfFloat::ToFloat(inHiDw); + } - PackUtil32 _in{in}; - const float decodeScale = (static_cast(_in.uc[3]) - -192.0f) / 32385.0f; - out[0] = (static_cast(_in.uc[0]) + -127.0f) * decodeScale; - out[1] = (static_cast(_in.uc[1]) + -127.0f) * decodeScale; - out[2] = (static_cast(_in.uc[2]) + -127.0f) * decodeScale; -} + void Vec2UnpackTexCoordsVU(const uint32_t in, float (&out)[2]) + { + const auto inHiDw = static_cast((in >> 16) & std::numeric_limits::max()); + const auto inLoDw = static_cast(in & std::numeric_limits::max()); -void Pack32::Vec3UnpackUnitVecThirdBased(const uint32_t in, float* out) -{ - PackUtil32 v0{(in >> 0) & 0x3FF}; - PackUtil32 v1{(in >> 10) & 0x3FF}; - PackUtil32 v2{(in >> 20) & 0x3FF}; + out[0] = HalfFloat::ToFloat(inHiDw); + out[1] = HalfFloat::ToFloat(inLoDw); + } - v0.u = v0.u - 2 * (v0.u & 0x200) + 0x40400000; - v1.u = v1.u - 2 * (v1.u & 0x200) + 0x40400000; - v2.u = v2.u - 2 * (v2.u & 0x200) + 0x40400000; - out[0] = (v0.f - 3.0f) * 8208.0312f; - out[1] = (v1.f - 3.0f) * 8208.0312f; - out[2] = (v2.f - 3.0f) * 8208.0312f; -} + void Vec3UnpackUnitVecScaleBased(const uint32_t in, float (&out)[3]) + { + assert(out != nullptr); -void Pack32::Vec4UnpackGfxColor(uint32_t in, float* out) -{ - out[0] = static_cast(in & UINT8_MAX) / 255.0f; - out[1] = static_cast((in >> 8) & UINT8_MAX) / 255.0f; - out[2] = static_cast((in >> 16) & UINT8_MAX) / 255.0f; - out[3] = static_cast((in >> 24) & UINT8_MAX) / 255.0f; -} + const PackUtil32 inUtil{in}; + const float decodeScale = (static_cast(inUtil.uc[3]) - -192.0f) / 32385.0f; + out[0] = (static_cast(inUtil.uc[0]) + -127.0f) * decodeScale; + out[1] = (static_cast(inUtil.uc[1]) + -127.0f) * decodeScale; + out[2] = (static_cast(inUtil.uc[2]) + -127.0f) * decodeScale; + } + + void Vec3UnpackUnitVecThirdBased(const uint32_t in, float (&out)[3]) + { + // This is based on the game's reversed code, the original code may have made a bit more sense + PackUtil32 v0{(in >> 0) & 0x3FF}; + PackUtil32 v1{(in >> 10) & 0x3FF}; + PackUtil32 v2{(in >> 20) & 0x3FF}; + + v0.u = v0.u - 2 * (v0.u & 0x200) + 0x40400000; + v1.u = v1.u - 2 * (v1.u & 0x200) + 0x40400000; + v2.u = v2.u - 2 * (v2.u & 0x200) + 0x40400000; + out[0] = (v0.f - 3.0f) * 8208.0312f; + out[1] = (v1.f - 3.0f) * 8208.0312f; + out[2] = (v2.f - 3.0f) * 8208.0312f; + } + + void Vec4UnpackGfxColor(const uint32_t in, float (&out)[4]) + { + out[0] = static_cast(in & std::numeric_limits::max()) / 255.0f; + out[1] = static_cast((in >> 8) & std::numeric_limits::max()) / 255.0f; + out[2] = static_cast((in >> 16) & std::numeric_limits::max()) / 255.0f; + out[3] = static_cast((in >> 24) & std::numeric_limits::max()) / 255.0f; + } + +} // namespace pack32 diff --git a/src/Common/Utils/Pack.h b/src/Common/Utils/Pack.h index 7ef679d7..5dd6743f 100644 --- a/src/Common/Utils/Pack.h +++ b/src/Common/Utils/Pack.h @@ -2,17 +2,17 @@ #include -class Pack32 +namespace pack32 { - Pack32() = default; + uint32_t Vec2PackTexCoordsUV(const float (&in)[2]); + uint32_t Vec2PackTexCoordsVU(const float (&in)[2]); + uint32_t Vec3PackUnitVecScaleBased(const float (&in)[3]); + uint32_t Vec3PackUnitVecThirdBased(const float (&in)[3]); + uint32_t Vec4PackGfxColor(const float (&in)[4]); -public: - static uint32_t Vec2PackTexCoords(const float* in); - static uint32_t Vec3PackUnitVec(const float* in); - static uint32_t Vec4PackGfxColor(const float* in); - static void Vec2UnpackTexCoordsUV(uint32_t in, float* out); - static void Vec2UnpackTexCoordsVU(uint32_t in, float* out); - static void Vec3UnpackUnitVecScaleBased(uint32_t in, float* out); - static void Vec3UnpackUnitVecThirdBased(uint32_t in, float* out); - static void Vec4UnpackGfxColor(uint32_t in, float* out); -}; + void Vec2UnpackTexCoordsUV(uint32_t in, float (&out)[2]); + void Vec2UnpackTexCoordsVU(uint32_t in, float (&out)[2]); + void Vec3UnpackUnitVecScaleBased(uint32_t in, float (&out)[3]); + void Vec3UnpackUnitVecThirdBased(uint32_t in, float (&out)[3]); + void Vec4UnpackGfxColor(uint32_t in, float (&out)[4]); +}; // namespace pack32 diff --git a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp index c69a0f9e..0775772f 100644 --- a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp @@ -218,27 +218,14 @@ namespace for (auto vertexIndex = 0u; vertexIndex < surface.vertCount; vertexIndex++) { const auto& v = surface.verts0[vertexIndex]; - vec2_t uv; - vec3_t normalVec; - vec4_t color; - - Common::Vec2UnpackTexCoords(v.texCoord, &uv); - Common::Vec3UnpackUnitVec(v.normal, &normalVec); - Common::Vec4UnpackGfxColor(v.color, &color); XModelVertex vertex{}; vertex.coordinates[0] = v.xyz[0]; vertex.coordinates[1] = v.xyz[1]; vertex.coordinates[2] = v.xyz[2]; - vertex.normal[0] = normalVec[0]; - vertex.normal[1] = normalVec[1]; - vertex.normal[2] = normalVec[2]; - vertex.color[0] = color[0]; - vertex.color[1] = color[1]; - vertex.color[2] = color[2]; - vertex.color[3] = color[3]; - vertex.uv[0] = uv[0]; - vertex.uv[1] = uv[1]; + Common::Vec3UnpackUnitVec(v.normal, vertex.normal); + Common::Vec4UnpackGfxColor(v.color, vertex.color); + Common::Vec2UnpackTexCoords(v.texCoord, vertex.uv); out.m_vertices.emplace_back(vertex); } diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp index 5a36bd6f..cee8cf25 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp @@ -207,27 +207,14 @@ namespace for (auto vertexIndex = 0u; vertexIndex < surface.vertCount; vertexIndex++) { const auto& v = surface.verts0[vertexIndex]; - vec2_t uv; - vec3_t normalVec; - vec4_t color; - - Common::Vec2UnpackTexCoords(v.texCoord, &uv); - Common::Vec3UnpackUnitVec(v.normal, &normalVec); - Common::Vec4UnpackGfxColor(v.color, &color); XModelVertex vertex{}; vertex.coordinates[0] = v.xyz[0]; vertex.coordinates[1] = v.xyz[1]; vertex.coordinates[2] = v.xyz[2]; - vertex.normal[0] = normalVec[0]; - vertex.normal[1] = normalVec[1]; - vertex.normal[2] = normalVec[2]; - vertex.color[0] = color[0]; - vertex.color[1] = color[1]; - vertex.color[2] = color[2]; - vertex.color[3] = color[3]; - vertex.uv[0] = uv[0]; - vertex.uv[1] = uv[1]; + Common::Vec3UnpackUnitVec(v.normal, vertex.normal); + Common::Vec4UnpackGfxColor(v.color, vertex.color); + Common::Vec2UnpackTexCoords(v.texCoord, vertex.uv); out.m_vertices.emplace_back(vertex); } diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp index 53b4bf5e..6a0af227 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp @@ -207,27 +207,14 @@ namespace for (auto vertexIndex = 0u; vertexIndex < surface.vertCount; vertexIndex++) { const auto& v = surface.verts0.packedVerts0[vertexIndex]; - vec2_t uv; - vec3_t normalVec; - vec4_t color; - - Common::Vec2UnpackTexCoords(v.texCoord, &uv); - Common::Vec3UnpackUnitVec(v.normal, &normalVec); - Common::Vec4UnpackGfxColor(v.color, &color); XModelVertex vertex{}; vertex.coordinates[0] = v.xyz[0]; vertex.coordinates[1] = v.xyz[1]; vertex.coordinates[2] = v.xyz[2]; - vertex.normal[0] = normalVec[0]; - vertex.normal[1] = normalVec[1]; - vertex.normal[2] = normalVec[2]; - vertex.color[0] = color[0]; - vertex.color[1] = color[1]; - vertex.color[2] = color[2]; - vertex.color[3] = color[3]; - vertex.uv[0] = uv[0]; - vertex.uv[1] = uv[1]; + Common::Vec3UnpackUnitVec(v.normal, vertex.normal); + Common::Vec4UnpackGfxColor(v.color, vertex.color); + Common::Vec2UnpackTexCoords(v.texCoord, vertex.uv); out.m_vertices.emplace_back(vertex); } diff --git a/src/ObjWriting/Game/T5/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/T5/AssetDumpers/AssetDumperXModel.cpp index 2fc1821c..b9102858 100644 --- a/src/ObjWriting/Game/T5/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/T5/AssetDumpers/AssetDumperXModel.cpp @@ -220,27 +220,14 @@ namespace for (auto vertexIndex = 0u; vertexIndex < surface.vertCount; vertexIndex++) { const auto& v = surface.verts0[vertexIndex]; - vec2_t uv; - vec3_t normalVec; - vec4_t color; - - Common::Vec2UnpackTexCoords(v.texCoord, &uv); - Common::Vec3UnpackUnitVec(v.normal, &normalVec); - Common::Vec4UnpackGfxColor(v.color, &color); XModelVertex vertex{}; vertex.coordinates[0] = v.xyz[0]; vertex.coordinates[1] = v.xyz[1]; vertex.coordinates[2] = v.xyz[2]; - vertex.normal[0] = normalVec.x; - vertex.normal[1] = normalVec.y; - vertex.normal[2] = normalVec.z; - vertex.color[0] = color.r; - vertex.color[1] = color.g; - vertex.color[2] = color.b; - vertex.color[3] = color.a; - vertex.uv[0] = uv.x; - vertex.uv[1] = uv.y; + Common::Vec3UnpackUnitVec(v.normal, vertex.normal); + Common::Vec4UnpackGfxColor(v.color, vertex.color); + Common::Vec2UnpackTexCoords(v.texCoord, vertex.uv); out.m_vertices.emplace_back(vertex); } diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperXModel.cpp index cb812d11..d160dc77 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperXModel.cpp @@ -246,29 +246,14 @@ namespace for (auto vertexIndex = 0u; vertexIndex < surface.vertCount; vertexIndex++) { const auto& v = surface.verts0[vertexIndex]; - vec2_t uv{}; - vec3_t normalVec{}; - vec3_t tangentVec{}; - vec4_t color{}; - - Common::Vec2UnpackTexCoords(v.texCoord, &uv); - Common::Vec3UnpackUnitVec(v.normal, &normalVec); - Common::Vec3UnpackUnitVec(v.tangent, &tangentVec); - Common::Vec4UnpackGfxColor(v.color, &color); XModelVertex vertex{}; vertex.coordinates[0] = v.xyz.x; vertex.coordinates[1] = v.xyz.y; vertex.coordinates[2] = v.xyz.z; - vertex.normal[0] = normalVec.x; - vertex.normal[1] = normalVec.y; - vertex.normal[2] = normalVec.z; - vertex.color[0] = color.x; - vertex.color[1] = color.y; - vertex.color[2] = color.z; - vertex.color[3] = color.w; - vertex.uv[0] = uv.x; - vertex.uv[1] = uv.y; + Common::Vec3UnpackUnitVec(v.normal, vertex.normal); + Common::Vec4UnpackGfxColor(v.color, vertex.color); + Common::Vec2UnpackTexCoords(v.texCoord, vertex.uv); out.m_vertices.emplace_back(vertex); }