Mesh.h#

Parent directory (model)

Represent a Mesh, usually an object (collection of primitives) that use the same transformation (but can be skinned) and material.

Includes#

  • PVRAssets/IndexedArray.h

  • PVRCore/strings/StringHash.h

  • PVRCore/types/FreeValue.h

  • PVRCore/types/Types.h

Included By#

Namespaces#

Classes#

Source Code#

#pragma once
#include "PVRCore/strings/StringHash.h"
#include "PVRCore/types/Types.h"
#include "PVRCore/types/FreeValue.h"
#include "PVRAssets/IndexedArray.h"

namespace pvr {
namespace assets {
class Mesh
{
public:
    const FreeValue* getMeshSemantic(const StringHash& semantic) const
    {
        auto it = _data.semantics.find(semantic);
        if (it == _data.semantics.end()) { return NULL; }
        return &it->second;
    }

    const std::shared_ptr<void>& getUserDataPtr() const { return this->_data.userDataPtr; }
    std::shared_ptr<void> getUserDataPtr() { return this->_data.userDataPtr; }

    void setUserDataPtr(const std::shared_ptr<void>& ptr) { _data.userDataPtr = ptr; }
    class VertexAttributeData
    {
    private:
        StringHash _semantic; // Semantic for this element
        VertexAttributeLayout _layout;
        uint16_t _dataIndex; // Getters, setters and constructors
    public:
        VertexAttributeData() : _layout(DataType::None, static_cast<uint8_t>(0), static_cast<uint16_t>(0)), _dataIndex(static_cast<uint16_t>(-1)) {}

        VertexAttributeData(const StringHash& semantic, DataType type, uint8_t n, uint16_t offset, uint16_t dataIndex)
            : _semantic(semantic), _layout(type, n, offset), _dataIndex(dataIndex)
        {}

        const StringHash& getSemantic() const { return _semantic; }

        uint32_t getOffset() const { return _layout.offset; }

        const VertexAttributeLayout& getVertexLayout() const { return _layout; }

        uint32_t getN() const { return _layout.width; }

        uint32_t getDataIndex() const { return _dataIndex; }

        void setSemantic(const StringHash& semantic) { _semantic = semantic; }

        void setDataType(DataType type);

        void setOffset(uint32_t offset);

        void setN(uint8_t n);

        void setDataIndex(uint16_t dataIndex);

        bool operator==(const VertexAttributeData& rhs) { return _semantic == rhs._semantic; }

        bool operator<(const VertexAttributeData& rhs) { return _semantic < rhs._semantic; }
    };

    class FaceData
    {
        friend class Mesh;

    protected:
        IndexType _indexType;
        UInt8Buffer _data;

    public:
        FaceData();

        IndexType getDataType() const { return _indexType; }

        const uint8_t* getData() const { return _data.data(); }

        uint8_t* getData() { return _data.data(); }

        uint32_t getDataSize() const { return static_cast<uint32_t>(_data.size()); }

        uint32_t getDataTypeSize() const { return _indexType == IndexType::IndexType16Bit ? 16u : 32u; }

        void setData(const uint8_t* data, uint32_t size, const IndexType indexType = IndexType::IndexType16Bit);
    };

    struct MeshInfo
    {
        uint32_t numVertices;
        uint32_t numFaces;

        std::vector<uint32_t> stripLengths;

        uint32_t numPatchSubdivisions;
        uint32_t numPatches;
        uint32_t numControlPointsPerPatch;

        float units;
        PrimitiveTopology primitiveType;
        bool isIndexed;
        bool isSkinned;

        glm::vec3 min;
        glm::vec3 max;

        MeshInfo()
            : numVertices(0), numFaces(0), numPatchSubdivisions(0), numPatches(0), numControlPointsPerPatch(0), units(1.0f), primitiveType(PrimitiveTopology::TriangleList),
              isIndexed(true), isSkinned(0), min(std::numeric_limits<float>::min()), max(std::numeric_limits<float>::max())
        {}
    };

    typedef IndexedArray<VertexAttributeData, StringHash> VertexAttributeContainer;

    struct InternalData
    {
        std::map<StringHash, FreeValue> semantics;
        VertexAttributeContainer vertexAttributes;
        std::vector<StridedBuffer> vertexAttributeDataBlocks;
        uint32_t numBones;

        FaceData faces;
        MeshInfo primitiveData;

        int32_t skeleton;

        glm::mat4x4 unpackMatrix;
        std::shared_ptr<void> userDataPtr;

        InternalData() : skeleton(-1) {}
    };

private:
    InternalData _data;
    class PredicateVertAttribMinOffset
    {
    public:
        const VertexAttributeContainer& container;
        PredicateVertAttribMinOffset(const VertexAttributeContainer& container) : container(container) {}
        bool operator()(uint16_t lhs, uint16_t rhs) { return container[lhs].getOffset() < container[rhs].getOffset(); }
    };

public:
    void setStride(uint32_t index, uint32_t stride); // a size of 0 is supported

    int32_t addData(const uint8_t* data, uint32_t size, uint32_t stride); // a size of 0 is supported

    int32_t addData(const uint8_t* data, uint32_t size, uint32_t stride, uint32_t index); // a size of 0 is supported

    void removeData(uint32_t index); // Will update Vertex Attributes so they don't point at this data

    void clearAllData() { _data.vertexAttributeDataBlocks.clear(); }

    const void* getData(uint32_t index) const { return static_cast<const void*>(_data.vertexAttributeDataBlocks[index].data()); }

    uint8_t* getData(uint32_t index) { return (index >= _data.vertexAttributeDataBlocks.size()) ? NULL : _data.vertexAttributeDataBlocks[index].data(); }

    size_t getDataSize(uint32_t index) const { return _data.vertexAttributeDataBlocks[index].size(); }
    uint32_t getStride(uint32_t index) const
    {
        debug_assertion(index < _data.vertexAttributeDataBlocks.size(), "Stride index out of bound");
        return _data.vertexAttributeDataBlocks[index].stride;
    }

    void addFaces(const uint8_t* data, uint32_t size, const IndexType indexType);

    int32_t addVertexAttribute(const VertexAttributeData& element, bool forceReplace = false);

    int32_t addVertexAttribute(const StringHash& semanticName, const DataType& type, uint32_t width, uint32_t offset, uint32_t dataIndex, bool forceReplace = false);

    void removeVertexAttribute(const StringHash& semanticName);

    void removeAllVertexAttributes();

    uint32_t getNumVertices() const { return _data.primitiveData.numVertices; }

    uint32_t getNumFaces() const { return _data.primitiveData.numFaces; }

    uint32_t getNumIndices() const
    {
        return static_cast<uint32_t>(
            _data.primitiveData.stripLengths.size() ? _data.primitiveData.numFaces + (_data.primitiveData.stripLengths.size() * 2) : _data.primitiveData.numFaces * 3);
    }

    uint32_t getNumElements() const { return static_cast<uint32_t>(_data.vertexAttributes.size()); }

    uint32_t getNumDataElements() const { return static_cast<uint32_t>(_data.vertexAttributeDataBlocks.size()); }

    uint32_t getNumBoneBatches() const { return _data.primitiveData.isSkinned ? 1u : 0u; }

    PrimitiveTopology getPrimitiveType() const { return _data.primitiveData.primitiveType; }

    void setPrimitiveType(const PrimitiveTopology& type) { _data.primitiveData.primitiveType = type; }

    const MeshInfo& getMeshInfo() const { return _data.primitiveData; }

    MeshInfo& getMeshInfo() { return _data.primitiveData; }

    int32_t getSkeletonId() const { return _data.skeleton; }

    const glm::mat4x4& getUnpackMatrix() const { return _data.unpackMatrix; }
    void setUnpackMatrix(const glm::mat4x4& unpackMatrix) { _data.unpackMatrix = unpackMatrix; }

    const std::vector<StridedBuffer>& getVertexData() const { return _data.vertexAttributeDataBlocks; }

    const StridedBuffer& getVertexData(uint32_t n) const { return _data.vertexAttributeDataBlocks[n]; }

    const FaceData& getFaces() const { return _data.faces; }

    FaceData& getFaces() { return _data.faces; }

    uint32_t getNumBones() const { return _data.numBones; }
    const VertexAttributeData* getVertexAttributeByName(const StringHash& semanticName) const
    {
        VertexAttributeContainer::const_index_iterator found = _data.vertexAttributes.indexed_find(semanticName);
        if (found != _data.vertexAttributes.indexed_end()) { return &(_data.vertexAttributes[found->second]); }
        return NULL;
    }

    int32_t getVertexAttributeIndex(const char* semanticName) const { return static_cast<int32_t>(_data.vertexAttributes.getIndex(semanticName)); }

    const VertexAttributeData* getVertexAttribute(int32_t idx) const
    {
        return (static_cast<uint32_t>(idx) < _data.vertexAttributes.sizeWithDeleted() ? &_data.vertexAttributes[static_cast<size_t>(idx)] : NULL);
    }

    uint32_t getVertexAttributesSize() const { return static_cast<uint32_t>(_data.vertexAttributes.size()); }

    void setVertexAttributeIndex(const char* attributeName, size_t userIndex) { _data.vertexAttributes.relocate(attributeName, userIndex); }

    VertexAttributeContainer& getVertexAttributes() { return _data.vertexAttributes; }

    const VertexAttributeContainer& getVertexAttributes() const { return _data.vertexAttributes; }

    uint32_t getNumStrips() const { return static_cast<uint32_t>(_data.primitiveData.stripLengths.size()); }

    const uint32_t* getStripLengths() const { return _data.primitiveData.stripLengths.data(); }

    uint32_t getStripLength(uint32_t strip) const { return _data.primitiveData.stripLengths[strip]; }

    void setStripData(uint32_t numStrips, const uint32_t* lengths)
    {
        _data.primitiveData.stripLengths.resize(numStrips);
        _data.primitiveData.stripLengths.assign(lengths, lengths + numStrips);
    }

    void setNumVertices(uint32_t numVertices) { _data.primitiveData.numVertices = numVertices; }

    void setNumFaces(uint32_t numFaces) { _data.primitiveData.numFaces = numFaces; }

    InternalData& getInternalData() { return _data; }
};
} // namespace assets
} // namespace pvr