class new in 2020.06
#include <Magnum/Trade/MeshData.h>
MeshData Mesh data.
Provides access to mesh vertex and index data, together with additional information such as primitive type. Populated instances of this class are returned from AbstractImporter::
Populating an OpenGL mesh
If the goal is creating a GL::
Trade::MeshData data = …; GL::Mesh mesh = MeshTools::compile(data);
This works also with any custom shader that follows the attribute binding defined in Shaders::
Setting GPU mesh properties directly
If you need more control, for example in presence of custom attributes, if you have a custom shader that doesn't follow the attribute binding defined in Shaders::
GL::Mesh mesh{data.primitive()}; mesh.setCount(data.indexCount()); /* Upload index data and configure their layout */ GL::Buffer indices{data.indexData()}; mesh.setIndexBuffer(indices, 0, data.indexType()); /* Upload vertex data and set up position and normal attributes */ GL::Buffer vertices{data.vertexData()}; mesh.addVertexBuffer(vertices, data.attributeOffset(Trade::MeshAttribute::Position), data.attributeStride(Trade::MeshAttribute::Position), GL::DynamicAttribute{Shaders::PhongGL::Position{}, data.attributeFormat(Trade::MeshAttribute::Position)}); mesh.addVertexBuffer(vertices, data.attributeOffset(Trade::MeshAttribute::Normal), data.attributeStride(Trade::MeshAttribute::Normal), GL::DynamicAttribute{Shaders::PhongGL::Normal{}, data.attributeFormat(Trade::MeshAttribute::Normal)});
If using a shader that follows the Shaders::
Accessing mesh data
When access to individual attributes from the CPU side is desired, for example to inspect the topology or to pass the data to a physics simulation, the simplest way is accessing attributes through the convenience indicesAsArray(), positions3DAsArray(), normalsAsArray() etc. functions. Unless the mesh has a known layout, you're expected to check for index buffer and attribute presence first with isIndexed() and hasAttribute() (or, in case you need to access for example secondary texture coordinates, attributeCount(MeshAttribute, Int) const). Apart from that, the convenience functions abstract away the internal layout of the mesh data, giving you always a contiguous array in a predictable type.
if(data.primitive() != MeshPrimitive::Triangles || !data.isIndexed() || !data.hasAttribute(Trade::MeshAttribute::Position)) Fatal{} << "Oh well"; /* Calculate the face area */ Containers::Array<UnsignedInt> indices = data.indicesAsArray(); Containers::Array<Vector3> positions = data.positions3DAsArray(); Float area = 0.0f; for(std::size_t i = 0; i < indices.size(); i += 3) area += Math::cross( positions[indices[i + 1]] - positions[indices[i]], positions[indices[i + 2]] - positions[indices[i]]).length()*0.5f;
If allocation is undesirable, the indicesInto(), positions3DInto() etc. variants take a target view where to put the output instead of returning a newly created array. The most efficient way is without copies or conversions however, by direct accessing the index and attribute data using indices() and attribute(). In that case you additionally need to be sure about the data types used or decide based on indexType() and attributeFormat(). Replacing the above with with direct data access would look like this:
… if(data.indexType() != MeshIndexType::UnsignedInt || data.attributeFormat(Trade::MeshAttribute::Position) != VertexFormat::Vector3) Fatal{} << "Dang"; Containers::StridedArrayView1D<const UnsignedInt> indices = data.indices<UnsignedInt>(); Containers::StridedArrayView1D<const Vector3> positions = data.attribute<Vector3>(Trade::MeshAttribute::Position);
There are also non-templated type-erased indices() and attribute() overloads returning void
views, useful for example when a dispatch based on the actual type is deferred to an external function. Compared to using the template versions you however lose the type safety checks implemented in MeshData itself.
Mutable data access
In a general case, mesh index and vertex data can also refer to a memory-mapped file or constant memory and thus indices() and attribute() return const
views. When it's desirable to modify the data in-place, there's the mutableIndexData(), mutableVertexData(), mutableIndices() and mutableAttribute() set of functions. To use these, you need to additionally check that the data are mutable using indexDataFlags() or vertexDataFlags() first. Further continuing from the above, this snippet applies a transformation to the mesh positions in-place:
… if(data.attributeFormat(Trade::MeshAttribute::Position) != VertexFormat::Vector3) Fatal{} << "Sigh"; /* Scale the mesh two times */ Matrix4 transformation = Matrix4::scaling(Vector3{2.0f}); for(Vector3& i: data.mutableAttribute<Vector3>(Trade::MeshAttribute::Position)) i = transformation.transformPoint(i);
Morph targets
By default, named attribute access (either through the positions3DAsArray() etc. convenience accesors or via attribute() and similar) searches only through the base attributes. Meshes that have morph targets can have the additional attributes accessed by passing a morphTargetId
argument to these functions:
if(!data.hasAttribute(Trade::MeshAttribute::Position, 0) || !data.hasAttribute(Trade::MeshAttribute::Position, 1)) Fatal{} << "Positions not present in morph targets 0 and 1"; Float weights[]{0.25f, 0.5f}; /* Calculate morphed positions with the above weights */ Containers::Array<Vector3> positions = data.positions3DAsArray(0, -1); for(Int morphTargetId: {0, 1}) { Containers::StridedArrayView1D<const Vector3> morphed = data.attribute<Vector3>(Trade::MeshAttribute::Position, 0, morphTargetId); for(std::size_t i = 0; i != data.vertexCount(); ++i) positions[i] += morphed[i]*weights[morphTargetId]; }
If a base attribute doesn't have a corresponding morph target attribute (which can be checked using hasAttribute(MeshAttribute, Int) const with appropriate morphTargetId
passed), the base attribute is meant to be used unchanged. Base attributes with multiple sets can have multiple sets of morph target attributes as well (which can be again checked using attributeCount(MeshAttribute, Int) const with appropriate morphTargetId
passed). If only some instances from the set have a morph target, the remaining attributes are expected to alias the base ones (i.e., have the same attributeOffset(), attributeStride() and attributeArraySize()) in order to match their numbering. Finally, there can attributes that are only defined among morph targets but have no corresponding base attribute. This isn't restricted in any way and their treatment is left to be application-specific.
Special data layouts
The class is able to represent data layouts beyond what's supported by common GPU vertex pipelines, in particular:
- attributes with zero stride (a single value repeated for all vertices),
- attributes with negative stride (causing the attribute data to be read in reverse order),
- indices in a non-contiguous array (strided, similar to attributes).
These are allowed in order to support certain special cases where it would otherwise be needed to perform a manual and potentially expensive data repacking operation before putting them in a MeshData. Unless explicitly stated otherwise, all Magnum APIs returning a MeshData (such as the Primitives library or various importer plugins) don't make use of those advanced data layout features; and conversely all Magnum APIs taking a MeshData are aware of such features and can handle them approriately.
When passing mesh data to the GPU, the MeshTools::
if(data.attributeStride(Trade::MeshAttribute::Position) <= 0 || data.attributeStride(Trade::MeshAttribute::Normal) <= 0 || (data.isIndexed() && !data.indices().isContiguous())) Fatal{} << "Uh oh"; // Now it's safe to use the Position and Normal attributes and the index buffer // in a GPU mesh
In order to convert a mesh with a special data layout to something the GPU vertex pipeline is able to consume, MeshTools::
Populating an instance
If the goal is creating a MeshData instance from individual attributes as opposed to getting it from an importer or as an output of another operation and making a copy of the data is acceptable, easiest is to pass them to the MeshTools::
Otherwise, creating a MeshData instance from scratch requires you to have all vertex data contained in a single chunk of memory. By default it takes over the ownership of an Containers::
struct Vertex { Vector3 position; Vector4 color; }; Containers::Array<char> indexData{indexCount*sizeof(UnsignedShort)}; Containers::Array<char> vertexData{vertexCount*sizeof(Vertex)}; … Containers::StridedArrayView1D<const Vertex> vertices = Containers::arrayCast<const Vertex>(vertexData); Containers::ArrayView<const UnsignedShort> indices = Containers::arrayCast<const UnsignedShort>(indexData); Trade::MeshData data{MeshPrimitive::Triangles, std::move(indexData), Trade::MeshIndexData{indices}, std::move(vertexData), { Trade::MeshAttributeData{Trade::MeshAttribute::Position, vertices.slice(&Vertex::position)}, Trade::MeshAttributeData{Trade::MeshAttribute::Color, vertices.slice(&Vertex::color)} }};
Non-owned instances and static vertex layouts
In some cases you may want the MeshData instance to only refer to external data without taking ownership, for example with a memory-mapped file, global data etc. For that, instead of moving in Containers::
const UnsignedShort indices[]{ … }; Vertex vertices[]{ … }; Trade::MeshData data{MeshPrimitive::Triangles, Trade::DataFlags{}, indices, Trade::MeshIndexData{indices}, Trade::DataFlag::Mutable, vertices, { Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::stridedArrayView(vertices).slice(&Vertex::position)}, Trade::MeshAttributeData{Trade::MeshAttribute::Color, Containers::stridedArrayView(vertices).slice(&Vertex::color)} }};
There are also other constructor overloads allowing you to mix and match owned vertex data with non-owned index data and vice versa. The MeshAttributeData list is still implicitly allocated in the above case, but it can also be defined externally and referenced via meshAttributeDataNonOwningArray() instead if desired. Finally, if the vertex layout is constant but the actual data is allocated / populated at runtime, the MeshAttributeData instances can be defined in a global array as offset-only:
struct Vertex { Vector3 position; Vector4 color; }; /* Layout known in advance, except for vertex count */ constexpr Trade::MeshAttributeData attributes[]{ Trade::MeshAttributeData{Trade::MeshAttribute::Position, VertexFormat::Vector3, offsetof(Vertex, position), 0, sizeof(Vertex)}, Trade::MeshAttributeData{Trade::MeshAttribute::Color, VertexFormat::Vector4, offsetof(Vertex, color), 15, sizeof(Vertex)} }; /* Actual data populated later */ Containers::Array<char> vertexData{vertexCount*sizeof(Vertex)}; … /* Using the statically defined attribute layout together with explicitly passed vertex count */ Trade::MeshData mesh{MeshPrimitive::Triangles, std::move(vertexData), Trade::meshAttributeDataNonOwningArray(attributes), vertexCount};
See also the corresponding MeshAttributeData documentation for offset-only fields.
Custom mesh attributes
To allow for greater flexibility, a MeshData instance can describe not just attributes that are predefined in the MeshAttribute enum, but also custom attributes, created with meshAttributeCustom(). For example, the snippet below describes a custom per-face structure that exposes faces as higher-order polygons combining multiple triangles together —in this case, each face has an array of 15 IDs, which is exposed as a 2D array:
/* Each face can consist of 15 triangles at most, triangleCount says how many indices in triangleIds are valid */ struct Face { UnsignedShort triangleIds[15]; UnsignedByte triangleCount; }; constexpr Trade::MeshAttribute TriangleIds = Trade::meshAttributeCustom(0x01); constexpr Trade::MeshAttribute TriangleCount = Trade::meshAttributeCustom(0x02); Containers::Array<char> vertexData; auto faces = Containers::arrayCast<const Face>(vertexData); Trade::MeshData data{MeshPrimitive::Faces, std::move(vertexData), { Trade::MeshAttributeData{TriangleIds, Containers::StridedArrayView2D<const UnsignedShort>{faces, &faces[0].triangleIds[0], {faces.size(), 15}, {sizeof(Face), sizeof(UnsignedShort)}}}, Trade::MeshAttributeData{TriangleCount, Containers::StridedArrayView1D<const UnsignedByte>{faces, &faces[0].triangleCount, faces.size(), sizeof(Face)}} }};
Later, the (array) attributes can be retrieved back using the same custom identifiers — note the use of []
to get back a 2D array again:
Containers::StridedArrayView2D<const UnsignedShort> triangleIds = data.attribute<UnsignedShort[]>(TriangleIds); Containers::StridedArrayView1D<const UnsignedByte> triangleCounts = data.attribute<UnsignedByte>(TriangleCount);
When a custom attribute is exposed through AbstractImporter, it's possible to map custom MeshAttribute values to human-readable string names using AbstractImporter::
Public types
- enum (anonymous): UnsignedInt { ImplicitVertexCount = ~UnsignedInt{} }
Constructors, destructors, conversion operators
-
MeshData(MeshPrimitive primitive,
Containers::
Array<char>&& indexData, const MeshIndexData& indices, Containers:: Array<char>&& vertexData, Containers:: Array<MeshAttributeData>&& attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit noexcept - Construct an indexed mesh data.
-
MeshData(MeshPrimitive primitive,
Containers::
Array<char>&& indexData, const MeshIndexData& indices, Containers:: Array<char>&& vertexData, std:: initializer_list<MeshAttributeData> attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit -
MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers::
ArrayView<const void> indexData, const MeshIndexData& indices, DataFlags vertexDataFlags, Containers:: ArrayView<const void> vertexData, Containers:: Array<MeshAttributeData>&& attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit noexcept - Construct indexed mesh data with non-owned index and vertex data.
-
MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers::
ArrayView<const void> indexData, const MeshIndexData& indices, DataFlags vertexDataFlags, Containers:: ArrayView<const void> vertexData, std:: initializer_list<MeshAttributeData> attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit -
MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers::
ArrayView<const void> indexData, const MeshIndexData& indices, Containers:: Array<char>&& vertexData, Containers:: Array<MeshAttributeData>&& attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit noexcept - Construct indexed mesh data with non-owned index data.
-
MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers::
ArrayView<const void> indexData, const MeshIndexData& indices, Containers:: Array<char>&& vertexData, std:: initializer_list<MeshAttributeData> attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit -
MeshData(MeshPrimitive primitive,
Containers::
Array<char>&& indexData, const MeshIndexData& indices, DataFlags vertexDataFlags, Containers:: ArrayView<const void> vertexData, Containers:: Array<MeshAttributeData>&& attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit noexcept - Construct indexed mesh data with non-owned vertex data.
-
MeshData(MeshPrimitive primitive,
Containers::
Array<char>&& indexData, const MeshIndexData& indices, DataFlags vertexDataFlags, Containers:: ArrayView<const void> vertexData, std:: initializer_list<MeshAttributeData> attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit -
MeshData(MeshPrimitive primitive,
Containers::
Array<char>&& vertexData, Containers:: Array<MeshAttributeData>&& attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit noexcept - Construct a non-indexed mesh data.
-
MeshData(MeshPrimitive primitive,
Containers::
Array<char>&& vertexData, std:: initializer_list<MeshAttributeData> attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit -
MeshData(MeshPrimitive primitive,
DataFlags vertexDataFlags,
Containers::
ArrayView<const void> vertexData, Containers:: Array<MeshAttributeData>&& attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit noexcept - Construct a non-owned non-indexed mesh data.
-
MeshData(MeshPrimitive primitive,
DataFlags vertexDataFlags,
Containers::
ArrayView<const void> vertexData, std:: initializer_list<MeshAttributeData> attributes, UnsignedInt vertexCount = ImplicitVertexCount, const void* importerState = nullptr) explicit -
MeshData(MeshPrimitive primitive,
Containers::
Array<char>&& indexData, const MeshIndexData& indices, UnsignedInt vertexCount, const void* importerState = nullptr) explicit noexcept - Construct an attribute-less indexed mesh data.
-
MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers::
ArrayView<const void> indexData, const MeshIndexData& indices, UnsignedInt vertexCount, const void* importerState = nullptr) explicit noexcept - Construct a non-owned attribute-less indexed mesh data.
- MeshData(MeshPrimitive primitive, UnsignedInt vertexCount, const void* importerState = nullptr) explicit noexcept
- Construct an index-less attribute-less mesh data.
- MeshData(const MeshData&) deleted
- Copying is not allowed.
- MeshData(MeshData&&) noexcept
- Move constructor.
Public functions
- auto operator=(const MeshData&) -> MeshData& deleted
- Copying is not allowed.
- auto operator=(MeshData&&) -> MeshData& noexcept
- Move assignment.
- auto primitive() const -> MeshPrimitive
- Primitive.
- auto indexDataFlags() const -> DataFlags
- Index data flags.
- auto vertexDataFlags() const -> DataFlags
- Vertex data flags.
-
auto indexData() const & -> Containers::
ArrayView<const char> - Raw index data.
-
auto indexData() const && -> Containers::
ArrayView<const char> deleted - Taking a view to a r-value instance is not allowed.
-
auto mutableIndexData() & -> Containers::
ArrayView<char> - Mutable raw index data.
-
auto mutableIndexData() && -> Containers::
ArrayView<char> deleted - Taking a view to a r-value instance is not allowed.
-
auto attributeData() const & -> Containers::
ArrayView<const MeshAttributeData> - Raw attribute metadata.
-
auto attributeData() && -> Containers::
ArrayView<const MeshAttributeData> deleted - Taking a view to a r-value instance is not allowed.
-
auto vertexData() const & -> Containers::
ArrayView<const char> - Raw vertex data.
-
auto vertexData() const && -> Containers::
ArrayView<const char> deleted - Taking a view to a r-value instance is not allowed.
-
auto mutableVertexData() & -> Containers::
ArrayView<char> - Mutable raw vertex data.
-
auto mutableVertexData() && -> Containers::
ArrayView<char> deleted - Taking a view to a r-value instance is not allowed.
- auto isIndexed() const -> bool
- Whether the mesh is indexed.
- auto indexCount() const -> UnsignedInt
- Index count.
- auto indexType() const -> MeshIndexType
- Index type.
-
auto indexOffset() const -> std::
size_t - Index offset.
- auto indexStride() const -> Short new in Git master
- Index stride.
-
auto indices() const -> Containers::
StridedArrayView2D<const char> - Indices.
-
auto mutableIndices() -> Containers::
StridedArrayView2D<char> - Mutable indices.
-
template<class T>auto indices() const -> Containers::
StridedArrayView1D<const T> - Indices in a concrete type.
-
template<class T>auto mutableIndices() -> Containers::
StridedArrayView1D<T> - Mutable indices in a concrete type.
- auto vertexCount() const -> UnsignedInt
- Vertex count.
- auto attributeCount() const -> UnsignedInt
- Total attribute count.
- auto attributeCount(Int morphTargetId) const -> UnsignedInt new in Git master
- Attribute count for given morph target.
- auto attributeData(UnsignedInt id) const -> MeshAttributeData
- Raw attribute data.
- auto attributeName(UnsignedInt id) const -> MeshAttribute
- Attribute name.
- auto attributeId(UnsignedInt id) const -> UnsignedInt new in Git master
- Attribute ID in a set of attributes of the same name and morph target ID.
- auto attributeFormat(UnsignedInt id) const -> VertexFormat
- Attribute format.
-
auto attributeOffset(UnsignedInt id) const -> std::
size_t - Attribute offset.
- auto attributeStride(UnsignedInt id) const -> Short
- Attribute stride.
- auto attributeArraySize(UnsignedInt id) const -> UnsignedShort
- Attribute array size.
- auto attributeMorphTargetId(UnsignedInt id) const -> Int new in Git master
- Attribute morph target ID.
- auto hasAttribute(MeshAttribute name, Int morphTargetId = -1) const -> bool
- Whether the mesh has given attribute.
- auto attributeCount(MeshAttribute name, Int morphTargetId = -1) const -> UnsignedInt
- Count of given named attribute.
-
auto findAttributeId(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Optional<UnsignedInt> new in Git master - Find an absolute ID of a named attribute.
- auto attributeId(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const -> UnsignedInt
- Absolute ID of a named attribute.
- auto attributeFormat(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const -> VertexFormat
- Format of a named attribute.
-
auto attributeOffset(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const -> std::
size_t - Offset of a named attribute.
- auto attributeStride(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const -> Short
- Stride of a named attribute.
- auto attributeArraySize(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const -> UnsignedShort
- Array size of a named attribute.
-
auto attribute(UnsignedInt id) const -> Containers::
StridedArrayView2D<const char> - Data for given attribute.
-
auto mutableAttribute(UnsignedInt id) -> Containers::
StridedArrayView2D<char> - Mutable data for given attribute.
-
template<class T, class = typename std::auto attribute(UnsignedInt id) const -> Containers::
enable_if<!std:: is_array<T>::value>::type> StridedArrayView1D<const T> - Data for given attribute in a concrete type.
-
template<class T, class = typename std::auto attribute(UnsignedInt id) const -> Containers::
enable_if<std:: is_array<T>::value>::type> StridedArrayView2D<const typename std:: remove_extent<T>::type> - Data for given array attribute in a concrete type.
-
template<class T, class = typename std::auto mutableAttribute(UnsignedInt id) -> Containers::
enable_if<!std:: is_array<T>::value>::type> StridedArrayView1D<T> - Mutable data for given attribute in a concrete type.
-
template<class T, class = typename std::auto mutableAttribute(UnsignedInt id) -> Containers::
enable_if<std:: is_array<T>::value>::type> StridedArrayView2D<typename std:: remove_extent<T>::type> - Mutable data for given array attribute in a concrete type.
-
auto attribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
StridedArrayView2D<const char> - Data for given named attribute.
-
auto mutableAttribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) -> Containers::
StridedArrayView2D<char> - Mutable data for given named attribute.
-
template<class T, class = typename std::auto attribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const -> Containers::
enable_if<!std:: is_array<T>::value>::type> StridedArrayView1D<const T> - Data for given named attribute in a concrete type.
-
template<class T, class = typename std::auto attribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const -> Containers::
enable_if<std:: is_array<T>::value>::type> StridedArrayView2D<const typename std:: remove_extent<T>::type> - Data for given named array attribute in a concrete type.
-
template<class T, class = typename std::auto mutableAttribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) -> Containers::
enable_if<!std:: is_array<T>::value>::type> StridedArrayView1D<T> - Mutable data for given named attribute in a concrete type.
-
template<class T, class = typename std::auto mutableAttribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) -> Containers::
enable_if<std:: is_array<T>::value>::type> StridedArrayView2D<typename std:: remove_extent<T>::type> - Mutable data for given named array attribute in a concrete type.
-
auto indicesAsArray() const -> Containers::
Array<UnsignedInt> - Indices as 32-bit integers.
-
void indicesInto(const Containers::
StridedArrayView1D<UnsignedInt>& destination) const - Indices as 32-bit integers into a pre-allocated view.
-
auto positions2DAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Vector2> - Positions as 2D float vectors.
-
void positions2DInto(const Containers::
StridedArrayView1D<Vector2>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Positions as 2D float vectors into a pre-allocated view.
-
auto positions3DAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Vector3> - Positions as 3D float vectors.
-
void positions3DInto(const Containers::
StridedArrayView1D<Vector3>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Positions as 3D float vectors into a pre-allocated view.
-
auto tangentsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Vector3> - Tangents as 3D float vectors.
-
void tangentsInto(const Containers::
StridedArrayView1D<Vector3>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Tangents as 3D float vectors into a pre-allocated view.
-
auto bitangentSignsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Float> - Bitangent signs as floats.
-
void bitangentSignsInto(const Containers::
StridedArrayView1D<Float>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Bitangent signs as floats into a pre-allocated view.
-
auto bitangentsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Vector3> - Bitangents as 3D float vectors.
-
void bitangentsInto(const Containers::
StridedArrayView1D<Vector3>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Bitangents as 3D float vectors into a pre-allocated view.
-
auto normalsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Vector3> - Normals as 3D float vectors.
-
void normalsInto(const Containers::
StridedArrayView1D<Vector3>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Normals as 3D float vectors into a pre-allocated view.
-
auto textureCoordinates2DAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Vector2> - Texture coordinates as 2D float vectors.
-
void textureCoordinates2DInto(const Containers::
StridedArrayView1D<Vector2>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Texture coordinates as 2D float vectors into a pre-allocated view.
-
auto colorsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const -> Containers::
Array<Color4> - Colors as RGBA floats.
-
void colorsInto(const Containers::
StridedArrayView1D<Color4>& destination, UnsignedInt id = 0, Int morphTargetId = -1) const - Colors as RGBA floats into a pre-allocated view.
-
auto jointIdsAsArray(UnsignedInt id = 0) const -> Containers::
Array<UnsignedInt> new in Git master - Skin joint IDs as unsigned int arrays.
-
void jointIdsInto(const Containers::
StridedArrayView2D<UnsignedInt>& destination, UnsignedInt id = 0) const new in Git master - Skin joint IDs as unsigned int arrays into a pre-allocated view.
-
auto weightsAsArray(UnsignedInt id = 0) const -> Containers::
Array<Float> new in Git master - Skin weights as float arrays.
-
void weightsInto(const Containers::
StridedArrayView2D<Float>& weightsDestination, UnsignedInt id = 0) const new in Git master - Skin weights as float arrays into a pre-allocated view.
-
auto objectIdsAsArray(UnsignedInt id = 0) const -> Containers::
Array<UnsignedInt> - Object IDs as 32-bit integers.
-
void objectIdsInto(const Containers::
StridedArrayView1D<UnsignedInt>& destination, UnsignedInt id = 0) const - Object IDs as 32-bit integers into a pre-allocated view.
-
auto releaseIndexData() -> Containers::
Array<char> - Release index data storage.
-
auto releaseAttributeData() -> Containers::
Array<MeshAttributeData> - Release attribute data storage.
-
auto releaseVertexData() -> Containers::
Array<char> - Release vertex data storage.
- auto importerState() const -> const void*
- Importer-specific state.
Enum documentation
enum Magnum:: Trade:: MeshData:: (anonymous): UnsignedInt
Enumerators | |
---|---|
ImplicitVertexCount |
Implicit vertex count. When passed to a constructor, indicates that vertex count should be taken from attribute data views. |
Function documentation
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
Containers:: Array<char>&& indexData,
const MeshIndexData& indices,
Containers:: Array<char>&& vertexData,
Containers:: Array<MeshAttributeData>&& attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit noexcept
Construct an indexed mesh data.
Parameters | |
---|---|
primitive | Primitive |
indexData | Index data |
indices | Index data description |
vertexData | Vertex data |
attributes | Description of all vertex attribute data |
vertexCount | Vertex count. If set to ImplicitVertexCount, vertex count is taken from data views passed to attributes (in which case there has to be at least one). |
importerState | Importer-specific state |
The indices
are expected to point to a sub-range of indexData
. For a non-indexed mesh either pass default-constructed indexData and indices
arguments, or use the MeshData(MeshPrimitive, Containers::
The attributes
are expected to reference (sparse) sub-ranges of vertexData
. Particular attributes can have additional restrictions, see documentation of MeshAttribute values for more information. If the mesh has no attributes, the indices
are expected to be valid (but can be empty), you can also use the MeshData(MeshPrimitive, Containers::
The indexDataFlags() / vertexDataFlags() are implicitly set to a combination of DataFlag::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
Containers:: Array<char>&& indexData,
const MeshIndexData& indices,
Containers:: Array<char>&& vertexData,
std:: initializer_list<MeshAttributeData> attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers:: ArrayView<const void> indexData,
const MeshIndexData& indices,
DataFlags vertexDataFlags,
Containers:: ArrayView<const void> vertexData,
Containers:: Array<MeshAttributeData>&& attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit noexcept
Construct indexed mesh data with non-owned index and vertex data.
Parameters | |
---|---|
primitive | Primitive |
indexDataFlags | Index data flags |
indexData | View on index data |
indices | Index data description |
vertexDataFlags | Vertex data flags |
vertexData | View on vertex data |
attributes | Description of all vertex attribute data |
vertexCount | Vertex count. If set to ImplicitVertexCount, vertex count is taken from data views passed to attributes (in which case there has to be at least one). |
importerState | Importer-specific state |
Compared to MeshData(MeshPrimitive, Containers::indexDataFlags
/ vertexDataFlags
parameters can contain DataFlag::
Use MeshData(MeshPrimitive, DataFlags, Containers::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers:: ArrayView<const void> indexData,
const MeshIndexData& indices,
DataFlags vertexDataFlags,
Containers:: ArrayView<const void> vertexData,
std:: initializer_list<MeshAttributeData> attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers:: ArrayView<const void> indexData,
const MeshIndexData& indices,
Containers:: Array<char>&& vertexData,
Containers:: Array<MeshAttributeData>&& attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit noexcept
Construct indexed mesh data with non-owned index data.
Parameters | |
---|---|
primitive | Primitive |
indexDataFlags | Index data flags |
indexData | View on index data |
indices | Index data description |
vertexData | Vertex data |
attributes | Description of all vertex attribute data |
vertexCount | Vertex count. If set to ImplicitVertexCount, vertex count is taken from data views passed to attributes (in which case there has to be at least one). |
importerState | Importer-specific state |
Compared to MeshData(MeshPrimitive, Containers::indexDataFlags
parameter can contain DataFlag::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers:: ArrayView<const void> indexData,
const MeshIndexData& indices,
Containers:: Array<char>&& vertexData,
std:: initializer_list<MeshAttributeData> attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
Containers:: Array<char>&& indexData,
const MeshIndexData& indices,
DataFlags vertexDataFlags,
Containers:: ArrayView<const void> vertexData,
Containers:: Array<MeshAttributeData>&& attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit noexcept
Construct indexed mesh data with non-owned vertex data.
Parameters | |
---|---|
primitive | Primitive |
indexData | Index data |
indices | Index data description |
vertexDataFlags | Vertex data flags |
vertexData | View on vertex data |
attributes | Description of all vertex attribute data |
vertexCount | Vertex count. If set to ImplicitVertexCount, vertex count is taken from data views passed to attributes (in which case there has to be at least one). |
importerState | Importer-specific state |
Compared to MeshData(MeshPrimitive, Containers::vertexDataFlags
parameter can contain DataFlag::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
Containers:: Array<char>&& indexData,
const MeshIndexData& indices,
DataFlags vertexDataFlags,
Containers:: ArrayView<const void> vertexData,
std:: initializer_list<MeshAttributeData> attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
Containers:: Array<char>&& vertexData,
Containers:: Array<MeshAttributeData>&& attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit noexcept
Construct a non-indexed mesh data.
Parameters | |
---|---|
primitive | Primitive |
vertexData | Vertex data |
attributes | Description of all vertex attribute data |
vertexCount | Vertex count. If set to ImplicitVertexCount, vertex count is taken from data views passed to attributes (in which case there has to be at least one). |
importerState | Importer-specific state |
Same as calling MeshData(MeshPrimitive, Containers::indexData
and indices
arguments.
The vertexDataFlags() are implicitly set to a combination of DataFlag::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
Containers:: Array<char>&& vertexData,
std:: initializer_list<MeshAttributeData> attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
DataFlags vertexDataFlags,
Containers:: ArrayView<const void> vertexData,
Containers:: Array<MeshAttributeData>&& attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit noexcept
Construct a non-owned non-indexed mesh data.
Parameters | |
---|---|
primitive | Primitive |
vertexDataFlags | Vertex data flags |
vertexData | View on vertex data |
attributes | Description of all vertex attribute data |
vertexCount | Vertex count. If set to ImplicitVertexCount, vertex count is taken from data views passed to attributes (in which case there has to be at least one). |
importerState | Importer-specific state |
Compared to MeshData(MeshPrimitive, Containers::vertexDataFlags
parameter can contain DataFlag::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
DataFlags vertexDataFlags,
Containers:: ArrayView<const void> vertexData,
std:: initializer_list<MeshAttributeData> attributes,
UnsignedInt vertexCount = ImplicitVertexCount,
const void* importerState = nullptr) explicit
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
Containers:: Array<char>&& indexData,
const MeshIndexData& indices,
UnsignedInt vertexCount,
const void* importerState = nullptr) explicit noexcept
Construct an attribute-less indexed mesh data.
Parameters | |
---|---|
primitive | Primitive |
indexData | Index data |
indices | Index data description |
vertexCount | Vertex count. Passing ImplicitVertexCount is not allowed in this overload. |
importerState | Importer-specific state |
Same as calling MeshData(MeshPrimitive, Containers::vertexData
and attributes
arguments. The indices
are expected to be valid (but can be empty). If you want to create an attribute-less non-indexed mesh, use MeshData(MeshPrimitive, UnsignedInt, const void*) instead.
The indexDataFlags() are implicitly set to a combination of DataFlag::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
DataFlags indexDataFlags,
Containers:: ArrayView<const void> indexData,
const MeshIndexData& indices,
UnsignedInt vertexCount,
const void* importerState = nullptr) explicit noexcept
Construct a non-owned attribute-less indexed mesh data.
Parameters | |
---|---|
primitive | Primitive |
indexDataFlags | Index data flags |
indexData | View on index data |
indices | Index data description |
vertexCount | Vertex count. Passing ImplicitVertexCount is not allowed in this overload. |
importerState | Importer-specific state |
Compared to MeshData(MeshPrimitive, Containers::indexDataFlags
parameter can contain DataFlag::
Magnum:: Trade:: MeshData:: MeshData(MeshPrimitive primitive,
UnsignedInt vertexCount,
const void* importerState = nullptr) explicit noexcept
Construct an index-less attribute-less mesh data.
Parameters | |
---|---|
primitive | Primitive |
vertexCount | Vertex count. Passing ImplicitVertexCount is not allowed in this overload. |
importerState | Importer-specific state |
Useful in case the drawing is fully driven by a shader. For consistency, the indexDataFlags() / vertexDataFlags() are implicitly set to a combination of DataFlag::
DataFlags Magnum:: Trade:: MeshData:: indexDataFlags() const
Index data flags.
DataFlags Magnum:: Trade:: MeshData:: vertexDataFlags() const
Vertex data flags.
Containers:: ArrayView<const char> Magnum:: Trade:: MeshData:: indexData() const &
Raw index data.
Returns nullptr
if the mesh is not indexed.
Containers:: ArrayView<char> Magnum:: Trade:: MeshData:: mutableIndexData() &
Mutable raw index data.
Like indexData(), but returns a non-const view. Expects that the mesh is mutable.
Containers:: ArrayView<const MeshAttributeData> Magnum:: Trade:: MeshData:: attributeData() const &
Raw attribute metadata.
Returns the raw data that are used as a base for all attribute*()
accessors, or nullptr
if the mesh has no attributes. In most cases you don't want to access those directly, but rather use the attribute(), attributeName(), attributeFormat(), attributeOffset(), attributeStride() etc. accessors. Compared to those and to attributeData(UnsignedInt) const, the MeshAttributeData instances returned by this function may have different data pointers, and some of them might be offset-only — use this function only if you really know what are you doing.
Containers:: ArrayView<const char> Magnum:: Trade:: MeshData:: vertexData() const &
Raw vertex data.
Contains data for all vertex attributes. Returns nullptr
if the mesh has no attributes.
Containers:: ArrayView<char> Magnum:: Trade:: MeshData:: mutableVertexData() &
Mutable raw vertex data.
Like vertexData(), but returns a non-const view. Expects that the mesh is mutable.
UnsignedInt Magnum:: Trade:: MeshData:: indexCount() const
Index count.
Count of elements in the indices() array. Expects that the mesh is indexed; returned value is always non-zero. See also vertexCount() which returns count of elements in every attribute() array, and attributeCount() which returns count of different per-vertex attribute arrays.
MeshIndexType Magnum:: Trade:: MeshData:: indexType() const
Index type.
Expects that the mesh is indexed.
std:: size_t Magnum:: Trade:: MeshData:: indexOffset() const
Index offset.
Byte offset of the first index from the beginning of the indexData(), or a byte difference between pointers returned from indexData() and indices(). Expects that the mesh is indexed.
Short Magnum:: Trade:: MeshData:: indexStride() const new in Git master
Index stride.
Stride between consecutive elements in the indexData() array. In rare cases the stride may be different from the index type size and even be zero or negative, such data layouts are however not commonly supported by GPU APIs.
Containers:: StridedArrayView2D<const char> Magnum:: Trade:: MeshData:: indices() const
Indices.
For an indexed mesh, the second dimension represent the actual data type (its size is equal to type size for known MeshIndexType values, and to absolute indexStride() for implementation-specific values), even in case there's zero indices, and is guaranteed to be contiguous. For a non-indexed mesh, the returned view has a zero size in both dimensions. In rare cases the first dimension stride may be different from the index type size and even be zero or negative, such data layouts are however not commonly supported by GPU APIs.
Use the templated overload below to get the indices in a concrete type.
Containers:: StridedArrayView2D<char> Magnum:: Trade:: MeshData:: mutableIndices()
Mutable indices.
Like indices() const, but returns a mutable view. Expects that the mesh is mutable.
template<class T>
Containers:: StridedArrayView1D<const T> Magnum:: Trade:: MeshData:: indices() const
Indices in a concrete type.
Expects that the mesh is indexed and that T
corresponds to indexType(). In rare cases the first dimension stride may be different from the index type size and even be zero or negative, such data layouts are however not commonly supported by GPU APIs. You can also use the non-templated indicesAsArray() accessor to get indices converted to a contiguous 32-bit array, but note that such operation involves extra allocation and data conversion.
template<class T>
Containers:: StridedArrayView1D<T> Magnum:: Trade:: MeshData:: mutableIndices()
Mutable indices in a concrete type.
Like indices() const, but returns a mutable view. Expects that the mesh is mutable.
UnsignedInt Magnum:: Trade:: MeshData:: vertexCount() const
Vertex count.
Count of elements in every attribute array returned by attribute() (or, in case of an attribute-less mesh, the desired vertex count). See also indexCount() which returns count of elements in the indices() array, and attributeCount() which returns count of different per-vertex attributes.
UnsignedInt Magnum:: Trade:: MeshData:: attributeCount() const
Total attribute count.
Count of all per-vertex attributes including extra attributes and morph targets, or 0
for an attribute-less mesh. See also indexCount() which returns count of elements in the indices() array and vertexCount() which returns count of elements in every attribute().
UnsignedInt Magnum:: Trade:: MeshData:: attributeCount(Int morphTargetId) const new in Git master
Attribute count for given morph target.
Count of attributes for which attributeMorphTargetId() is equal to morphTargetId
, or 0
if there's no such morph target. Use -1
to get the count of base attributes that aren't morph targets. Total number of attributes in all morph targets can be calculated by subtracting the value of this function with -1
from attributeCount() const.
MeshAttributeData Magnum:: Trade:: MeshData:: attributeData(UnsignedInt id) const
Raw attribute data.
Returns the raw data that are used as a base for all attribute*()
accessors. In most cases you don't want to access those directly, but rather use the attribute(), attributeName(), attributeFormat(), attributeOffset(), attributeStride() etc. accessors. This is also the reason why there's no overload taking a MeshAttribute, unlike the other accessors.
Useful mainly for passing particular attributes unchanged directly to MeshTools algorithms — unlike with attributeData() and releaseAttributeData(), returned instances are guaranteed to always have an absolute data pointer (i.e., MeshAttributeData::false
). The id
is expected to be smaller than attributeCount() const.
MeshAttribute Magnum:: Trade:: MeshData:: attributeName(UnsignedInt id) const
Attribute name.
The id
is expected to be smaller than attributeCount() const.
UnsignedInt Magnum:: Trade:: MeshData:: attributeId(UnsignedInt id) const new in Git master
Attribute ID in a set of attributes of the same name and morph target ID.
The id
is expected to be smaller than attributeCount() const. Returns the number of attributes of the same attributeName() and attributeMorphTargetId() preceeding id
, or 0
if it's the first attribute of given name and given morph target ID.
VertexFormat Magnum:: Trade:: MeshData:: attributeFormat(UnsignedInt id) const
Attribute format.
The id
is expected to be smaller than attributeCount() const. You can also use attributeFormat(MeshAttribute, UnsignedInt, Int) const to directly get a type of given named attribute.
std:: size_t Magnum:: Trade:: MeshData:: attributeOffset(UnsignedInt id) const
Attribute offset.
Byte offset of the first element of given attribute from the beginning of the vertexData() array, or a byte difference between pointers returned from vertexData() and a particular attribute(). The id
is expected to be smaller than attributeCount() const. You can also use attributeOffset(MeshAttribute, UnsignedInt, Int) const to directly get an offset of given named attribute.
Short Magnum:: Trade:: MeshData:: attributeStride(UnsignedInt id) const
Attribute stride.
Stride between consecutive elements of given attribute in the vertexData() array. In rare cases the stride may be zero or negative, such data layouts are however not commonly supported by GPU APIs. The id
is expected to be smaller than attributeCount() const. You can also use attributeStride(MeshAttribute, UnsignedInt, Int) const to directly get a stride of given named attribute.
UnsignedShort Magnum:: Trade:: MeshData:: attributeArraySize(UnsignedInt id) const
Attribute array size.
In case given attribute is an array (the equivalent of e.g. int[30]
), returns array size, otherwise returns 0
. The id
is expected to be smaller than attributeCount() const. You can also use attributeArraySize(MeshAttribute, UnsignedInt, Int) const to directly get array size of given named attribute.
Note that this is different from vertex count, which is exposed through vertexCount(), and is an orthogonal concept to having multiple attributes of the same name (for example two sets of texture coordinates), which is exposed through attributeCount(MeshAttribute, Int) const. See Custom mesh attributes for an example.
Int Magnum:: Trade:: MeshData:: attributeMorphTargetId(UnsignedInt id) const new in Git master
Attribute morph target ID.
In case given attribute is a morph target, returns its ID, otherwise returns -1
. The id
is expected to be smaller than attributeCount() const.
bool Magnum:: Trade:: MeshData:: hasAttribute(MeshAttribute name,
Int morphTargetId = -1) const
Whether the mesh has given attribute.
By default it checks only attributes that aren't morph targets, set morphTargetId
to check the attribute for given morph target ID.
UnsignedInt Magnum:: Trade:: MeshData:: attributeCount(MeshAttribute name,
Int morphTargetId = -1) const
Count of given named attribute.
Unlike attributeCount() const this returns count for given attribute name — for example a mesh can have more than one set of texture coordinates. By default it counts only attributes that aren't morph targets, set morphTargetId
to count attributes for given morph target ID.
Containers:: Optional<UnsignedInt> Magnum:: Trade:: MeshData:: findAttributeId(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const new in Git master
Find an absolute ID of a named attribute.
If name
isn't present or id
is not smaller than attributeCount(MeshAttribute, Int) const, returns Containers::
UnsignedInt Magnum:: Trade:: MeshData:: attributeId(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Absolute ID of a named attribute.
Like findAttributeId(), but the id
is expected to be smaller than attributeCount(MeshAttribute, Int) const.
VertexFormat Magnum:: Trade:: MeshData:: attributeFormat(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Format of a named attribute.
The id
is expected to be smaller than attributeCount(MeshAttribute, Int) const.
std:: size_t Magnum:: Trade:: MeshData:: attributeOffset(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Offset of a named attribute.
The id
is expected to be smaller than attributeCount(MeshAttribute, Int) const. See attributeOffset(UnsignedInt) const for more information.
Short Magnum:: Trade:: MeshData:: attributeStride(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Stride of a named attribute.
The id
is expected to be smaller than attributeCount(MeshAttribute, Int) const. See attributeStride(UnsignedInt) const for more information.
UnsignedShort Magnum:: Trade:: MeshData:: attributeArraySize(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Array size of a named attribute.
The id
is expected to be smaller than attributeCount(MeshAttribute, Int) const. Note that this is different from vertex count, and is an orthogonal concept to having multiple attributes of the same name — see attributeArraySize(UnsignedInt) const for more information.
Containers:: StridedArrayView2D<const char> Magnum:: Trade:: MeshData:: attribute(UnsignedInt id) const
Data for given attribute.
The id
is expected to be smaller than attributeCount() const. The second dimension represents the actual data type (its size is equal to format size for known VertexFormat values, possibly multiplied by array size, and to absolute attribute stride for implementation-specific values) and is guaranteed to be contiguous. In rare cases the first dimension stride may be zero or negative, such data layouts are however not commonly supported by GPU APIs.
Use the templated overload below to get the attribute in a concrete type. You can also use attribute(MeshAttribute, UnsignedInt, Int) const to directly get data for given named attribute.
Containers:: StridedArrayView2D<char> Magnum:: Trade:: MeshData:: mutableAttribute(UnsignedInt id)
Mutable data for given attribute.
Like attribute(UnsignedInt) const, but returns a mutable view. Expects that the mesh is mutable.
template<class T, class = typename std:: enable_if<!std:: is_array<T>::value>::type>
Containers:: StridedArrayView1D<const T> Magnum:: Trade:: MeshData:: attribute(UnsignedInt id) const
Data for given attribute in a concrete type.
The id
is expected to be smaller than attributeCount() const and T
is expected to correspond to attributeFormat(UnsignedInt) const. Expects that the vertex format is not implementation-specific, in that case you can only access the attribute via the typeless attribute(UnsignedInt) const above. The attribute is also expected to not be an array, in that case you need to use the overload below by using T[]
instead of T
. In rare cases the stride of the returned view may be zero or negative, such data layouts are however not commonly supported by GPU APIs. You can also use the non-templated positions2DAsArray(), positions3DAsArray(), tangentsAsArray(), bitangentSignsAsArray(), bitangentsAsArray(), normalsAsArray(), textureCoordinates2DAsArray(), colorsAsArray(), jointIdsAsArray(), weightsAsArray() and objectIdsAsArray() accessors to get common attributes converted to usual types in contiguous arrays, but note that these operations involve extra allocation and data conversion.
template<class T, class = typename std:: enable_if<std:: is_array<T>::value>::type>
Containers:: StridedArrayView2D<const typename std:: remove_extent<T>::type> Magnum:: Trade:: MeshData:: attribute(UnsignedInt id) const
Data for given array attribute in a concrete type.
Same as above, except that it works with array attributes as well — you're expected to select this overload by passing T[]
instead of T
. The second dimension is guaranteed to be contiguous and have the same size as reported by attributeArraySize() for given attribute. For non-array attributes the second dimension has a size of 1
.
template<class T, class = typename std:: enable_if<!std:: is_array<T>::value>::type>
Containers:: StridedArrayView1D<T> Magnum:: Trade:: MeshData:: mutableAttribute(UnsignedInt id)
Mutable data for given attribute in a concrete type.
Like attribute(UnsignedInt) const, but returns a mutable view. Expects that the mesh is mutable.
template<class T, class = typename std:: enable_if<std:: is_array<T>::value>::type>
Containers:: StridedArrayView2D<typename std:: remove_extent<T>::type> Magnum:: Trade:: MeshData:: mutableAttribute(UnsignedInt id)
Mutable data for given array attribute in a concrete type.
Same as above, except that it works with array attributes as well — you're expected to select this overload by passing T[]
instead of T
. The second dimension is guaranteed to be contiguous and have the same size as reported by attributeArraySize() for given attribute. For non-array attributes the second dimension has a size of 1
.
Containers:: StridedArrayView2D<const char> Magnum:: Trade:: MeshData:: attribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Data for given named attribute.
The id
is expected to be smaller than attributeCount(MeshAttribute, Int) const. See attribute(UnsignedInt) const for more information. Use the templated overload below to get the attribute in a concrete type.
Containers:: StridedArrayView2D<char> Magnum:: Trade:: MeshData:: mutableAttribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1)
Mutable data for given named attribute.
Like attribute(MeshAttribute, UnsignedInt, Int) const, but returns a mutable view. Expects that the mesh is mutable.
template<class T, class = typename std:: enable_if<!std:: is_array<T>::value>::type>
Containers:: StridedArrayView1D<const T> Magnum:: Trade:: MeshData:: attribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Data for given named attribute in a concrete type.
The id
is expected to be smaller than attributeCount(MeshAttribute, Int) const and T
is expected to correspond to attributeFormat(MeshAttribute, UnsignedInt, Int) const. Expects that the vertex format is not implementation-specific, in that case you can only access the attribute via the typeless attribute(MeshAttribute, UnsignedInt, Int) const above. The attribute is also expected to not be an array, in that case you need to use the overload below by using T[]
instead of T
. In rare cases the stride of the returned view may be zero or negative, such data layouts are however not commonly supported by GPU APIs. You can also use the non-templated positions2DAsArray(), positions3DAsArray(), tangentsAsArray(), bitangentSignsAsArray(), bitangentsAsArray(), normalsAsArray(), textureCoordinates2DAsArray(), colorsAsArray(), jointIdsAsArray(), weightsAsArray() and objectIdsAsArray() accessors to get common attributes converted to usual types in contiguous arrays, but note that these operations involve extra data conversion and an allocation.
template<class T, class = typename std:: enable_if<std:: is_array<T>::value>::type>
Containers:: StridedArrayView2D<const typename std:: remove_extent<T>::type> Magnum:: Trade:: MeshData:: attribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Data for given named array attribute in a concrete type.
Same as above, except that it works with array attributes as well — you're expected to select this overload by passing T[]
instead of T
. The second dimension is guaranteed to be contiguous and have the same size as reported by attributeArraySize() for given attribute. For non-array attributes the second dimension has a size of 1
.
template<class T, class = typename std:: enable_if<!std:: is_array<T>::value>::type>
Containers:: StridedArrayView1D<T> Magnum:: Trade:: MeshData:: mutableAttribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1)
Mutable data for given named attribute in a concrete type.
Like attribute(MeshAttribute, UnsignedInt, Int) const, but returns a mutable view. Expects that the mesh is mutable.
template<class T, class = typename std:: enable_if<std:: is_array<T>::value>::type>
Containers:: StridedArrayView2D<typename std:: remove_extent<T>::type> Magnum:: Trade:: MeshData:: mutableAttribute(MeshAttribute name,
UnsignedInt id = 0,
Int morphTargetId = -1)
Mutable data for given named array attribute in a concrete type.
Same as above, except that it works with array attributes as well — you're expected to select this overload by passing T[]
instead of T
. The second dimension is guaranteed to be contiguous and have the same size as reported by attributeArraySize() for given attribute. For non-array attributes the second dimension has a size of 1
.
Containers:: Array<UnsignedInt> Magnum:: Trade:: MeshData:: indicesAsArray() const
Indices as 32-bit integers.
Convenience alternative to the templated indices(). Converts the index array from an arbitrary underlying type and returns it in a newly-allocated array.
void Magnum:: Trade:: MeshData:: indicesInto(const Containers:: StridedArrayView1D<UnsignedInt>& destination) const
Indices as 32-bit integers into a pre-allocated view.
Like indicesAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<Vector2> Magnum:: Trade:: MeshData:: positions2DAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Positions as 2D float vectors.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
void Magnum:: Trade:: MeshData:: positions2DInto(const Containers:: StridedArrayView1D<Vector2>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Positions as 2D float vectors into a pre-allocated view.
Like positions2DAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<Vector3> Magnum:: Trade:: MeshData:: positions3DAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Positions as 3D float vectors.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::0.0f
. Expects that the vertex format is not implementation-specific, in that case you can only access the attribute via the typeless attribute(MeshAttribute, UnsignedInt, Int) const.
void Magnum:: Trade:: MeshData:: positions3DInto(const Containers:: StridedArrayView1D<Vector3>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Positions as 3D float vectors into a pre-allocated view.
Like positions3DAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<Vector3> Magnum:: Trade:: MeshData:: tangentsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Tangents as 3D float vectors.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
If the tangents contain a fourth component with bitangent direction, it's ignored here — use bitangentSignsAsArray() to get those instead. You can also use tangentsInto() together with bitangentSignsInto() to put them both in a single array.
void Magnum:: Trade:: MeshData:: tangentsInto(const Containers:: StridedArrayView1D<Vector3>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Tangents as 3D float vectors into a pre-allocated view.
Like tangentsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data. Use bitangentSignsInto() to extract the fourth component wit bitangent direction, if present.
Containers:: Array<Float> Magnum:: Trade:: MeshData:: bitangentSignsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Bitangent signs as floats.
Counterpart to tangentsAsArray() returning value of the fourth component. Expects that the type of MeshAttribute::
void Magnum:: Trade:: MeshData:: bitangentSignsInto(const Containers:: StridedArrayView1D<Float>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Bitangent signs as floats into a pre-allocated view.
Like bitangentsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<Vector3> Magnum:: Trade:: MeshData:: bitangentsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Bitangents as 3D float vectors.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
Note that in some cases the bitangents aren't provided directly but calculated from normals and four-component tangents. In that case you'll need to get bitangent signs via bitangentSignsAsArray() and calculate the bitangents as shown in the documentation of MeshAttribute::
void Magnum:: Trade:: MeshData:: bitangentsInto(const Containers:: StridedArrayView1D<Vector3>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Bitangents as 3D float vectors into a pre-allocated view.
Like bitangentsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<Vector3> Magnum:: Trade:: MeshData:: normalsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Normals as 3D float vectors.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
void Magnum:: Trade:: MeshData:: normalsInto(const Containers:: StridedArrayView1D<Vector3>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Normals as 3D float vectors into a pre-allocated view.
Like normalsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<Vector2> Magnum:: Trade:: MeshData:: textureCoordinates2DAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Texture coordinates as 2D float vectors.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
void Magnum:: Trade:: MeshData:: textureCoordinates2DInto(const Containers:: StridedArrayView1D<Vector2>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Texture coordinates as 2D float vectors into a pre-allocated view.
Like textureCoordinates2DAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<Color4> Magnum:: Trade:: MeshData:: colorsAsArray(UnsignedInt id = 0,
Int morphTargetId = -1) const
Colors as RGBA floats.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::1.0f
. Expects that the vertex format is not implementation-specific, in that case you can only access the attribute via the typeless attribute(MeshAttribute, UnsignedInt, Int) const.
void Magnum:: Trade:: MeshData:: colorsInto(const Containers:: StridedArrayView1D<Color4>& destination,
UnsignedInt id = 0,
Int morphTargetId = -1) const
Colors as RGBA floats into a pre-allocated view.
Like colorsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<UnsignedInt> Magnum:: Trade:: MeshData:: jointIdsAsArray(UnsignedInt id = 0) const new in Git master
Skin joint IDs as unsigned int arrays.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
As it's an array attribute, the returned array has vertexCount() times attributeArraySize(MeshAttribute, UnsignedInt, Int) const elements. You can make a 2D view onto the result to conveniently index the data:
Trade::MeshData data = …; Containers::Array<UnsignedInt> array = data.jointIdsAsArray(); Containers::StridedArrayView2D<UnsignedInt> array2D{array, {data.vertexCount(), data.attributeArraySize(Trade::MeshAttribute::JointIds)}}; for(Containers::StridedArrayView1D<UnsignedInt> i: array2D) { for(UnsignedInt j: i) { // do something with joint ID j in vertex i } }
void Magnum:: Trade:: MeshData:: jointIdsInto(const Containers:: StridedArrayView2D<UnsignedInt>& destination,
UnsignedInt id = 0) const new in Git master
Skin joint IDs as unsigned int arrays into a pre-allocated view.
Like jointIdsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data — first dimension being vertexCount() and second attributeArraySize(MeshAttribute. UnsignedInt) const. The second dimension is additionally expected to be contiguous.
Containers:: Array<Float> Magnum:: Trade:: MeshData:: weightsAsArray(UnsignedInt id = 0) const new in Git master
Skin weights as float arrays.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
As it's an array attribute, the returned array has vertexCount() times attributeArraySize(MeshAttribute, UnsignedInt, Int) const elements. You can make a 2D view onto the result to conveniently index the data, see jointIdsAsArray() for an example snippet.
void Magnum:: Trade:: MeshData:: weightsInto(const Containers:: StridedArrayView2D<Float>& weightsDestination,
UnsignedInt id = 0) const new in Git master
Skin weights as float arrays into a pre-allocated view.
Like weightsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data — first dimension being vertexCount() and second attributeArraySize(MeshAttribute. UnsignedInt) const. The second dimension is additionally expected to be contiguous.
Containers:: Array<UnsignedInt> Magnum:: Trade:: MeshData:: objectIdsAsArray(UnsignedInt id = 0) const
Object IDs as 32-bit integers.
Convenience alternative to attribute(MeshAttribute, UnsignedInt, Int) const with MeshAttribute::
void Magnum:: Trade:: MeshData:: objectIdsInto(const Containers:: StridedArrayView1D<UnsignedInt>& destination,
UnsignedInt id = 0) const
Object IDs as 32-bit integers into a pre-allocated view.
Like objectIdsAsArray(), but puts the result into destination
instead of allocating a new array. Expects that destination
is sized to contain exactly all data.
Containers:: Array<char> Magnum:: Trade:: MeshData:: releaseIndexData()
Release index data storage.
Releases the ownership of the index data array and resets internal index-related state to default. The mesh then behaves like it has zero indices (but it can still have a non-zero vertex count), however indexData() still return a zero-sized non-null array so index offset calculation continues to work as expected.
Note that the returned array has a custom no-op deleter when the data are not owned by the mesh, and while the returned array type is mutable, the actual memory might be not.
Containers:: Array<MeshAttributeData> Magnum:: Trade:: MeshData:: releaseAttributeData()
Release attribute data storage.
Releases the ownership of the attribute data array and resets internal attribute-related state to default. The mesh then behaves like if it has no attributes (but it can still have a non-zero vertex count). Note that the returned array has a custom no-op deleter when the data are not owned by the mesh, and while the returned array type is mutable, the actual memory might be not. Additionally, the returned MeshAttributeData instances may have different data pointers and sizes than what's returned by the attribute() and attributeData(UnsignedInt) const accessors as some of them might be offset-only — use this function only if you really know what are you doing.
Containers:: Array<char> Magnum:: Trade:: MeshData:: releaseVertexData()
Release vertex data storage.
Releases the ownership of the vertex data array and resets internal attribute-related state to default. The mesh then behaves like it has zero vertices (but it can still have a non-zero amount of attributes), however vertexData() will still return a zero- sized non-null array so attribute offset calculation continues to work as expected.
Note that the returned array has a custom no-op deleter when the data are not owned by the mesh, and while the returned array type is mutable, the actual memory might be not.
const void* Magnum:: Trade:: MeshData:: importerState() const
Importer-specific state.
See AbstractImporter::