From 312c746279a3560ac4a23ffefe7184206f92655a Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Fri, 15 Sep 2023 16:15:07 +0800 Subject: [PATCH] add some functions --- LibCmo/CK2/ObjImpls/CKMesh.cpp | 196 ++++++++++++++++++++++++++++++++- LibCmo/CK2/ObjImpls/CKMesh.hpp | 97 ++++++++++++++++ LibCmo/VxMath/VxTypes.hpp | 18 +++ 3 files changed, 310 insertions(+), 1 deletion(-) diff --git a/LibCmo/CK2/ObjImpls/CKMesh.cpp b/LibCmo/CK2/ObjImpls/CKMesh.cpp index aab6d13..df6681f 100644 --- a/LibCmo/CK2/ObjImpls/CKMesh.cpp +++ b/LibCmo/CK2/ObjImpls/CKMesh.cpp @@ -6,7 +6,7 @@ namespace LibCmo::CK2::ObjImpls { CKMesh::CKMesh(CKContext* ctx, CK_ID ckid, CKSTRING name) : - CKBeObject(ctx, ckid, name){} + CKBeObject(ctx, ckid, name) {} CKMesh::~CKMesh() {} @@ -21,7 +21,201 @@ namespace LibCmo::CK2::ObjImpls { bool suc = CKBeObject::Load(chunk, file); if (!suc) return false; + // clear + + return true; } + void CKMesh::CleanMesh() { + // clear material channel first + SetMtlChannelCount(0); + // then clear other + SetVertexCount(0); + SetMaterialSlotCount(0); + SetFaceCount(0); + SetLineCount(0); + } + +#pragma region Vertex Section + + CKDWORD CKMesh::GetVertexCount() { + return m_VertexCount; + } + + void CKMesh::SetVertexCount(CKDWORD count) { + m_VertexCount = count; + m_VertexPosition.resize(count); + m_VertexNormal.resize(count); + m_VertexUV.resize(count); + m_VertexColor.resize(count, 0xFFFFFFFF); + m_VertexSpecularColor.resize(count, 0x00000000); + m_VertexWeight.resize(count, 0.0f); + + // notify mtl channels refresh its custom uv + SyncVertexCountToMtlChannel(); + } + + VxMath::VxVector3* CKMesh::GetVertexPositions() { + return m_VertexPosition.data(); + } + + VxMath::VxVector3* CKMesh::GetVertexNormals() { + return m_VertexNormal.data(); + } + + VxMath::VxVector2* CKMesh::GetVertexUVs() { + return m_VertexUV.data(); + } + + CKDWORD* CKMesh::GetVertexColors() { + return m_VertexColor.data(); + } + + CKDWORD* CKMesh::GetVertexSpecularColors() { + return m_VertexSpecularColor.data(); + } + + float* CKMesh::GetVertexWeights() { + return m_VertexWeight.data(); + } + +#pragma endregion + +#pragma region Material Slot Section + + CKDWORD CKMesh::GetMaterialSlotCount() { + return m_MtlSlotCount; + } + + void CKMesh::SetMaterialSlotCount(CKDWORD count) { + m_MtlSlotCount = count; + m_MaterialSlot.resize(count, nullptr); + } + + void CKMesh::SetMaterialSlot(CKMaterial* mtl, CKDWORD idx) { + if (idx >= m_MtlSlotCount) return; + m_MaterialSlot[idx] = mtl; + } + +#pragma endregion + +#pragma region Face Section + + CKDWORD CKMesh::GetFaceCount() { + return m_FaceCount; + } + + void CKMesh::SetFaceCount(CKDWORD count) { + m_FaceCount = count; + m_FaceIndices.resize(count * 3, 0); + m_FaceMtlIndex.resize(count, 0); + m_Faces.resize(count); + } + + CKWORD* CKMesh::GetFaceIndices() { + return m_FaceIndices.data(); + } + + CKWORD* CKMesh::GetFaceMaterialSlotIndexs() { + return m_FaceIndices.data(); + } + + VxMath::VxVector3* CKMesh::GetFaceNormals(CKDWORD& stride) { + stride = CKSizeof(FaceData_t); + return &m_Faces.data()->m_Normal; + } + + CKWORD* CKMesh::GetFaceChannelMasks(CKDWORD& stride) { + stride = CKSizeof(FaceData_t); + return &m_Faces.data()->m_ChannelMask; + } + +#pragma endregion + +#pragma region Line Section + + CKDWORD CKMesh::GetLineCount() { + return m_LineCount; + } + + void CKMesh::SetLineCount(CKDWORD count) { + m_LineCount = count; + m_LineIndices.resize(count * 2, 0); + } + + CKWORD* CKMesh::GetLineIndices() { + return m_LineIndices.data(); + } + +#pragma endregion + +#pragma region Mtl Channel Section + + CKDWORD CKMesh::GetMtlChannelCount() { + return m_MtlChannelCount; + } + + void CKMesh::SetMtlChannelCount(CKDWORD count) { + m_MtlChannelCount = count; + m_MaterialChannels.resize(count); + + // sync mask to each face. + // each face accept all mask in default + SyncMtlChannelToFaceMask(); + } + + CKMaterial** CKMesh::GetMtlChannelMaterials(CKDWORD& stride) { + stride = CKSizeof(MaterialChannel_t); + return &m_MaterialChannels.data()->m_Material; + } + + VxMath::VXBLEND_MODE* CKMesh::GetMtlChannelSourceBlends(CKDWORD& stride) { + stride = CKSizeof(MaterialChannel_t); + return &m_MaterialChannels.data()->m_SourceBlend; + } + + VxMath::VXBLEND_MODE* CKMesh::GetMtlChannelDestBlends(CKDWORD& stride) { + stride = CKSizeof(MaterialChannel_t); + return &m_MaterialChannels.data()->m_DestBlend; + } + + VxMath::VxVector2* CKMesh::GetMtlChannelCustomUVs(CKDWORD idx) { + if (idx >= m_MtlChannelCount) return nullptr; + return m_MaterialChannels[idx].m_CustomUV.data(); + } + + VxMath::VXCHANNEL_FLAGS CKMesh::GetMtlChannelFlags(CKDWORD idx) { + if (idx >= m_MtlChannelCount) return static_cast(0); + return m_MaterialChannels[idx].m_Flags; + } + + void CKMesh::SetMtlChannelFlags(CKDWORD idx, VxMath::VXCHANNEL_FLAGS flags) { + if (idx >= m_MtlChannelCount) return; + m_MaterialChannels[idx].m_Flags = flags; + + // refresh self custom uv + SyncVertexCountToMtlChannel(); + } + + void CKMesh::SyncVertexCountToMtlChannel() { + for (auto& channel : m_MaterialChannels) { + if (!EnumsHelper::Has(channel.m_Flags, VxMath::VXCHANNEL_FLAGS::VXCHANNEL_SAMEUV)) { + channel.m_CustomUV.resize(m_VertexCount); + } else { + channel.m_CustomUV.clear(); + } + } + } + + void CKMesh::SyncMtlChannelToFaceMask() { + CKWORD mask = static_cast(~(0xFFFF << m_MtlChannelCount)); + for (auto& face : m_Faces) { + face.m_ChannelMask |= mask; + } + } + +#pragma endregion + + } diff --git a/LibCmo/CK2/ObjImpls/CKMesh.hpp b/LibCmo/CK2/ObjImpls/CKMesh.hpp index b010a96..20405cb 100644 --- a/LibCmo/CK2/ObjImpls/CKMesh.hpp +++ b/LibCmo/CK2/ObjImpls/CKMesh.hpp @@ -19,9 +19,106 @@ namespace LibCmo::CK2::ObjImpls { virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override; virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override; //virtual void PostLoad() override; + + // ===== Misc Section ===== + public: + void CleanMesh(); + + // ===== Line Section ===== + public: + CKDWORD GetVertexCount(); + void SetVertexCount(CKDWORD count); + VxMath::VxVector3* GetVertexPositions(); + VxMath::VxVector3* GetVertexNormals(); + VxMath::VxVector2* GetVertexUVs(); + CKDWORD* GetVertexColors(); + CKDWORD* GetVertexSpecularColors(); + float* GetVertexWeights(); + + // ===== Material Slot Section ===== + public: + CKDWORD GetMaterialSlotCount(); + void SetMaterialSlotCount(CKDWORD count); + void SetMaterialSlot(CKMaterial* mtl, CKDWORD idx); + + // ===== Face Section ===== + public: + CKDWORD GetFaceCount(); + void SetFaceCount(CKDWORD count); + CKWORD* GetFaceIndices(); + CKWORD* GetFaceMaterialSlotIndexs(); + VxMath::VxVector3* GetFaceNormals(CKDWORD& stride); + CKWORD* GetFaceChannelMasks(CKDWORD& stride); + + // ===== Line Section ===== + public: + CKDWORD GetLineCount(); + void SetLineCount(CKDWORD count); + CKWORD* GetLineIndices(); + + // ===== Material Channel Section ===== + public: + CKDWORD GetMtlChannelCount(); + void SetMtlChannelCount(CKDWORD count); + CKMaterial** GetMtlChannelMaterials(CKDWORD& stride); + VxMath::VXBLEND_MODE* GetMtlChannelSourceBlends(CKDWORD& stride); + VxMath::VXBLEND_MODE* GetMtlChannelDestBlends(CKDWORD& stride); + + VxMath::VxVector2* GetMtlChannelCustomUVs(CKDWORD idx); + VxMath::VXCHANNEL_FLAGS GetMtlChannelFlags(CKDWORD idx); + void SetMtlChannelFlags(CKDWORD idx, VxMath::VXCHANNEL_FLAGS flags); + protected: + // 2 sync functions served for material channels. + void SyncVertexCountToMtlChannel(); // setup material channel custom uv properly + void SyncMtlChannelToFaceMask(); // request all face accept all material channels. protected: + struct FaceData_t { + FaceData_t() : + m_Normal(), + m_ChannelMask(0xFFFF) + {} + VxMath::VxVector3 m_Normal; + CKWORD m_ChannelMask; + }; + struct MaterialChannel_t { + MaterialChannel_t() : + m_Material(nullptr), + m_SourceBlend(VxMath::VXBLEND_MODE::VXBLEND_ZERO), + m_DestBlend(VxMath::VXBLEND_MODE::VXBLEND_SRCCOLOR), + m_CustomUV(), + m_Flags(EnumsHelper::Merge({ VxMath::VXCHANNEL_FLAGS::VXCHANNEL_ACTIVE, VxMath::VXCHANNEL_FLAGS::VXCHANNEL_SAMEUV })) + {} + CKMaterial* m_Material; + VxMath::VXBLEND_MODE m_SourceBlend; + VxMath::VXBLEND_MODE m_DestBlend; + XContainer::XArray m_CustomUV; + VxMath::VXCHANNEL_FLAGS m_Flags; + }; + VxMath::VXMESH_FLAGS m_Flags; + CKDWORD m_VertexCount; + CKDWORD m_LineCount; + CKDWORD m_MtlSlotCount; + CKDWORD m_FaceCount; + CKDWORD m_MtlChannelCount; + + XContainer::XArray m_VertexPosition; + XContainer::XArray m_VertexNormal; + XContainer::XArray m_VertexUV; + XContainer::XArray m_VertexColor; + XContainer::XArray m_VertexSpecularColor; + XContainer::XArray m_VertexWeight; + + XContainer::XArray m_MaterialSlot; + + XContainer::XArray m_FaceIndices; + XContainer::XArray m_FaceMtlIndex; + XContainer::XArray m_Faces; + + XContainer::XArray m_LineIndices; + + XContainer::XArray m_MaterialChannels; }; } diff --git a/LibCmo/VxMath/VxTypes.hpp b/LibCmo/VxMath/VxTypes.hpp index f801f5b..019bb7b 100644 --- a/LibCmo/VxMath/VxTypes.hpp +++ b/LibCmo/VxMath/VxTypes.hpp @@ -304,6 +304,24 @@ namespace LibCmo::VxMath { } }; + template, int> = 0> + class VxStridedData { + public: + VxStridedData(_Ty ptr, CK2::CKDWORD stride) : + m_Ptr(reinterpret_cast(m_Ptr)), + m_Stride(stride) + {} + ~VxStridedData() {} + + _Ty operator[](size_t idx) { + return reinterpret_cast<_Ty>(m_Ptr + (m_Stride * idx)); + } + + private: + CK2::CKBYTE* m_Ptr; + CK2::CKDWORD m_Stride; + }; + /** * VxImageDescEx describe the height, width, * and etc for image.