From 94dadbfb1f66fa5e4a49520e702c49c446e4f921 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sat, 23 Sep 2023 15:55:57 +0800 Subject: [PATCH] write garbage for BMap dll --- BMap/BMExports.cpp | 19 ++- BMap/BMExports.hpp | 7 +- BMap/BMap.cpp | 192 +++++++++++++++++++++-------- BMap/BMap.hpp | 132 +++++++++----------- LibCmo/CK2/CKGlobals.cpp | 2 +- LibCmo/CK2/CKGlobals.hpp | 1 + LibCmo/CK2/ObjImpls/CK3dEntity.cpp | 4 + 7 files changed, 226 insertions(+), 131 deletions(-) diff --git a/BMap/BMExports.cpp b/BMap/BMExports.cpp index fa41eb7..347e04f 100644 --- a/BMap/BMExports.cpp +++ b/BMap/BMExports.cpp @@ -1,9 +1,24 @@ #include "BMExports.hpp" +#include +#include + +static std::set g_AllBMFiles = std::set(); void BMInit() { - + // register IronPad + IronPad::IronPadRegister(); + // and startup CK environment + LibCmo::CK2::CKStartUp(); } void BMDispose() { - + // free all existed file reader / writer + for (auto ptr : g_AllBMFiles) { + delete ptr; + } + g_AllBMFiles.clear(); + // shutdown CK environment + LibCmo::CK2::CKShutdown(); + // unregister iron pad + IronPad::IronPadUnregister(); } diff --git a/BMap/BMExports.hpp b/BMap/BMExports.hpp index c4a86fa..0665e47 100644 --- a/BMap/BMExports.hpp +++ b/BMap/BMExports.hpp @@ -9,7 +9,7 @@ LIBCMO_EXPORT void BMDispose(); #pragma endregion -#pragma region BMapFile Life Time Manager +#pragma region BMFile //LIBCMO_EXPORT BMap::BMFile* BMFile_Load(const char* file_name, const char* temp_folder, const char* texture_folder, const char* encoding); //LIBCMO_EXPORT BMap::BMFile* BMFile_Create(); @@ -18,4 +18,9 @@ LIBCMO_EXPORT void BMDispose(); #pragma endregion +#pragma region BMMeshTransition + + +#pragma endregion + diff --git a/BMap/BMap.cpp b/BMap/BMap.cpp index 558f51a..3cc861d 100644 --- a/BMap/BMap.cpp +++ b/BMap/BMap.cpp @@ -10,7 +10,7 @@ namespace BMap { const LibCmo::VxMath::VxVector2& uv) : m_Vertex(vec), m_Norm(norm), m_UV(uv) {} - BMMeshTransition::TransitionFace::TransitionFace(uint32_t _i1, uint32_t _i2, uint32_t _i3, uint32_t mtl_id) : + BMMeshTransition::TransitionFace::TransitionFace(LibCmo::CKDWORD _i1, LibCmo::CKDWORD _i2, LibCmo::CKDWORD _i3, LibCmo::CKDWORD mtl_id) : m_Idx1(_i1), m_Idx2(_i2), m_Idx3(_i3), m_MtlSlotIdx(mtl_id) {} bool BMMeshTransition::TransitionVertexCompare::operator()(const TransitionVertex& lhs, const TransitionVertex& rhs) const { @@ -29,56 +29,51 @@ namespace BMap { BMMeshTransition::~BMMeshTransition() {} - void BMMeshTransition::PrepareVertexCount(uint32_t count) { + void BMMeshTransition::PrepareVertexCount(LibCmo::CKDWORD count) { if (m_IsParsed) return; m_Vertexs.resize(count); m_IsVertexOK = true; } - void BMMeshTransition::PrepareVertex(uint32_t index, float x, float y, float z) { - if (m_IsParsed || index >= m_Vertexs.size()) return; - m_Vertexs[index].x = x; - m_Vertexs[index].y = y; - m_Vertexs[index].z = z; + LibCmo::VxMath::VxVector3* BMMeshTransition::PrepareVertex() { + if (m_IsParsed || !m_IsVertexOK) return nullptr; + return m_Vertexs.data(); } - void BMMeshTransition::PrepareNormalCount(uint32_t count) { + void BMMeshTransition::PrepareNormalCount(LibCmo::CKDWORD count) { if (m_IsParsed) return; m_Normals.resize(count); m_IsNormalOK = true; } - void BMMeshTransition::PrepareNormal(uint32_t index, float x, float y, float z) { - if (m_IsParsed || index >= m_Normals.size()) return; - m_Normals[index].x = x; - m_Normals[index].y = y; - m_Normals[index].z = z; + LibCmo::VxMath::VxVector3* BMMeshTransition::PrepareNormal() { + if (m_IsParsed || !m_IsNormalOK) return nullptr; + return m_Normals.data(); } - void BMMeshTransition::PrepareUVCount(uint32_t count) { + void BMMeshTransition::PrepareUVCount(LibCmo::CKDWORD count) { if (m_IsParsed) return; m_UVs.resize(count); m_IsUVOK = true; } - void BMMeshTransition::PrepareUV(uint32_t index, float u, float v) { - if (m_IsParsed || index >= m_UVs.size()) return; - m_UVs[index].x = u; - m_UVs[index].y = v; + LibCmo::VxMath::VxVector2* BMMeshTransition::PrepareUV() { + if (m_IsParsed || !m_IsUVOK) return nullptr; + return m_UVs.data(); } - void BMMeshTransition::PrepareMtlSlotCount(uint32_t count) { + void BMMeshTransition::PrepareMtlSlotCount(LibCmo::CKDWORD count) { if (m_IsParsed) return; m_MtlSlots.resize(count, nullptr); m_IsMtlSlotOK = true; } - void BMMeshTransition::PrepareMtlSlot(uint32_t index, BMMaterial* mtl) { - if (m_IsParsed || index >= m_MtlSlots.size()) return; - m_MtlSlots[index] = mtl; + LibCmo::CK2::ObjImpls::CKMaterial** BMMeshTransition::PrepareMtlSlot() { + if (m_IsParsed || !m_IsMtlSlotOK) return nullptr; + return m_MtlSlots.data(); } - void BMMeshTransition::PrepareFaceCount(uint32_t count) { + void BMMeshTransition::PrepareFaceCount(LibCmo::CKDWORD count) { if (m_IsParsed) return; m_FaceVertexs.resize(count * 3); m_FaceNormals.resize(count * 3); @@ -87,45 +82,46 @@ namespace BMap { m_IsFaceOK = true; } - void BMMeshTransition::PrepareFaceVertexIndices(uint32_t index, uint32_t indice1, uint32_t indice2, uint32_t indice3) { - index *= 3; - if (m_IsParsed || index >= m_FaceVertexs.size()) return; - m_FaceVertexs[index] = indice1; - m_FaceVertexs[index + 1] = indice2; - m_FaceVertexs[index + 2] = indice3; + LibCmo::CKDWORD* BMMeshTransition::PrepareFaceVertexIndices() { + if (m_IsParsed || !m_IsFaceOK) return nullptr; + return m_FaceVertexs.data(); } - void BMMeshTransition::PrepareFaceNormalIndices(uint32_t index, uint32_t indice1, uint32_t indice2, uint32_t indice3) { - index *= 3; - if (m_IsParsed || index >= m_FaceNormals.size()) return; - m_FaceNormals[index] = indice1; - m_FaceNormals[index + 1] = indice2; - m_FaceNormals[index + 2] = indice3; - + LibCmo::CKDWORD* BMMeshTransition::PrepareFaceNormalIndices() { + if (m_IsParsed || !m_IsFaceOK) return nullptr; + return m_FaceVertexs.data(); } - void BMMeshTransition::PrepareFaceUVIndices(uint32_t index, uint32_t indice1, uint32_t indice2, uint32_t indice3) { - index *= 3; - if (m_IsParsed || index >= m_FaceUVs.size()) return; - m_FaceUVs[index] = indice1; - m_FaceUVs[index + 1] = indice2; - m_FaceUVs[index + 2] = indice3; - + LibCmo::CKDWORD* BMMeshTransition::PrepareFaceUVIndices() { + if (m_IsParsed || !m_IsFaceOK) return nullptr; + return m_FaceVertexs.data(); } - void BMMeshTransition::PrepareFaceMtlSlot(uint32_t index, uint32_t mtl_slot) { - if (m_IsParsed || index >= m_FaceMtlSlotIdxs.size()) return; - m_FaceMtlSlotIdxs[index] = mtl_slot; + LibCmo::CKDWORD* BMMeshTransition::PrepareFaceMtlSlot() { + if (m_IsParsed || !m_IsFaceOK) return nullptr; + return m_FaceVertexs.data(); } - bool BMMeshTransition::Parse(BMMesh* write_into_mesh) { + bool BMMeshTransition::Parse(LibCmo::CK2::ObjImpls::CKMesh* write_into_mesh) { if (m_IsParsed || write_into_mesh == nullptr) return false; if (!m_IsVertexOK || !m_IsNormalOK || !m_IsUVOK || !m_IsFaceOK || !m_IsMtlSlotOK) return false; + m_IsParsed = true; + // do parse DoRealParse(); + + // check vertex overflow + if (m_ProcVertexs.size() > std::numeric_limits::max()) { + return false; + } + // check mtl slot overflow + if (m_MtlSlots.size() > std::numeric_limits::max()) { + return false; + } + + // apply to mesh ApplyToMesh(write_into_mesh); - m_IsParsed = true; return true; } @@ -138,7 +134,7 @@ namespace BMap { // iterate face for (size_t faceid = 0; faceid < face_size; ++faceid) { - uint32_t idx[3]; + LibCmo::CKDWORD idx[3]; for (int j = 0; j < 3; ++j) { // create one first TransitionVertex tvec( @@ -148,7 +144,7 @@ namespace BMap { ); // try insert it - auto insert_result = m_ProcDupRemover.try_emplace(tvec, static_cast(m_ProcVertexs.size())); + auto insert_result = m_ProcDupRemover.try_emplace(tvec, static_cast(m_ProcVertexs.size())); // get the new inserted index or existed index. idx[j] = insert_result.first->second; // if insert successfully, append to proc vertexs @@ -162,12 +158,104 @@ namespace BMap { } } - void BMMeshTransition::ApplyToMesh(BMMesh* write_into_mesh) { - // todo: apply to mesh + void BMMeshTransition::ApplyToMesh(LibCmo::CK2::ObjImpls::CKMesh* write_into_mesh) { + LibCmo::CKDWORD vec_count = static_cast(m_ProcVertexs.size()), + face_count = static_cast(m_ProcFaces.size()), + mtl_count = static_cast(m_MtlSlots.size()); + write_into_mesh->CleanMesh(); + + // write vertex + write_into_mesh->SetVertexCount(vec_count); + LibCmo::VxMath::VxCopyStructure( + vec_count, + write_into_mesh->GetVertexPositions(), + CKSizeof(LibCmo::VxMath::VxVector3), + CKSizeof(LibCmo::VxMath::VxVector3), + &m_ProcVertexs.data()->m_Vertex, + CKSizeof(TransitionVertex) + ); + LibCmo::VxMath::VxCopyStructure( + vec_count, + write_into_mesh->GetVertexNormals(), + CKSizeof(LibCmo::VxMath::VxVector3), + CKSizeof(LibCmo::VxMath::VxVector3), + &m_ProcVertexs.data()->m_Norm, + CKSizeof(TransitionVertex) + ); + LibCmo::VxMath::VxCopyStructure( + vec_count, + write_into_mesh->GetVertexUVs(), + CKSizeof(LibCmo::VxMath::VxVector2), + CKSizeof(LibCmo::VxMath::VxVector2), + &m_ProcVertexs.data()->m_UV, + CKSizeof(TransitionVertex) + ); + + // write face + write_into_mesh->SetFaceCount(face_count); + auto pIndices = write_into_mesh->GetFaceIndices(); + auto pMtlIdx = write_into_mesh->GetFaceMaterialSlotIndexs(); + for (LibCmo::CKDWORD i = 0; i < face_count; ++i) { + *(pIndices++) = static_cast(m_ProcFaces[i].m_Idx1); + *(pIndices++) = static_cast(m_ProcFaces[i].m_Idx2); + *(pIndices++) = static_cast(m_ProcFaces[i].m_Idx3); + + *(pMtlIdx++) = static_cast(m_ProcFaces[i].m_MtlSlotIdx); + } + + // set mtl slot + write_into_mesh->SetMaterialSlotCount(mtl_count); + auto pMtlSlot = write_into_mesh->GetMaterialSlots(); + for (LibCmo::CKDWORD i = 0; i < mtl_count; ++i) { + *(pMtlSlot++) = m_MtlSlots[i]; + } } #pragma endregion +#pragma region BMfile + + BMFile::BMFile(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[], bool is_reader) { + + } + + BMFile::~BMFile() {} + + bool BMFile::Load(LibCmo::CKSTRING filename) { + return false; + } + + bool BMFile::Save(LibCmo::CKSTRING filename, LibCmo::CKINT compress_level) { + return false; + } + +#define VISITOR_IMPL(namepart, cidpart) \ +LibCmo::CKDWORD BMFile::Get ## namepart ## Count() { \ + if (!m_IsReader) return 0; \ + return static_cast(m_Obj ## namepart ## s.size()); \ +} \ +LibCmo::CK2::ObjImpls::CK ## namepart * BMFile::Get ## namepart (LibCmo::CKDWORD idx) { \ + if (!m_IsReader || idx >= m_Obj ## namepart ## s.size()) return nullptr; \ + return m_Obj ## namepart ## s[idx]; \ +} \ +LibCmo::CK2::ObjImpls::CK ## namepart * BMFile::Create ## namepart (LibCmo::CKSTRING name) { \ + if (m_IsReader) return nullptr; \ + LibCmo::CK2::ObjImpls::CK ## namepart * obj = static_cast( \ + m_Context->CreateObject(LibCmo::CK2::CK_CLASSID::CKCID_ ## cidpart, name) \ + ); \ + if (obj != nullptr) m_Obj ## namepart ## s.emplace_back(obj); \ + return obj; \ +} + + VISITOR_IMPL(Group, GROUP) + VISITOR_IMPL(3dObject, 3DOBJECT) + VISITOR_IMPL(Mesh, MESH) + VISITOR_IMPL(Material, MATERIAL) + VISITOR_IMPL(Texture, TEXTURE) + +#undef VISITOR_IMPL + +#pragma endregion } diff --git a/BMap/BMap.hpp b/BMap/BMap.hpp index 6fe9d8c..8698f36 100644 --- a/BMap/BMap.hpp +++ b/BMap/BMap.hpp @@ -7,51 +7,6 @@ namespace BMap { - class BMGroup { - public: - BMGroup(LibCmo::CK2::ObjImpls::CKGroup* ptr); - ~BMGroup(); - LIBCMO_DEFAULT_COPY_MOVE(BMGroup); - - LibCmo::CK2::ObjImpls::CKGroup* m_NativePtr; - }; - - class BMTexture { - public: - BMTexture(LibCmo::CK2::ObjImpls::CKTexture* ptr); - ~BMTexture(); - LIBCMO_DEFAULT_COPY_MOVE(BMTexture); - - LibCmo::CK2::ObjImpls::CKTexture* m_NativePtr; - }; - - class BMMaterial { - public: - BMMaterial(LibCmo::CK2::ObjImpls::CKMaterial* ptr); - ~BMMaterial(); - LIBCMO_DEFAULT_COPY_MOVE(BMMaterial); - - LibCmo::CK2::ObjImpls::CKMaterial* m_NativePtr; - }; - - class BMMesh { - public: - BMMesh(LibCmo::CK2::ObjImpls::CKMesh* ptr); - ~BMMesh(); - LIBCMO_DEFAULT_COPY_MOVE(BMMesh); - - LibCmo::CK2::ObjImpls::CKMesh* m_NativePtr; - }; - - class BM3dEntity { - public: - BM3dEntity(LibCmo::CK2::ObjImpls::CK3dEntity* ptr); - ~BM3dEntity(); - LIBCMO_DEFAULT_COPY_MOVE(BM3dEntity); - - LibCmo::CK2::ObjImpls::CK3dEntity* m_NativePtr; - }; - class BMMeshTransition { private: struct TransitionVertex { @@ -64,9 +19,9 @@ namespace BMap { LibCmo::VxMath::VxVector2 m_UV; }; struct TransitionFace { - TransitionFace(uint32_t _i1, uint32_t _i2, uint32_t _i3, uint32_t mtl_id); - uint32_t m_Idx1, m_Idx2, m_Idx3; - uint32_t m_MtlSlotIdx; + TransitionFace(LibCmo::CKDWORD _i1, LibCmo::CKDWORD _i2, LibCmo::CKDWORD _i3, LibCmo::CKDWORD mtl_id); + LibCmo::CKDWORD m_Idx1, m_Idx2, m_Idx3; + LibCmo::CKDWORD m_MtlSlotIdx; }; struct TransitionVertexCompare { bool operator()(const TransitionVertex& lhs, const TransitionVertex& rhs) const; @@ -76,54 +31,81 @@ namespace BMap { BMMeshTransition(); ~BMMeshTransition(); - void PrepareVertexCount(uint32_t count); - void PrepareVertex(uint32_t index, float x, float y, float z); - void PrepareNormalCount(uint32_t count); - void PrepareNormal(uint32_t index, float x, float y, float z); - void PrepareUVCount(uint32_t count); - void PrepareUV(uint32_t index, float u, float v); - void PrepareMtlSlotCount(uint32_t count); - void PrepareMtlSlot(uint32_t index, BMMaterial* mtl); - void PrepareFaceCount(uint32_t count); - void PrepareFaceVertexIndices(uint32_t index, uint32_t indice1, uint32_t indice2, uint32_t indice3); - void PrepareFaceNormalIndices(uint32_t index, uint32_t indice1, uint32_t indice2, uint32_t indice3); - void PrepareFaceUVIndices(uint32_t index, uint32_t indice1, uint32_t indice2, uint32_t indice3); - void PrepareFaceMtlSlot(uint32_t index, uint32_t mtl_slot); + void PrepareVertexCount(LibCmo::CKDWORD count); + LibCmo::VxMath::VxVector3* PrepareVertex(); + void PrepareNormalCount(LibCmo::CKDWORD count); + LibCmo::VxMath::VxVector3* PrepareNormal(); + void PrepareUVCount(LibCmo::CKDWORD count); + LibCmo::VxMath::VxVector2* PrepareUV(); + void PrepareMtlSlotCount(LibCmo::CKDWORD count); + LibCmo::CK2::ObjImpls::CKMaterial** PrepareMtlSlot(); + void PrepareFaceCount(LibCmo::CKDWORD count); + LibCmo::CKDWORD* PrepareFaceVertexIndices(); + LibCmo::CKDWORD* PrepareFaceNormalIndices(); + LibCmo::CKDWORD* PrepareFaceUVIndices(); + LibCmo::CKDWORD* PrepareFaceMtlSlot(); - bool Parse(BMMesh* write_into_mesh); + bool Parse(LibCmo::CK2::ObjImpls::CKMesh* write_into_mesh); private: void DoRealParse(); - void ApplyToMesh(BMMesh* write_into_mesh); + void ApplyToMesh(LibCmo::CK2::ObjImpls::CKMesh* write_into_mesh); bool m_IsVertexOK, m_IsNormalOK, m_IsUVOK, m_IsFaceOK, m_IsMtlSlotOK; bool m_IsParsed; std::vector m_Vertexs, m_Normals; std::vector m_UVs; - std::vector m_FaceVertexs, m_FaceNormals, m_FaceUVs; - std::vector m_FaceMtlSlotIdxs; - std::vector m_MtlSlots; + std::vector m_FaceVertexs, m_FaceNormals, m_FaceUVs; + std::vector m_FaceMtlSlotIdxs; + std::vector m_MtlSlots; std::vector m_ProcVertexs; std::vector m_ProcFaces; - // unordered_map have performance problem when dealing with massive data (in this case, big mesh) - // so we use map to get stable time cost. - std::map m_ProcDupRemover; + /** + @brief The core duplication vertex remover. + @remark + unordered_map have performance problem when dealing with massive data (in this case, big mesh). + so we use map to get stable time cost. + */ + std::map m_ProcDupRemover; }; class BMFile { public: - BMFile(); + BMFile(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[], bool is_reader); ~BMFile(); + bool Load(LibCmo::CKSTRING filename); + bool Save(LibCmo::CKSTRING filename, LibCmo::CKINT compress_level); + +#define VISITOR_DECL(namepart) \ +LibCmo::CKDWORD Get ## namepart ## Count(); \ +LibCmo::CK2::ObjImpls::CK ## namepart * Get ## namepart (LibCmo::CKDWORD idx); \ +LibCmo::CK2::ObjImpls::CK ## namepart * Create ## namepart (LibCmo::CKSTRING name); + + VISITOR_DECL(Group) + VISITOR_DECL(3dObject) + VISITOR_DECL(Mesh) + VISITOR_DECL(Material) + VISITOR_DECL(Texture) + +#undef VISITOR_DECL + private: + bool m_IsReader; LibCmo::CK2::CKContext* m_Context; - std::vector m_ObjGroups; - std::vector m_Obj3dObjects; - std::vector m_ObjMeshs; - std::vector m_ObjMaterials; - std::vector m_ObjTextures; + +#define VISITOR_SELF(namepart) \ +std::vector m_Obj ## namepart ## s; + + VISITOR_SELF(Group) + VISITOR_SELF(3dObject) + VISITOR_SELF(Mesh) + VISITOR_SELF(Material) + VISITOR_SELF(Texture) + +#undef VISITOR_SELF }; } diff --git a/LibCmo/CK2/CKGlobals.cpp b/LibCmo/CK2/CKGlobals.cpp index ddb6fd6..49da212 100644 --- a/LibCmo/CK2/CKGlobals.cpp +++ b/LibCmo/CK2/CKGlobals.cpp @@ -392,7 +392,7 @@ namespace LibCmo::CK2 { // reserve class info array. g_CKClassInfo.reserve(static_cast(CK_CLASSID::CKCID_MAXCLASSID)); - // todo: add class type registrations + // MARK: add class type registrations here #define EasyClassReg(clsname, cid, parentCid, strName) \ CKClassRegister(cid, parentCid, \ nullptr, \ diff --git a/LibCmo/CK2/CKGlobals.hpp b/LibCmo/CK2/CKGlobals.hpp index b205efc..53e44be 100644 --- a/LibCmo/CK2/CKGlobals.hpp +++ b/LibCmo/CK2/CKGlobals.hpp @@ -154,6 +154,7 @@ namespace LibCmo::CK2 { XContainer::XBitArray CKGetAllNotifyClassID(const XContainer::XBitArray& delObjCids); // ========== Initializations functions ========== + CKERROR CKStartUp(); CKERROR CKShutdown(); diff --git a/LibCmo/CK2/ObjImpls/CK3dEntity.cpp b/LibCmo/CK2/ObjImpls/CK3dEntity.cpp index ee471a8..6f0dd8d 100644 --- a/LibCmo/CK2/ObjImpls/CK3dEntity.cpp +++ b/LibCmo/CK2/ObjImpls/CK3dEntity.cpp @@ -145,6 +145,8 @@ namespace LibCmo::CK2::ObjImpls { // so we just read it and skip it. CK_ID placeid; chunk->ReadObjectID(placeid); + // and remove this flag + EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID); } // read parent @@ -153,6 +155,8 @@ namespace LibCmo::CK2::ObjImpls { // we ignore this field. CK_ID parentid; chunk->ReadObjectID(parentid); + // and remove this flag + EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID); } // read priority (non-zero zorder)