Browse Source

Trade: improve MeshData, SceneData and MaterialData population docs.

Especially the part about non-owned data was lacking, with basically no
information about what are offset-only attributes and fields actually
good for.
pull/620/head
Vladimír Vondruš 3 years ago
parent
commit
041b1aa654
  1. 164
      doc/snippets/MagnumTrade.cpp
  2. 13
      src/Magnum/Trade/MaterialData.h
  3. 93
      src/Magnum/Trade/MeshData.h
  4. 70
      src/Magnum/Trade/SceneData.h

164
doc/snippets/MagnumTrade.cpp

@ -758,24 +758,20 @@ Trade::MeshAttributeData data{Trade::MeshAttribute::Position, positions};
}
{
UnsignedInt vertexCount{};
/* [MeshAttributeData-usage-offset-only] */
struct Vertex {
Vector3 position;
Vector4 color;
};
/* Layout defined statically, 15 vertices in total */
constexpr Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
VertexFormat::Vector3, offsetof(Vertex, position), 15, sizeof(Vertex)};
constexpr Trade::MeshAttributeData colors{Trade::MeshAttribute::Color,
VertexFormat::Vector4, offsetof(Vertex, color), 15, sizeof(Vertex)};
/* Actual data populated later */
Containers::Array<char> vertexData{15*sizeof(Vertex)};
DOXYGEN_ELLIPSIS()
Trade::MeshData{MeshPrimitive::Triangles, std::move(vertexData),
{positions, colors}};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
VertexFormat::Vector3, offsetof(Vertex, position), vertexCount, sizeof(Vertex)};
Trade::MeshAttributeData colors{Trade::MeshAttribute::Color,
VertexFormat::Vector4, offsetof(Vertex, color), vertexCount, sizeof(Vertex)};
/* [MeshAttributeData-usage-offset-only] */
static_cast<void>(positions);
static_cast<void>(colors);
}
#ifdef MAGNUM_TARGET_VK
@ -895,18 +891,18 @@ struct Vertex {
Containers::Array<char> indexData{indexCount*sizeof(UnsignedShort)};
Containers::Array<char> vertexData{vertexCount*sizeof(Vertex)};
DOXYGEN_ELLIPSIS()
auto vertices = Containers::arrayCast<const Vertex>(vertexData);
auto indices = Containers::arrayCast<const UnsignedShort>(indexData);
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,
Containers::StridedArrayView1D<const Vector3>{vertices,
&vertices[0].position, vertexCount, sizeof(Vertex)}},
vertices.slice(&Vertex::position)},
Trade::MeshAttributeData{Trade::MeshAttribute::Color,
Containers::StridedArrayView1D<const Vector4>{vertices,
&vertices[0].color, vertexCount, sizeof(Vertex)}}
vertices.slice(&Vertex::color)}
}};
/* [MeshData-populating] */
}
@ -917,29 +913,51 @@ struct Vertex {
Vector4 color;
};
/* [MeshData-populating-non-owned] */
const UnsignedShort indices[] {
0, 1, 2,
2, 1, 3,
3, 4, 5,
5, 4, 6
const UnsignedShort indices[]{
DOXYGEN_ELLIPSIS(0)
};
Vertex vertices[]{
DOXYGEN_ELLIPSIS({})
};
Vertex vertices[7];
Trade::MeshData data{MeshPrimitive::Triangles,
Trade::DataFlags{}, indices, Trade::MeshIndexData{indices},
Trade::DataFlag::Mutable, vertices, {
Trade::MeshAttributeData{Trade::MeshAttribute::Position,
Containers::StridedArrayView1D<const Vector3>{
Containers::arrayView(vertices), &vertices[0].position,
Containers::arraySize(vertices), sizeof(Vertex)}},
Containers::stridedArrayView(vertices).slice(&Vertex::position)},
Trade::MeshAttributeData{Trade::MeshAttribute::Color,
Containers::StridedArrayView1D<const Vector4>{
Containers::arrayView(vertices), &vertices[0].color,
Containers::arraySize(vertices), sizeof(Vertex)}}
Containers::stridedArrayView(vertices).slice(&Vertex::color)}
}};
/* [MeshData-populating-non-owned] */
}
{
UnsignedInt vertexCount{};
/* [MeshData-populating-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)};
DOXYGEN_ELLIPSIS()
/* Using the statically defined attribute layout together with explicitly
passed vertex count */
Trade::MeshData mesh{MeshPrimitive::Triangles, std::move(vertexData),
Trade::meshAttributeDataNonOwningArray(attributes), vertexCount};
/* [MeshData-populating-offset-only] */
}
{
/* [MeshData-populating-custom] */
/* Each face can consist of 15 triangles at most, triangleCount says how many
@ -1060,27 +1078,23 @@ Trade::SceneFieldData field{Trade::SceneField::Transformation,
}
{
std::size_t objectCount = 120;
/* [SceneFieldData-usage-offset-only] */
struct Node {
UnsignedInt object;
UnsignedInt mapping;
Int parent;
Matrix4 transform;
Matrix4 transformation;
};
/* Layout defined statically, 120 objects in total */
constexpr Trade::SceneFieldData parents{Trade::SceneField::Parent, 120,
Trade::SceneMappingType::UnsignedInt, offsetof(Node, object), sizeof(Node),
Trade::SceneFieldData parents{Trade::SceneField::Parent, objectCount,
Trade::SceneMappingType::UnsignedInt, offsetof(Node, mapping), sizeof(Node),
Trade::SceneFieldType::Int, offsetof(Node, parent), sizeof(Node)};
constexpr Trade::SceneFieldData transforms{Trade::SceneField::Transformation, 120,
Trade::SceneMappingType::UnsignedInt, offsetof(Node, object), sizeof(Node),
Trade::SceneFieldType::Matrix4x4, offsetof(Node, transform), sizeof(Node)};
/* Actual data populated later */
Containers::Array<char> data{120*sizeof(Node)};
DOXYGEN_ELLIPSIS()
Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 120, std::move(data),
{parents, transforms}};
Trade::SceneFieldData transformations{Trade::SceneField::Transformation, objectCount,
Trade::SceneMappingType::UnsignedInt, offsetof(Node, mapping), sizeof(Node),
Trade::SceneFieldType::Matrix4x4, offsetof(Node, transformation), sizeof(Node)};
/* [SceneFieldData-usage-offset-only] */
static_cast<void>(parents);
static_cast<void>(transformations);
}
{
@ -1197,7 +1211,7 @@ for(std::size_t i = 0; i != transformationMapping.size(); ++i) {
const std::size_t nodeCount{}, meshAssignmentCount{};
/* [SceneData-populating] */
struct Common {
UnsignedShort object;
UnsignedShort mapping;
Short parent;
Matrix4 transformation;
};
@ -1219,17 +1233,71 @@ Trade::SceneData scene{
Trade::SceneMappingType::UnsignedShort, nodeCount,
std::move(data), {
Trade::SceneFieldData{Trade::SceneField::Parent,
common.slice(&Common::object), common.slice(&Common::parent)},
common.slice(&Common::mapping),
common.slice(&Common::parent)},
Trade::SceneFieldData{Trade::SceneField::Transformation,
common.slice(&Common::object), common.slice(&Common::transformation)},
common.slice(&Common::mapping), common.slice(&Common::transformation)},
Trade::SceneFieldData{Trade::SceneField::Mesh,
meshMaterialMapping, meshes},
meshMaterialMapping,
meshes},
Trade::SceneFieldData{Trade::SceneField::MeshMaterial,
meshMaterialMapping, meshMaterials}
meshMaterialMapping,
meshMaterials}
}};
/* [SceneData-populating] */
}
{
constexpr std::size_t objectCount = 1;
/* [SceneData-populating-non-owned] */
constexpr struct Data {
UnsignedShort mapping;
Short parent;
Matrix4 transformation;
} data[objectCount]{
DOXYGEN_ELLIPSIS({})
};
Trade::SceneData scene{
Trade::SceneMappingType::UnsignedShort, objectCount,
Trade::DataFlag::Global, data, {
Trade::SceneFieldData{Trade::SceneField::Parent,
Containers::stridedArrayView(data).slice(&Data::mapping),
Containers::stridedArrayView(data).slice(&Data::parent)},
DOXYGEN_ELLIPSIS()
}};
/* [SceneData-populating-non-owned] */
}
{
constexpr std::size_t objectCount = 1;
/* [SceneData-populating-offset-only] */
struct Data {
UnsignedInt mapping;
Int parent;
Matrix4 transformation;
};
/* Layout defined statically */
constexpr Trade::SceneFieldData fields[]{
Trade::SceneFieldData{Trade::SceneField::Parent, objectCount,
Trade::SceneMappingType::UnsignedInt, offsetof(Data, mapping), sizeof(Data),
Trade::SceneFieldType::Int, offsetof(Data, parent), sizeof(Data)},
Trade::SceneFieldData{Trade::SceneField::Transformation, objectCount,
Trade::SceneMappingType::UnsignedInt, offsetof(Data, mapping), sizeof(Data),
Trade::SceneFieldType::Matrix4x4, offsetof(Data, transformation), sizeof(Data)}
};
/* Actual data populated later */
Containers::Array<char> data{objectCount*sizeof(Data)};
DOXYGEN_ELLIPSIS()
/* Using the statically defined field layout */
Trade::SceneData scene{Trade::SceneMappingType::UnsignedInt, objectCount,
std::move(data), Trade::sceneFieldDataNonOwningArray(fields)};
/* [SceneData-populating-offset-only] */
}
{
std::size_t nodeCount{};
/* [SceneData-populating-custom1] */

13
src/Magnum/Trade/MaterialData.h

@ -1919,11 +1919,14 @@ internally sorted by name to allow a @f$ \mathcal{O}(\log n) @f$ lookup.
@snippet MagnumTrade.cpp MaterialData-populating
In addition to passing ownership of an array it's also possible to have the
@ref MaterialData instance refer to external data (for example in a
memory-mapped file, constant memory etc.). Instead of moving in an
@relativeref{Corrade,Containers::Array} you pass @ref DataFlags describing if
the data is mutable or not together with an
@subsection Trade-MaterialData-populating-non-owned Non-owned instances
In some cases you may want the @ref MaterialData 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 an
@relativeref{Corrade,Containers::Array} of @ref MaterialAttributeData or
allocating it implicitly from an initializer list in the constructor, pass
@ref DataFlags describing data mutability and ownership together with an
@relativeref{Corrade,Containers::ArrayView}. Note that in this case, since the
attribute data is treated as immutable, you *have to* ensure the list is
already sorted by name.

93
src/Magnum/Trade/MeshData.h

@ -387,8 +387,9 @@ class MAGNUM_TRADE_EXPORT MeshIndexData {
@brief Mesh attribute data
@m_since{2020,06}
Convenience type for populating @ref MeshData, see its documentation for an
introduction. Additionally usable in various @ref MeshTools algorithms such as
Convenience type for populating @ref MeshData, see
@ref Trade-MeshData-populating "its documentation" for an introduction.
Additionally usable in various @ref MeshTools algorithms such as
@ref MeshTools::duplicate(const Trade::MeshData& data, Containers::ArrayView<const Trade::MeshAttributeData>)
or @ref MeshTools::interleave(const Trade::MeshData& data, Containers::ArrayView<const Trade::MeshAttributeData>, InterleaveFlags).
@ -406,19 +407,21 @@ supply @ref VertexFormat explicitly.
@subsection Trade-MeshAttributeData-usage-offset-only Offset-only attribute data
If the actual attribute data location is not known yet, the instance can be
created as "offset-only", meaning the actual view gets created only later when
passed to a @ref MeshData instance with a concrete vertex data array. This is
useful mainly to avoid pointer patching during data serialization, but also for
example when vertex layout is static (and thus can be defined at compile time),
but the actual data is allocated / populated at runtime:
created as "offset-only" using @ref MeshAttributeData(MeshAttribute, VertexFormat, std::size_t, UnsignedInt, std::ptrdiff_t, UnsignedShort),
meaning the actual view gets created only later when passed to a @ref MeshData
instance with a concrete vertex data array. This is useful mainly to avoid
pointer patching during data serialization, but also for example when vertex
layout is static (and thus can be defined at compile time), but the actual data
is allocated / populated at runtime.
@snippet MagnumTrade.cpp MeshAttributeData-usage-offset-only
Offset-only attributes return @cpp true @ce for @ref isOffsetOnly(). Note that
@ref MeshTools algorithms generally don't accept offset-only
@ref MeshAttributeData instances except when passed through a @ref MeshData, as
for a standalone offset-only @ref MeshAttributeData it's impossible to know
what data it points to.
See @ref Trade-MeshData-populating-non-owned "the corresponding MeshData documentation"
for a complete usage example. Offset-only attributes return @cpp true @ce for
@ref isOffsetOnly(). Note that @ref MeshTools algorithms generally don't accept
offset-only @ref MeshAttributeData instances except when passed through a
@ref MeshData, as for a standalone offset-only @ref MeshAttributeData it's
impossible to know what data it points to.
@section Trade-MeshAttributeData-custom-vertex-format Custom vertex formats
@ -696,7 +699,9 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData {
Useful when you have the attribute definitions statically defined (for example
when the vertex data themselves are already defined at compile time) and don't
want to allocate just to pass those to @ref MeshData.
want to allocate just to pass those to @ref MeshData. See documentation about
@ref Trade-MeshData-populating "populating a MeshData instance" for more
information.
*/
Containers::Array<MeshAttributeData> MAGNUM_TRADE_EXPORT meshAttributeDataNonOwningArray(Containers::ArrayView<const MeshAttributeData> view);
@ -706,8 +711,8 @@ Containers::Array<MeshAttributeData> MAGNUM_TRADE_EXPORT meshAttributeDataNonOwn
Provides access to mesh vertex and index data, together with additional
information such as primitive type. Populated instances of this class are
returned from @ref AbstractImporter::mesh() and from particular functions in
the @ref Primitives library.
returned from @ref AbstractImporter::mesh(), from particular functions in
the @ref Primitives library as well as from various @ref MeshTools algorithms.
@section Trade-MeshData-usage-compile Quick usage with MeshTools::compile()
@ -837,15 +842,32 @@ neither are possible too:
@snippet MagnumTrade.cpp MeshData-populating
In cases where you want the @ref MeshData instance to only refer to external
data without taking ownership (for example in a memory-mapped file, constant
memory etc.). Instead of moving in an @relativeref{Corrade,Containers::Array}
you pass @ref DataFlags describing if the data is mutable or not together with
an @relativeref{Corrade,Containers::ArrayView}. A variant of the above where
the index data is constant and vertex data mutable, both referenced externally:
@subsection Trade-MeshData-populating-non-owned Non-owned instances and static vertex layouts
In some cases you may want the @ref 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
@relativeref{Corrade,Containers::Array} instances, pass @ref DataFlags
describing data mutability and ownership together with
@relativeref{Corrade,Containers::ArrayView} instances to the
@ref MeshData(MeshPrimitive, DataFlags, Containers::ArrayView<const void>, const MeshIndexData&, DataFlags, Containers::ArrayView<const void>, Containers::Array<MeshAttributeData>&&, UnsignedInt, const void*)
constructor. The following snippet is a variant of the above where the index
data is constant and vertex data mutable, both referenced externally:
@snippet MagnumTrade.cpp MeshData-populating-non-owned
There are also other constructor overloads allowing you to mix and match owned
vertex data with non-owned index data and vice versa. The @ref MeshAttributeData
list is still implicitly allocated in the above case, but it can also be
defined externally and referenced via @ref meshAttributeDataNonOwningArray()
instead if desired. Finally, if the vertex layout is constant but the actual
data is allocated / populated at runtime, the @ref MeshAttributeData instances
can be defined in a global array as offset-only:
@snippet MagnumTrade.cpp MeshData-populating-offset-only
See also the @ref Trade-MeshAttributeData-usage-offset-only "corresponding MeshAttributeData documentation for offset-only fields".
@subsection Trade-MeshData-populating-custom Custom mesh attributes
To allow for greater flexibility, a @ref MeshData instance can describe not
@ -870,7 +892,6 @@ you can also supply implementation-specific values that are not available in
the generic @relativeref{Magnum,MeshPrimitive} enum, similarly see also
@ref Trade-MeshAttributeData-custom-vertex-format for details on
implementation-specific @ref VertexFormat values.
@see @ref AbstractImporter::mesh()
*/
class MAGNUM_TRADE_EXPORT MeshData {
public:
@ -896,14 +917,20 @@ class MAGNUM_TRADE_EXPORT MeshData {
* @param importerState Importer-specific state
*
* The @p indices are expected to point to a sub-range of @p indexData.
* For a non-indexed mesh either pass default-constructed
* @ref indexData and @p indices arguments, or use the
* @ref MeshData(MeshPrimitive, Containers::Array<char>&&, Containers::Array<MeshAttributeData>&&, UnsignedInt, const void*)
* constructor.
*
* The @p attributes are expected to reference (sparse) sub-ranges of
* @p vertexData. Particular attributes can have additional
* restrictions, see documentation of @ref MeshAttribute values for
* more information. If the mesh has no attributes, the @p indices are
* expected to be valid (but can be empty). If you want to create an
* attribute-less non-indexed mesh, use
* @ref MeshData(MeshPrimitive, UnsignedInt, const void*) to specify
* desired vertex count.
* expected to be valid (but can be empty), you can also use the
* @ref MeshData(MeshPrimitive, Containers::Array<char>&&, const MeshIndexData&, UnsignedInt, const void*)
* constructor in that case. If you want to create an attribute-less
* non-indexed mesh, use @ref MeshData(MeshPrimitive, UnsignedInt, const void*)
* instead.
*
* The @ref indexDataFlags() / @ref vertexDataFlags() are implicitly
* set to a combination of @ref DataFlag::Owned and
@ -937,6 +964,15 @@ class MAGNUM_TRADE_EXPORT MeshData {
* data. The @p indexDataFlags / @p vertexDataFlags parameters can
* contain @ref DataFlag::Mutable to indicate the external data can be
* modified, and are expected to *not* have @ref DataFlag::Owned set.
*
* Use @ref MeshData(MeshPrimitive, DataFlags, Containers::ArrayView<const void>, const MeshIndexData&, Containers::Array<char>&&, Containers::Array<MeshAttributeData>&&, UnsignedInt, const void*)
* to create a mesh with only index data non-owned and
* @ref MeshData(MeshPrimitive, Containers::Array<char>&&, const MeshIndexData&, DataFlags, Containers::ArrayView<const void>, Containers::Array<MeshAttributeData>&&, UnsignedInt, const void*)
* to create a mesh with only vertex data non-owned. There's also a
* @ref MeshData(MeshPrimitive, DataFlags, Containers::ArrayView<const void>, Containers::Array<MeshAttributeData>&&, UnsignedInt, const void*)
* convenience overload for non-indexed meshes with non-owned vertex
* data and @ref MeshData(MeshPrimitive, DataFlags, Containers::ArrayView<const void>, const MeshIndexData&, UnsignedInt, const void*)
* for attribute-less meshes with non-owned index data.
*/
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) noexcept;
@ -965,6 +1001,7 @@ class MAGNUM_TRADE_EXPORT MeshData {
* have @ref DataFlag::Owned set. The @ref vertexDataFlags() are
* implicitly set to a combination of @ref DataFlag::Owned and
* @ref DataFlag::Mutable.
* @see @ref MeshData(MeshPrimitive, DataFlags, Containers::ArrayView<const void>, const MeshIndexData&, DataFlags, Containers::ArrayView<const void>, Containers::Array<MeshAttributeData>&&, UnsignedInt, const void*)
*/
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) noexcept;
@ -993,6 +1030,7 @@ class MAGNUM_TRADE_EXPORT MeshData {
* have @ref DataFlag::Owned set. The @ref indexDataFlags() are
* implicitly set to a combination of @ref DataFlag::Owned and
* @ref DataFlag::Mutable.
* @see @ref MeshData(MeshPrimitive, DataFlags, Containers::ArrayView<const void>, const MeshIndexData&, DataFlags, Containers::ArrayView<const void>, Containers::Array<MeshAttributeData>&&, UnsignedInt, const void*)
*/
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) noexcept;
@ -1068,8 +1106,7 @@ class MAGNUM_TRADE_EXPORT MeshData {
* with default-constructed @p vertexData and @p attributes arguments.
* The @p indices are expected to be valid (but can be empty). If you
* want to create an attribute-less non-indexed mesh, use
* @ref MeshData(MeshPrimitive, UnsignedInt, const void*) to specify
* desired vertex count.
* @ref MeshData(MeshPrimitive, UnsignedInt, const void*) instead.
*
* The @ref indexDataFlags() are implicitly set to a combination of
* @ref DataFlag::Owned and @ref DataFlag::Mutable. For consistency,

70
src/Magnum/Trade/SceneData.h

@ -817,20 +817,22 @@ Alternatively, you can pass typeless @cpp const void @ce or 2D views and supply
@subsection Trade-SceneFieldData-usage-offset-only Offset-only field data
If the actual field / object data location is not known yet, the instance can
be created as "offset-only", meaning the actual view gets created only later
when passed to a @ref SceneData instance with a concrete data array. This is
useful mainly to avoid pointer patching during data serialization, less so when
the data layout is static (and thus can be defined at compile time), but the
actual data is allocated / populated at runtime:
If the actual field / mapping data location is not known yet, the instance can
be created as "offset-only" using @ref SceneFieldData(SceneField, std::size_t, SceneMappingType, std::size_t, std::ptrdiff_t, SceneFieldType, std::size_t, std::ptrdiff_t, UnsignedShort, SceneFieldFlags)
and related constructor overloads, meaning the actual views get created only
later when passed to a @ref SceneData instance with a concrete data array. This
is useful mainly to avoid pointer patching during data serialization, but also
for example when the data layout is static (and thus can be defined at compile
time), but the actual data is allocated / populated at runtime.
@snippet MagnumTrade.cpp SceneFieldData-usage-offset-only
Offset-only fields are marked with @ref SceneFieldFlag::OffsetOnly in
@ref flags(). Note that @ref SceneTools algorithms generally don't accept
offset-only @ref SceneFieldData instances except when passed through a
@ref SceneData, as for a standalone offset-only @ref SceneFieldData it's
impossible to know what data it points to.
See @ref Trade-SceneData-populating-non-owned "the corresponding SceneData documentation"
for a complete usage example. Offset-only fields are marked with
@ref SceneFieldFlag::OffsetOnly in @ref flags(). Note that @ref SceneTools
algorithms generally don't accept offset-only @ref SceneFieldData instances
except when passed through a @ref SceneData, as for a standalone offset-only
@ref SceneFieldData it's impossible to know what data it points to.
@subsection Trade-SceneFieldData-usage-object-mapping Ordered and implicit object mapping
@ -1196,8 +1198,7 @@ class MAGNUM_TRADE_EXPORT SceneFieldData {
* @param mappingType Object mapping type
* @param mappingOffset Object mapping data offset
* @param mappingStride Object mapping data stride
* @param fieldType Field type. @ref SceneFieldType::Bit and
* `SceneFieldType::String*` values are not allowed here.
* @param fieldType Field type
* @param fieldOffset Field data offset
* @param fieldStride Field data stride
* @param fieldArraySize Field array size. Use @cpp 0 @ce for
@ -1217,6 +1218,13 @@ class MAGNUM_TRADE_EXPORT SceneFieldData {
* @p fieldType / @p fieldArraySize checks against @p fieldStride can
* be done. You're encouraged to use the @ref SceneFieldData(SceneField, SceneMappingType, const Containers::StridedArrayView1D<const void>&, SceneFieldType, const Containers::StridedArrayView1D<const void>&, UnsignedShort, SceneFieldFlags)
* constructor if you want additional safeguards.
*
* @ref SceneFieldType::Bit and `SceneFieldType::String*` values are
* not allowed in @p fieldType. For offset-only bit fields use the
* @ref SceneFieldData(SceneField, std::size_t, SceneMappingType, std::size_t, std::ptrdiff_t, std::size_t, std::size_t, std::ptrdiff_t, UnsignedShort, SceneFieldFlags)
* constructor instead, for offset-only string fields use
* @ref SceneFieldData(SceneField, std::size_t, SceneMappingType, std::size_t, std::ptrdiff_t, std::size_t, SceneFieldType, std::size_t, std::ptrdiff_t, SceneFieldFlags)
* instead.
* @see @ref flags(), @ref fieldArraySize() const,
* @ref mappingData(Containers::ArrayView<const void>) const,
* @ref fieldData(Containers::ArrayView<const void>) const
@ -1257,7 +1265,8 @@ class MAGNUM_TRADE_EXPORT SceneFieldData {
* You're encouraged to use the @ref SceneFieldData(SceneField, SceneMappingType, const Containers::StridedArrayView1D<const void>&, const Containers::StridedBitArrayView1D&, SceneFieldFlags)
* or @ref SceneFieldData(SceneField, SceneMappingType, const Containers::StridedArrayView1D<const void>&, const Containers::StridedBitArrayView2D&, SceneFieldFlags)
* constructors if you want additional safeguards.
* @see @ref flags(),
* @see @ref SceneFieldData(SceneField, std::size_t, SceneMappingType, std::size_t, std::ptrdiff_t, SceneFieldType, std::size_t, std::ptrdiff_t, UnsignedShort, SceneFieldFlags),
* @ref flags(),
* @ref mappingData(Containers::ArrayView<const void>) const,
* @ref fieldData(Containers::ArrayView<const void>) const
*/
@ -1299,7 +1308,8 @@ class MAGNUM_TRADE_EXPORT SceneFieldData {
* @p fieldType checks against @p fieldStride can be done. You're
* encouraged to use the @ref SceneFieldData(SceneField, SceneMappingType, const Containers::StridedArrayView1D<const void>&, SceneFieldType, const Containers::StridedArrayView1D<const void>&, UnsignedShort, SceneFieldFlags)
* constructor if you want additional safeguards.
* @see @ref flags(),
* @see @ref SceneFieldData(SceneField, std::size_t, SceneMappingType, std::size_t, std::ptrdiff_t, SceneFieldType, std::size_t, std::ptrdiff_t, UnsignedShort, SceneFieldFlags),
* @ref flags(),
* @ref mappingData(Containers::ArrayView<const void>) const,
* @ref fieldData(Containers::ArrayView<const void>) const
*/
@ -1523,7 +1533,8 @@ Containers::Array<SceneFieldData> MAGNUM_TRADE_EXPORT sceneFieldDataNonOwningArr
Contains scene node hierarchy, transformations, resource assignment as well as
any other data associated with the scene. Populated instances of this class are
returned from @ref AbstractImporter::scene().
returned from @ref AbstractImporter::scene() as well as from various
@ref SceneTools algorithms.
@section Trade-SceneData-representation Data representation and terminology
@ -1745,6 +1756,31 @@ representation that matches your use case best, with fields interleaved
together or not. See also the @ref SceneFieldData class documentation for
additional ways how to specify and annotate the data.
@subsection Trade-SceneData-populating-non-owned Non-owned instances and static data layouts
In some cases you may want the @ref SceneData 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 an
@relativeref{Corrade,Containers::Array}, pass @ref DataFlags describing data
mutability and ownership together with an
@relativeref{Corrade,Containers::ArrayView} to the
@ref SceneData(SceneMappingType, UnsignedLong, DataFlags, Containers::ArrayView<const void>, Containers::Array<SceneFieldData>&&, const void*)
constructor:
@snippet MagnumTrade.cpp SceneData-populating-non-owned
The @ref SceneFieldData list is still implicitly allocated in the above case,
but it can also be defined externally and referenced via
@ref sceneFieldDataNonOwningArray() instead if desired. Finally, if the data
layout is constant but the actual data is allocated / populated at runtime, the
@ref SceneFieldData instances can be defined in a global array as offset-only
and then subsequently referenced from a @ref SceneData with a concrete data
array:
@snippet MagnumTrade.cpp SceneData-populating-offset-only
See also the @ref Trade-SceneFieldData-usage-offset-only "corresponding SceneFieldData documentation for offset-only fields".
@subsection Trade-SceneData-populating-custom Custom scene fields and non-node objects
Let's say that, in addition to the node hierarchy from above, our scene
@ -1825,8 +1861,6 @@ While there's many options how to store the string, retrieving of any string
@ref SceneFieldType can be conveniently done using @ref fieldStrings():
@snippet MagnumTrade.cpp SceneData-populating-strings-retrieve
@see @ref AbstractImporter::scene()
*/
class MAGNUM_TRADE_EXPORT SceneData {
public:

Loading…
Cancel
Save