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