#pragma once #include "Graphics/Initializer.h" #include "Material/MaterialInstance.h" #include "Component/Transform.h" #include "Containers/List.h" #include "Graphics/Command.h" #include "Graphics/Descriptor.h" #include "Graphics/Buffer.h" #include "Math/AABB.h" namespace Seele { DECLARE_REF(Mesh) struct MeshId { uint64 id; std::strong_ordering operator<=>(const MeshId& other) const { return id <=> other.id; } bool operator==(const MeshId& other) const { return id == other.id; } }; struct Meshlet { AABB boundingBox; uint32 uniqueVertices[Gfx::numVerticesPerMeshlet]; // unique vertiex indices in the vertex data uint8 primitiveLayout[Gfx::numPrimitivesPerMeshlet * 3]; // indices into the uniqueVertices array, only uint8 needed uint32 numVertices; uint32 numPrimitives; static void build(const Array& positions, const Array& indices, Array& meshlets); }; class VertexData { public: struct InstanceData { Matrix4 transformMatrix; }; struct MeshData { uint32 meshletOffset = 0; uint16 numMeshlets = 0; uint16 indicesOffset = 0; uint32 firstIndex = 0; uint32 numIndices = 0; }; static_assert(sizeof(MeshData) == 16); struct MeshInstanceData { InstanceData instance; MeshData data; }; struct MaterialInstanceData { PMaterialInstance materialInstance; Gfx::OShaderBuffer instanceBuffer; Gfx::OShaderBuffer meshDataBuffer; Gfx::PDescriptorSet descriptorSet; Array meshes; }; struct MaterialData { PMaterial material; Map instances; }; void resetMeshData(); void updateMesh(PMesh mesh, Component::Transform& transform); void createDescriptors(); void loadMesh(MeshId id, Array indices, Array meshlets); MeshId allocateVertexData(uint64 numVertices); uint64 getMeshOffset(MeshId id); uint64 getMeshVertexCount(MeshId id); virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) = 0; virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) = 0; virtual void bindBuffers(Gfx::PRenderCommand command) = 0; virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0; virtual Gfx::PDescriptorSet getVertexDataSet() = 0; virtual std::string getTypeName() const = 0; Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; } Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; } const Map& getMaterialData() const { return materialData; } const Array& getMeshData(MeshId id) { return meshData[id]; } static List getList(); static VertexData* findByTypeName(std::string name); virtual void init(Gfx::PGraphics graphics); virtual void destroy(); protected: virtual void resizeBuffers() = 0; virtual void updateBuffers() = 0; VertexData(); struct MeshletDescription { uint32_t vertexCount; uint32_t primitiveCount; uint32_t vertexOffset; uint32_t primitiveOffset; }; Map materialData; Map> meshData; Map meshOffsets; Map meshVertexCounts; Array meshlets; Array primitiveIndices; Array vertexIndices; Array indices; Gfx::PGraphics graphics; Gfx::ODescriptorLayout instanceDataLayout; // for mesh shading Gfx::OShaderBuffer meshletBuffer; Gfx::OShaderBuffer vertexIndicesBuffer; Gfx::OShaderBuffer primitiveIndicesBuffer; // for legacy pipeline Gfx::OIndexBuffer indexBuffer; uint64 idCounter; uint64 head; uint64 verticesAllocated; bool dirty; }; }