add some reading function

This commit is contained in:
yyc12345 2023-09-15 17:03:36 +08:00
parent 312c746279
commit 8f960604ca
3 changed files with 81 additions and 1 deletions

View File

@ -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<VxMath::VXMESH_FLAGS>(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<CKMaterial*>(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;
}

View File

@ -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(),

View File

@ -181,6 +181,11 @@ namespace LibCmo {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) & static_cast<std::underlying_type_t<TEnum>>(Inv(e2)));
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline void Mask(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) & static_cast<std::underlying_type_t<TEnum>>(e2));
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline void Add(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) | static_cast<std::underlying_type_t<TEnum>>(e2));