#pragma once #include "CmPrerequisites.h" #include "CmIReflectable.h" #include "CmVertexBuffer.h" #include "CmIndexBuffer.h" #include "CmVertexDeclaration.h" namespace CamelotEngine { class CM_EXPORT MeshData : public IReflectable { public: struct VertexElementData : public IReflectable { VertexElementData(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx, UINT8* _data, UINT32 numElements) :data(_data), elementCount(numElements), element(streamIdx, 0, type, semantic, semanticIdx) { } UINT8* data; UINT32 elementCount; VertexElement element; /************************************************************************/ /* SERIALIZATION */ /************************************************************************/ public: VertexElementData() :data(nullptr), elementCount(0) {} // Serialization only constructor friend class VertexElementDataRTTI; static RTTITypeBase* getRTTIStatic(); virtual RTTITypeBase* getRTTI() const; }; struct IndexElementData : public IReflectable { IndexElementData() :numIndices(0), subMesh(0), elementSize(0), indices(nullptr) { } UINT8* indices; UINT32 numIndices; UINT32 elementSize; UINT32 subMesh; /************************************************************************/ /* SERIALIZATION */ /************************************************************************/ public: friend class IndexElementDataRTTI; static RTTITypeBase* getRTTIStatic(); virtual RTTITypeBase* getRTTI() const; }; MeshData(IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT); ~MeshData(); /** * @brief Allocates a buffer for holding a specified amount of vertex positions, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector2* addPositionsVec2(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex positions, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector3* addPositionsVec3(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex positions, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector4* addPositionsVec4(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex normals, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector3* addNormals(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex tangents, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector3* addTangentsVec3(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex tangents, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector4* addTangentsVec4(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex bitangents, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector3* addBitangents(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex texture coordinates, * and returns a pointer the user can use to populate the buffer. If a previous set * of data exists in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector2* addUV0(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex texture coordinates, * and returns a pointer the user can use to populate the buffer. If a previous set * of data exists in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Vector2* addUV1(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex colors, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ Color* addColorsFloat(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex colors, and returns a * pointer the user can use to populate the buffer. If a previous set of data exists * in this same stream slot, it will be deleted. * * @param numElements Number of elements in the elements array. * @param streamIdx (optional) Zero-based index of the stream. Each stream will * internally be represented as a single vertex buffer. */ UINT32* addColorsDWORD(UINT32 numElements, UINT32 streamIdx = 0); /** * @brief Allocates a buffer for holding a specified amount of vertex data, and returns a * pointer the user can use to populate the buffer. Anything that was previously * present at the same data slot is removed. * * @param type Type of the vertex element. Determines size. * @param semantic Semantic that allows the engine to connect the data to a shader input slot. * @param numElements Number of elements in the array. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer. */ UINT8* addVertexElementData(VertexElementType type, VertexElementSemantic semantic, UINT32 numElements, UINT32 semanticIdx = 0, UINT32 streamIdx = 0); /** * @brief Allocates buffer for the indices for the specified sub mesh, and returns a * pointer the user can use to populate the buffer. Any indexes previously * set for the sub mesh are deleted. * * @param numIndices Number of indices. * @param subMesh (optional) the sub mesh. */ UINT32* addIndices32(UINT32 numIndices, UINT32 subMesh = 0); /** * @brief Allocates buffer for the indices for the specified sub mesh, and returns a * pointer the user can use to populate the buffer. Any indexes previously * set for the sub mesh are deleted. * * @param numIndices Number of indices. * @param subMesh (optional) the sub mesh. */ UINT16* addIndices16(UINT32 numIndices, UINT32 subMesh = 0); /** * @brief Query if we have vertex data for the specified semantic. */ bool hasElement(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const; /** * @brief Creates a new vertex declaration based on set vertex elements. */ VertexDeclarationPtr createDeclaration() const; UINT32 getNumSubmeshes() const { return (UINT32)mIndices.size(); } UINT32 getNumVertices() const; UINT32 getNumIndices(UINT32 subMesh) const; UINT16* getIndices16(UINT32 subMesh) const; UINT32* getIndices32(UINT32 subMesh) const; vector::type getVertexElements() const; MeshData::VertexElementData& getVertElemData(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx); UINT32 getIndexElementSize() { return mIndexType == IndexBuffer::IT_32BIT ? sizeof(UINT32) : sizeof(UINT16); } static MeshDataPtr combine(const vector::type& elements); private: friend class Mesh; vector::type mIndices; map::type>::type mVertexData; IndexBuffer::IndexType mIndexType; void clearIfItExists(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx); /************************************************************************/ /* SERIALIZATION */ /************************************************************************/ public: friend class MeshDataRTTI; static RTTITypeBase* getRTTIStatic(); virtual RTTITypeBase* getRTTI() const; }; }