#pragma once #pragma region MeshFilter Helper Structs struct VertexBufferData { VertexBufferData() : pDataStart(nullptr), pVertexBuffer(nullptr), BufferSize(0), VertexStride(0), VertexCount(0), IndexCount(0), InputLayoutID(0) {} void* pDataStart; ID3D11Buffer* pVertexBuffer; UINT BufferSize; UINT VertexStride; UINT VertexCount; UINT IndexCount; UINT InputLayoutID; void Destroy() { free(pDataStart); SafeRelease(pVertexBuffer); } }; struct AnimationKey { float tick{}; std::vector boneTransforms{}; }; struct AnimationClip { AnimationClip() = default; std::wstring name{}; float duration{}; float ticksPerSecond{}; std::vector keys{}; }; struct SubMeshBuffers { std::vector vertexbuffers{}; ID3D11Buffer* pIndexBuffer{}; bool HasVertexBuffer(UINT inputLayoutId) const { return std::ranges::find_if(vertexbuffers, [&inputLayoutId](const VertexBufferData& data) { return data.InputLayoutID == inputLayoutId; }) != vertexbuffers.end(); } bool GetVertexBufferData(UINT inputLayoutId, VertexBufferData** pVertexBufferData) { pVertexBufferData = nullptr; const auto it = std::ranges::find_if(vertexbuffers, [&inputLayoutId](const VertexBufferData& data) { return data.InputLayoutID == inputLayoutId; }); if (it == vertexbuffers.end()) return false; auto result = &*it; pVertexBufferData = &result; return true; } void Release() { for (auto& vbData : vertexbuffers) { vbData.Destroy(); } vertexbuffers.clear(); SafeRelease(pIndexBuffer) } }; struct SubMeshFilter { BYTE id{}; std::wstring name{}; UINT vertexCount{}; UINT indexCount{}; UINT uvChannelCount{}; ILSemantic layoutElements{ ILSemantic::NONE }; std::vector positions{}; std::vector normals{}; std::vector tangents{}; std::vector binormals{}; std::vector texCoords{}; std::vector colors{}; std::vector blendIndices{}; std::vector blendWeights{}; //INDEX DATA std::vector indices{}; //DX Data SubMeshBuffers buffers{}; bool HasElement(ILSemantic element) const { return isSet(layoutElements, element); } void Release() { layoutElements = ILSemantic::NONE; positions.clear(); normals.clear(); tangents.clear(); binormals.clear(); texCoords.clear(); colors.clear(); blendIndices.clear(); blendWeights.clear(); indices.clear(); buffers.Release(); } }; #pragma endregion class MeshFilter final { public: MeshFilter() = default; ~MeshFilter(); MeshFilter(const MeshFilter& other) = delete; MeshFilter(MeshFilter&& other) noexcept = delete; MeshFilter& operator=(const MeshFilter& other) = delete; MeshFilter& operator=(MeshFilter&& other) noexcept = delete; const std::vector& GetMeshes() const { return m_Meshes; } UINT GetMeshCount() const { return static_cast(m_Meshes.size()); } const std::vector& GetAnimationClips() const { return m_AnimationClips; } bool HasAnimations() const { return m_HasAnimations; } int GetVertexBufferId(UINT inputLayoutId, UINT8 subMeshId) const; void BuildVertexBuffer(const SceneContext& sceneContext, UINT inputLayoutID, UINT inputLayoutSize, const std::vector& inputLayoutDescriptions); void BuildVertexBuffer(const SceneContext& sceneContext, BaseMaterial* pMaterial); void BuildVertexBuffer(const D3D11Context& d3dContext, BaseMaterial* pMaterial); void BuildIndexBuffer(const SceneContext& sceneContext); void BuildIndexBuffer(const D3D11Context& d3dContext); const VertexBufferData& GetVertexBufferData(const SceneContext& sceneContext, BaseMaterial* pMaterial, UINT8 subMeshId = 0); const VertexBufferData& GetVertexBufferData(UINT inputLayoutId, UINT8 subMeshId = 0) const; ID3D11Buffer* GetIndexBuffer(UINT8 subMeshId = 0) const; UINT GetIndexCount(UINT8 subMeshId = 0) const { return m_Meshes[subMeshId].indexCount; } UINT GetVertexCount(UINT8 subMeshId = 0) const { return m_Meshes[subMeshId].vertexCount; } private: friend class MeshFilterLoader; //TODO: Resolve Friend Classes friend class ModelComponent; friend class ModelAnimator; friend class AnimationBlender; void BuildVertexBuffer(const SceneContext& sceneContext, BaseMaterial* pMaterial, UINT8 subMeshId); void BuildVertexBuffer(const D3D11Context& d3dContext, BaseMaterial* pMaterial, UINT8 subMeshId); void BuildVertexBuffer(const SceneContext& sceneContext, UINT inputLayoutID, UINT inputLayoutSize, const std::vector& inputLayoutDescriptions, UINT8 subMeshId); void BuildVertexBuffer(const D3D11Context& d3dContext, UINT inputLayoutID, UINT inputLayoutSize, const std::vector& inputLayoutDescriptions, UINT8 subMeshId); std::wstring m_MeshName{}; std::vector m_Meshes{}; std::vector m_AnimationClips{}; bool m_HasAnimations{}; USHORT m_BoneCount{}; static XMFLOAT4 m_DefaultColor; static XMFLOAT4 m_DefaultFloat4; static XMFLOAT3 m_DefaultFloat3; static XMFLOAT2 m_DefaultFloat2; };