diff --git a/LibCmo/CK2/ObjImpls/CKMesh.cpp b/LibCmo/CK2/ObjImpls/CKMesh.cpp index df6681f..f645db6 100644 --- a/LibCmo/CK2/ObjImpls/CKMesh.cpp +++ b/LibCmo/CK2/ObjImpls/CKMesh.cpp @@ -21,8 +21,73 @@ namespace LibCmo::CK2::ObjImpls { bool suc = CKBeObject::Load(chunk, file); if (!suc) return false; - // clear + // clear all data + CleanMesh(); + // check data version. + // MARK: too low data is not supported. + // because my work are not related to them + if (chunk->GetDataVersion() < CK_STATECHUNK_DATAVERSION::CHUNK_MESHCHANGE_VERSION) { + return false; + } + + // read flag + if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_MESH::CK_STATESAVE_MESHFLAGS)) { + CKDWORD flags; + chunk->ReadStruct(flags); + + m_Flags = static_cast(flags); + EnumsHelper::Mask(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_ALLFLAGS); + + // I don't know why, just interpter the IDA code. + EnumsHelper::Rm(m_Flags, EnumsHelper::Merge({ + VxMath::VXMESH_FLAGS::VXMESH_BOUNDINGUPTODATE, + VxMath::VXMESH_FLAGS::VXMESH_OPTIMIZED + })); + } + + // read material slots + if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_MESH::CK_STATESAVE_MESHMATERIALS)) { + // get and set material count + CKDWORD mtlCount; + chunk->ReadStruct(mtlCount); + SetMaterialSlotCount(mtlCount); + + // read slot + CK_ID mtlId; + CKDWORD ph; + CKObject* objptr; + for (auto& mtlSlot : m_MaterialSlot) { + // read id + chunk->ReadObjectID(mtlId); + // and read a place holder idk what the fuck it is. + chunk->ReadStruct(ph); + + // try getting object pointer and assign + objptr = m_Context->GetObject(mtlId); + if (objptr != nullptr && objptr->GetClassID() == CK_CLASSID::CKCID_MATERIAL) { + mtlSlot = static_cast(objptr); + } else { + mtlSlot = nullptr; + } + } + } + + // read vertex data + if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_MESH::CK_STATESAVE_MESHVERTICES)) { + // read and set vertex count + CKDWORD vertexCount; + chunk->ReadStruct(vertexCount); + + if (vertexCount != 0) { + VertexSaveFlags saveflags; + chunk->ReadStruct(saveflags); + + + + + } + } return true; } diff --git a/LibCmo/CK2/ObjImpls/CKMesh.hpp b/LibCmo/CK2/ObjImpls/CKMesh.hpp index 20405cb..469fed5 100644 --- a/LibCmo/CK2/ObjImpls/CKMesh.hpp +++ b/LibCmo/CK2/ObjImpls/CKMesh.hpp @@ -23,6 +23,9 @@ namespace LibCmo::CK2::ObjImpls { // ===== Misc Section ===== public: void CleanMesh(); + protected: + void BuildNormals(); + void BuildFaceNormals(); // ===== Line Section ===== public: @@ -73,6 +76,13 @@ namespace LibCmo::CK2::ObjImpls { void SyncMtlChannelToFaceMask(); // request all face accept all material channels. protected: + enum class VertexSaveFlags : CKDWORD { + SingleColor = 0x1u, /**< if not set, the VertexColor is a list£¬ otherwise a single global CKDWORD.*/ + SingleSpecularColor = 0x2u, /**< if not set, the VertexSpecularColor is a list£¬ otherwise a single global CKDWORD. */ + NoNormal = 0x4u, /**< if set, there are no normal data for vertex. */ + SingleUV = 0x8u, /**< if not set, the VertexUV is a list£¬ otherwise a single global VxVertex2. */ + NoPos = 0x10u, /**< if set, there are no position data for vertex. */ + }; struct FaceData_t { FaceData_t() : m_Normal(), diff --git a/LibCmo/VTUtils.hpp b/LibCmo/VTUtils.hpp index def6e87..9afcb69 100644 --- a/LibCmo/VTUtils.hpp +++ b/LibCmo/VTUtils.hpp @@ -180,6 +180,11 @@ namespace LibCmo { inline void Rm(TEnum& e1, TEnum e2) { e1 = static_cast(static_cast>(e1) & static_cast>(Inv(e2))); } + + template, int> = 0> + inline void Mask(TEnum& e1, TEnum e2) { + e1 = static_cast(static_cast>(e1) & static_cast>(e2)); + } template, int> = 0> inline void Add(TEnum& e1, TEnum e2) {