From 9461fe05632662f4cf64e45aba534deddf6dbe4f Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Thu, 3 Feb 2022 07:24:41 -0800 Subject: [PATCH] More CModel RE, removed the separated normal types hack --- Runtime/Graphics/CCubeModel.cpp | 53 ++++++++++++++---- Runtime/Graphics/CCubeModel.hpp | 99 ++++++++++++++++++++++++--------- 2 files changed, 114 insertions(+), 38 deletions(-) diff --git a/Runtime/Graphics/CCubeModel.cpp b/Runtime/Graphics/CCubeModel.cpp index 40871c516..fab9dd65e 100644 --- a/Runtime/Graphics/CCubeModel.cpp +++ b/Runtime/Graphics/CCubeModel.cpp @@ -2,7 +2,7 @@ #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/CSimplePool.hpp" -//TODO Remove WIP once we've transitioned to this +// TODO Remove WIP once we've transitioned to this namespace metaforce::WIP { #pragma region CModel u32 CModel::sTotalMemory = 0; @@ -61,10 +61,11 @@ CModel::CModel(std::unique_ptr in, u32 dataLen, IObjectStore* store) for (u32 i = 0; i < numNormals; ++i) { if ((flags & 2) == 0) { const auto* norm = reinterpret_cast(normals + (i * (sizeof(float) * 3))); - m_floatNormals.emplace_back(hecl::SBig(norm[0]), hecl::SBig(norm[1]), hecl::SBig(norm[2])); + m_normals.emplace_back(hecl::SBig(norm[0]), hecl::SBig(norm[1]), hecl::SBig(norm[2])); } else { const auto* norm = reinterpret_cast(normals + (i * (sizeof(s16) * 3))); - m_shortNormals.emplace_back(std::array{hecl::SBig(norm[0]), hecl::SBig(norm[1]), hecl::SBig(norm[2])}); + m_normals.emplace_back(hecl::SBig(norm[0]) / 32676.f, hecl::SBig(norm[1]) / 32676.f, + hecl::SBig(norm[2]) / 32676.f); } } u32 numColors = hecl::SBig(*secSizeCur) / (sizeof(int)); @@ -102,17 +103,18 @@ CModel::CModel(std::unique_ptr in, u32 dataLen, IObjectStore* store) x8_surfaces.reserve(x8_surfaces.capacity() * 2); } - x8_surfaces.emplace_back(MemoryFromPartData(dataCur, secSizeCur)); + x8_surfaces.emplace_back(std::make_unique(MemoryFromPartData(dataCur, secSizeCur))); } const float* bounds = reinterpret_cast(data + 12); - m_aabox.min = {hecl::SBig(bounds[0]), hecl::SBig(bounds[1]), hecl::SBig(bounds[2])}; - m_aabox.max = {hecl::SBig(bounds[3]), hecl::SBig(bounds[4]), hecl::SBig(bounds[5])}; + zeus::CAABox aabox = zeus::skNullBox; + aabox.min = {hecl::SBig(bounds[0]), hecl::SBig(bounds[1]), hecl::SBig(bounds[2])}; + aabox.max = {hecl::SBig(bounds[3]), hecl::SBig(bounds[4]), hecl::SBig(bounds[5])}; /* This constructor has been changed from the original to take into account platform differences */ - x28_modelInst = std::make_unique(&x8_surfaces, &x18_matSets[0].x0_textures, x18_matSets[0].x10_data, - &m_positions, &m_floatNormals, &m_shortNormals, &m_colors, &m_floatUVs, - &m_shortUVs, &m_aabox, flags, true, -1); + x28_modelInst = + std::make_unique(&x8_surfaces, &x18_matSets[0].x0_textures, x18_matSets[0].x10_data, &m_positions, + &m_colors, &m_normals, &m_floatUVs, &m_shortUVs, aabox, flags, true, -1); sThisFrameList = this; if (x34_next != nullptr) { @@ -187,6 +189,23 @@ void CModel::DisableTextureTimeout() { sIsTextureTimeoutEnabled = false; } #pragma region CCubeModel +CCubeModel::CCubeModel(const std::vector>* surfaces, + const std::vector>* textures, const u8* materialData, + const std::vector* positions, const std::vector* colors, + const std::vector* normals, const std::vector* texCoords, + const std::vector>* packedTexCoords, const zeus::CAABox& aabox, u8 flags, + bool b1, u32 idx) +: x0_modelInstance(surfaces, materialData, positions, colors, normals, texCoords, packedTexCoords) +, x1c_textures(textures) +, x20_worldAABB(aabox) +, x40_24_(!b1) +, x41_visorFlags(flags) +, x44_idx(idx) { + for (const auto& surf : x0_modelInstance.Surfaces()) { + surf->SetParent(this); + } +} + void CCubeModel::UnlockTextures() {} void CCubeModel::MakeTexturesFromMats(const u8* ptr, std::vector>& texture, bool b1) {} @@ -194,7 +213,19 @@ void CCubeModel::MakeTexturesFromMats(const u8* ptr, std::vector(mem.readUint32Big()); + x18_nextSurface = reinterpret_cast(mem.readUint32Big()); + x1c_extraSize = mem.readUint32Big(); + x20_normal.readBig(mem); + if (x1c_extraSize > 0) { + x2c_bounds = zeus::CAABox::ReadBoundingBoxBig(mem); + } +} #pragma endregion CFactoryFnReturn FModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, @@ -204,4 +235,4 @@ CFactoryFnReturn FModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr return ret; } -} // namespace metaforce +} // namespace metaforce::WIP diff --git a/Runtime/Graphics/CCubeModel.hpp b/Runtime/Graphics/CCubeModel.hpp index 8941aa3d5..e515bb1c5 100644 --- a/Runtime/Graphics/CCubeModel.hpp +++ b/Runtime/Graphics/CCubeModel.hpp @@ -34,7 +34,7 @@ private: std::unique_ptr x0_data; u32 x4_dataLen; - std::vector x8_surfaces; + std::vector> x8_surfaces; // Was a vector of void* std::vector x18_matSets; std::unique_ptr x28_modelInst = nullptr; u16 x2c_ = 0; @@ -43,10 +43,8 @@ private: CModel* x34_next; u32 x38_lastFrame; /* Resident copies of maintained data */ - zeus::CAABox m_aabox; std::vector m_positions; - std::vector m_floatNormals; - std::vector> m_shortNormals; + std::vector m_normals; std::vector m_colors; std::vector m_floatUVs; std::vector> m_shortUVs; @@ -67,15 +65,60 @@ public: #pragma region CCubeModel class CCubeModel { +private: + class ModelInstance { + const std::vector>* x0_surfacePtrs; // was a pointer to vector of void + const u8* x4_materialData; + const std::vector* x8_positions; // was a pointer to void + const std::vector* xc_normals; // was a pointer to void + const std::vector* x10_colors; // was a pointer to void + const std::vector* x14_texCoords; // was a pointer to void + const std::vector>* x18_packedTexCoords; // was a pointer to void + + public: + ModelInstance(const std::vector>* surfaces, const u8* material, + const std::vector* positions, const std::vector* colors, + const std::vector* normals, const std::vector* texCoords, + const std::vector>* packedTexCoords) + : x0_surfacePtrs(surfaces) + , x4_materialData(material) + , x8_positions(positions) + , xc_normals(normals) + , x10_colors(colors) + , x14_texCoords(texCoords) + , x18_packedTexCoords(packedTexCoords) {} + + /* These functions have been slightly modified from their original to return the actual vector instead of a raw + * pointer + */ + [[nodiscard]] const std::vector>& Surfaces() const { return *x0_surfacePtrs; } + [[nodiscard]] const u8* GetMaterialPointer() const { return x4_materialData; } + void SetMaterialPointer(const u8* mat) { x4_materialData = mat; } + [[nodiscard]] const std::vector& GetVertexPointer() const { return *x8_positions; } + [[nodiscard]] const std::vector& GetNormalPointer() const { return *xc_normals; } + [[nodiscard]] const std::vector& GetColorPointer() const { return *x10_colors; } + [[nodiscard]] const std::vector& GetTCPointer() const { return *x14_texCoords; } + [[nodiscard]] const std::vector>& GetPackedTCPointer() const { return *x18_packedTexCoords; } + }; + + ModelInstance x0_modelInstance; + const std::vector>* x1c_textures; + zeus::CAABox x20_worldAABB; + CCubeSurface* x38_firstUnsortedSurf = nullptr; + CCubeSurface* x3c_firstSortedSurf = nullptr; + bool x40_24_; + u8 x41_visorFlags; + u32 x44_idx; + public: - CCubeModel(const std::vector* surfaces, const std::vector>* textures, - const u8* materialData, const std::vector* positions, - const std::vector* floatNormals, const std::vector>* shortNormals, - const std::vector* vtxColors, const std::vector* floatUvs, - const std::vector>* shortUVs, const zeus::CAABox* aabox, u8 flags, bool b1, u32 w1) {} + CCubeModel(const std::vector>* surfaces, + const std::vector>* textures, const u8* materialData, + const std::vector* positions, const std::vector* colors, + const std::vector* normals, const std::vector* texCoords, + const std::vector>* packedTexCoords, const zeus::CAABox& aabox, u8 flags, bool b1, + u32 idx); void UnlockTextures(); - static void MakeTexturesFromMats(const u8* ptr, std::vector>& texture, bool b1); }; #pragma endregion @@ -83,29 +126,31 @@ public: #pragma region CCubeSurface class CCubeSurface { static constexpr zeus::CVector3f skDefaultNormal{1.f, 0.f, 0.f}; - -public: - enum class ECookie { - - }; + zeus::CVector3f x0_center; + u32 xc_materialIndex; + u32 x10_displayListSize; + CCubeModel* x14_parent; + CCubeSurface* x18_nextSurface; + u32 x1c_extraSize; + zeus::CVector3f x20_normal; + zeus::CAABox x2c_bounds; public: CCubeSurface(u8* ptr); bool IsValid() const; - static CCubeSurface* FromCookieValue(u32 value); - void GetCookie(ECookie cookie); - void SetCookie(ECookie cookie, u32 value); - u32 GetCookieValue() const; - s32 GetMaterialIndex() const; - s32 GetDisplayListSize() const; - u8* GetDisplayList() const; - u32 GetSurfaceHeaderSize() const; - zeus::CVector3f GetCenter() const; - u32 GetNormalHint() const; - zeus::CAABox GetBounds() const; + void SetParent(CCubeModel* parent) { x14_parent = parent; } + [[nodiscard]] u32 GetMaterialIndex() const { return xc_materialIndex; } + [[nodiscard]] u32 GetDisplayListSize() const { return x10_displayListSize & 0x7fffffff; } + [[nodiscard]] u32 GetNormalHint() const { return (x10_displayListSize >> 31) & 1; } + [[nodiscard]] u8* GetDisplayList() const; + // u32 GetSurfaceHeaderSize() const { } + [[nodiscard]] zeus::CVector3f GetCenter() const { return x0_center; } + [[nodiscard]] zeus::CAABox GetBounds() const { + return x1c_extraSize != 0 ? x2c_bounds : zeus::CAABox{x0_center, x0_center}; + } }; #pragma endregion CFactoryFnReturn FModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); -} // namespace metaforce +} // namespace metaforce::WIP