Magnum::SceneTools namespace new in Git master

Scene tools.

Scene manipulation and optimization tools.

This library is built if MAGNUM_WITH_SCENETOOLS is enabled when building Magnum. To use this library with CMake, request the SceneTools component of the Magnum package and link to the Magnum::SceneTools target:

find_package(Magnum REQUIRED SceneTools)

# ...
target_link_libraries(your-app PRIVATE Magnum::SceneTools)

Additional utilities are built separately. See the magnum-sceneconverter utility documentation, Downloading and building and Usage with CMake for more information.

Functions

auto combineFields(Trade::SceneMappingType mappingType, UnsignedLong mappingBound, Containers::ArrayView<const Trade::SceneFieldData> fields) -> Trade::SceneData new in Git master
Combine scene fields together.
auto combineFields(Trade::SceneMappingType mappingType, UnsignedLong mappingBound, std::initializer_list<Trade::SceneFieldData> fields) -> Trade::SceneData new in Git master
auto combineFields(const Trade::SceneData& scene) -> Trade::SceneData new in Git master
Combine scene fields from scratch.
auto copy(const Trade::SceneData& material) -> Trade::SceneData new in Git master
Make an owned copy of the scene.
auto copy(Trade::SceneData&& material) -> Trade::SceneData new in Git master
Make a scene with owned data.
auto filterFields(const Trade::SceneData& scene, Containers::BitArrayView fieldsToKeep) -> Trade::SceneData new in Git master
Filter a scene to contain only the selected subset of fields.
auto filterOnlyFields(const Trade::SceneData& scene, Containers::ArrayView<const Trade::SceneField> fields) -> Trade::SceneData new in Git master
Filter a scene to contain only the selected subset of named fields.
auto filterOnlyFields(const Trade::SceneData& scene, std::initializer_list<Trade::SceneField> fields) -> Trade::SceneData new in Git master
auto filterExceptFields(const Trade::SceneData& scene, Containers::ArrayView<const Trade::SceneField> fields) -> Trade::SceneData new in Git master
Filter a scene to contain everything except the selected subset of named fields.
auto filterExceptFields(const Trade::SceneData& scene, std::initializer_list<Trade::SceneField> fields) -> Trade::SceneData new in Git master
auto filterFieldEntries(const Trade::SceneData& scene, Containers::ArrayView<const Containers::Pair<UnsignedInt, Containers::BitArrayView>> entriesToKeep) -> Trade::SceneData new in Git master
Filter individual entries of fields in a scene.
auto filterFieldEntries(const Trade::SceneData& scene, std::initializer_list<Containers::Pair<UnsignedInt, Containers::BitArrayView>> entriesToKeep) -> Trade::SceneData new in Git master
auto filterFieldEntries(const Trade::SceneData& scene, Containers::ArrayView<const Containers::Pair<Trade::SceneField, Containers::BitArrayView>> entriesToKeep) -> Trade::SceneData new in Git master
Filter individual entries of named fields in a scene.
auto filterFieldEntries(const Trade::SceneData& scene, std::initializer_list<Containers::Pair<Trade::SceneField, Containers::BitArrayView>> entriesToKeep) -> Trade::SceneData new in Git master
auto filterObjects(const Trade::SceneData& scene, Containers::BitArrayView objectsToKeep) -> Trade::SceneData new in Git master
Filter objects in a scene.
auto flattenMeshHierarchy2D(const Trade::SceneData& scene, const Matrix3& globalTransformation = {}) -> Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix3>> deprecated in Git master
Flatten a 2D mesh hierarchy.
void flattenMeshHierarchy2DInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {}) deprecated in Git master
Flatten a 2D mesh hierarchy into an existing array.
auto flattenMeshHierarchy3D(const Trade::SceneData& scene, const Matrix4& globalTransformation = {}) -> Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix4>> deprecated in Git master
Flatten a 3D mesh hierarchy.
void flattenMeshHierarchy3DInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {}) deprecated in Git master
Flatten a 3D mesh hierarchy into an existing array.
auto flattenTransformationHierarchy2D(const Trade::SceneData& scene, Trade::SceneField field, const Matrix3& globalTransformation = {}) -> Containers::Array<Matrix3> deprecated in Git master
Flatten a 2D transformation hierarchy for given field.
auto flattenTransformationHierarchy2D(const Trade::SceneData& scene, UnsignedInt fieldId, const Matrix3& globalTransformation = {}) -> Containers::Array<Matrix3> deprecated in Git master
Flatten a 2D transformation hierarchy for given field ID.
void flattenTransformationHierarchy2DInto(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {}) deprecated in Git master
Flatten a 2D transformation hierarchy for given field into an existing array.
void flattenTransformationHierarchy2DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {}) deprecated in Git master
Flatten a 2D transformation hierarchy for given field ID into an existing array.
auto flattenTransformationHierarchy3D(const Trade::SceneData& scene, Trade::SceneField field, const Matrix4& globalTransformation = {}) -> Containers::Array<Matrix4> deprecated in Git master
Flatten a 3D transformation hierarchy for given field.
auto flattenTransformationHierarchy3D(const Trade::SceneData& scene, UnsignedInt fieldId, const Matrix4& globalTransformation = {}) -> Containers::Array<Matrix4> deprecated in Git master
Flatten a 3D transformation hierarchy for given field ID.
void flattenTransformationHierarchy3DInto(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {}) deprecated in Git master
Flatten a 3D transformation hierarchy for given field into an existing array.
void flattenTransformationHierarchy3DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {}) deprecated in Git master
Flatten a 3D transformation hierarchy for given field ID into an existing array.
auto parentsBreadthFirst(const Trade::SceneData& scene) -> Containers::Array<Containers::Pair<UnsignedInt, Int>> new in Git master
Retrieve parents in a breadth-first order.
void parentsBreadthFirstInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<UnsignedInt>& mappingDestination, const Containers::StridedArrayView1D<Int>& parentDestination) new in Git master
Retrieve parents in a breadth-first order into a pre-allocated view.
auto childrenDepthFirst(const Trade::SceneData& scene) -> Containers::Array<Containers::Pair<UnsignedInt, UnsignedInt>> new in Git master
Retrieve children in a depth-first order.
void childrenDepthFirstInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<UnsignedInt>& mappingDestination, const Containers::StridedArrayView1D<UnsignedInt>& childCountDestination) new in Git master
Retrieve childrem in a depth-first order into a pre-allocated view.
auto absoluteFieldTransformations2D(const Trade::SceneData& scene, UnsignedInt fieldId, const Matrix3& globalTransformation = {}) -> Containers::Array<Matrix3> new in Git master
Calculate absolute 2D transformations for given field.
auto absoluteFieldTransformations2D(const Trade::SceneData& scene, Trade::SceneField field, const Matrix3& globalTransformation = {}) -> Containers::Array<Matrix3> new in Git master
Calculate absolute 2D transformations for given named field.
void absoluteFieldTransformations2DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {}) new in Git master
Calculate absolute 2D transformations for given field into an existing array.
void absoluteFieldTransformations2DInto(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {}) new in Git master
Calculate absolute 2D transformations for given named field into an existing array.
auto absoluteFieldTransformations3D(const Trade::SceneData& scene, UnsignedInt fieldId, const Matrix4& globalTransformation = {}) -> Containers::Array<Matrix4> new in Git master
Calculate absolute 2D transformations for given field.
auto absoluteFieldTransformations3D(const Trade::SceneData& scene, Trade::SceneField field, const Matrix4& globalTransformation = {}) -> Containers::Array<Matrix4> new in Git master
Calculate absolute 3D transformations for given named field.
void absoluteFieldTransformations3DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {}) new in Git master
Calculate absolute 3D transformations for given field into an existing array.
void absoluteFieldTransformations3DInto(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {}) new in Git master
Calculate absolute 3D transformations for given named field into an existing array.
auto mapIndexField(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) -> Trade::SceneData new in Git master
Map an index field in a scene.
auto mapIndexField(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) -> Trade::SceneData new in Git master
Map a named index field in a scene.
auto mapIndexField(Trade::SceneData&& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) -> Trade::SceneData new in Git master
Map an index field in a scene.
auto mapIndexField(Trade::SceneData&& scene, Trade::SceneField field, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) -> Trade::SceneData new in Git master
Map a named index field in a scene.
void mapIndexFieldInPlace(Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master
Map an index field in a scene in-place.
void mapIndexFieldInPlace(Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master
Map a named index field in a scene in-place.
auto orderClusterParents(const Trade::SceneData& scene) -> Containers::Array<Containers::Pair<UnsignedInt, Int>> deprecated in Git master
Calculate ordered and clustered parents.
void orderClusterParentsInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<UnsignedInt>& mappingDestination, const Containers::StridedArrayView1D<Int>& parentDestination) deprecated in Git master
Calculate ordered and clustered parents.

Function documentation

Trade::SceneData Magnum::SceneTools::combineFields(Trade::SceneMappingType mappingType, UnsignedLong mappingBound, Containers::ArrayView<const Trade::SceneFieldData> fields) new in Git master

Combine scene fields together.

Combines fields of varying Trade::SceneMappingType together into a Trade::SceneData of a single mappingType. If any fields fully share their mapping views (such as Trade::SceneField::Mesh and MeshMaterial, including fields for which this isn't enforced), the sharing gets preserved. Partial sharing or sharing of data views (as opposed to mapping views) isn't recognized and the data will get duplicated.

Fields pointing to existing memory are copied to the output, fields with (sized) nullptr mapping or data views are treated as placeholders for copying the data later, with memory left uninitialized. If you however want to have placeholder mapping data shared among multiple fields you have to allocate them upfront. Fields with a string Trade::SceneFieldType can't have placeholder data views or nullptr string data pointers, as they're used to calculate the total string data size. Note that offset-only Trade::SceneFieldData instances are not supported in the fields array.

The resulting fields are always tightly packed (not interleaved). Returned data flags have both Trade::DataFlag::Mutable and Trade::DataFlag::Owned, so mutable attribute access is guaranteed.

Trade::SceneData Magnum::SceneTools::combineFields(Trade::SceneMappingType mappingType, UnsignedLong mappingBound, std::initializer_list<Trade::SceneFieldData> fields) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::SceneData Magnum::SceneTools::combineFields(const Trade::SceneData& scene) new in Git master

Combine scene fields from scratch.

Calls combineFields(Trade::SceneMappingType, UnsignedLong, Containers::ArrayView<const Trade::SceneFieldData>) with mapping type, bound and fields coming from scene. Useful for conveniently repacking an existing scene and throwing away data not referenced by any field.

Trade::SceneData Magnum::SceneTools::copy(const Trade::SceneData& material) new in Git master

Make an owned copy of the scene.

Allocates a copy of Trade::SceneData::data() and fieldData() and returns a new scene with them. All other properties such as the mapping bound or importer state are passed through unchanged, the data layout isn't changed in any way. The resulting Trade::SceneData::dataFlags() are always Trade::DataFlag::Owned and Trade::DataFlag::Mutable.

Trade::SceneData Magnum::SceneTools::copy(Trade::SceneData&& material) new in Git master

Make a scene with owned data.

If Trade::SceneData::dataFlags() are not Trade::DataFlag::Owned and Trade::DataFlag::Mutable or the field data don't have the default deleter, allocates a copy of Trade::SceneData::data() or fieldData(), otherwise transfers their ownership. The resulting data are always owned and mutable, the data layout isn't changed in any way.

Trade::SceneData Magnum::SceneTools::filterFields(const Trade::SceneData& scene, Containers::BitArrayView fieldsToKeep) new in Git master

Filter a scene to contain only the selected subset of fields.

Returns a non-owning reference to the data from scene with only the fields for which the corresponding bit in fieldsToKeep was set. The size of fieldsToKeep is expected to be equal to Trade::SceneData::fieldCount().

This function only operates on the field metadata — if you'd like to have the data repacked to contain just the remaining fields as well, pass the output to combineFields(const Trade::SceneData&).

Trade::SceneData Magnum::SceneTools::filterOnlyFields(const Trade::SceneData& scene, Containers::ArrayView<const Trade::SceneField> fields) new in Git master

Filter a scene to contain only the selected subset of named fields.

Returns a non-owning reference to the data from scene with only the fields that are listed in fields. Fields from the list that are not present in scene are skipped, duplicates in the list are treated the same as if given field was listed just once.

This function only operates on the field metadata — if you'd like to have the data repacked to contain just the remaining fields as well, pass the output to combineFields(const Trade::SceneData&).

Trade::SceneData Magnum::SceneTools::filterOnlyFields(const Trade::SceneData& scene, std::initializer_list<Trade::SceneField> fields) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::SceneData Magnum::SceneTools::filterExceptFields(const Trade::SceneData& scene, Containers::ArrayView<const Trade::SceneField> fields) new in Git master

Filter a scene to contain everything except the selected subset of named fields.

Returns a non-owning reference to the data from scene with only the fields that are not listed in fields. Fields from the list that are not present in scene are skipped, duplicates in the list are treated the same as if given fields was listed just once.

This function only operates on the field metadata — if you'd like to have the data repacked to contain just the remaining fields as well, pass the output to combineFields(const Trade::SceneData&).

Trade::SceneData Magnum::SceneTools::filterExceptFields(const Trade::SceneData& scene, std::initializer_list<Trade::SceneField> fields) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::SceneData Magnum::SceneTools::filterFieldEntries(const Trade::SceneData& scene, Containers::ArrayView<const Containers::Pair<UnsignedInt, Containers::BitArrayView>> entriesToKeep) new in Git master

Filter individual entries of fields in a scene.

Returns a copy of scene containing the same fields but only with entries for which the corresponding bit in entriesToKeep is set. Each item in entriesToKeep is a pair of a field ID and a mask of entries to keep in that field. The field ID is expected to be unique in the list and less than Trade::SceneData::fieldCount(), size of the mask then equal to Trade::SceneData::fieldSize() for that field. Fields not listed in the entriesToKeep array are passed through unchanged, use filterFields(), filterExceptFields() or filterOnlyFields() to deal with them as a whole if needed.

Fields that fully share their mapping views (such as Trade::SceneField::Mesh and MeshMaterial, including fields for which this isn't enforced) either need to be listed all in entriesToKeep with the same mask view, or all omitted so they're passed through. Fields that share the mapping only partially don't have any special handling. The data repacking is performed using combineFields(), see its documentation for more information.

Field flags are preserved except for Trade::SceneFieldFlag::ImplicitMapping — if a field with this flag is present in the list, the field is downgraded to Trade::SceneFieldFlag::OrderedMapping, as removing field entries makes the mapping to no longer be an implicit sequence (but the order is still preserved). For simplicity this downgrade happens always, even if all bits for given field may be set. Fields with Trade::SceneFieldFlag::ImplicitMapping that aren't present in the list have the flag preserved.

As an example, let's assume in the following snippet the scene contains Trade::SceneField::Translation, Rotation, Mesh, MeshMaterial and Light, with the intent to filter some translations and lights away. Filtering translations means the rotations have to be filtered as well, however neither meshes nor materials (which share the mapping as well) need to be listed if they're not filtered:

Trade::SceneData scene = ;

Containers::BitArray transformationsToKeep = ;
Containers::BitArray lightsToKeep = ;

/* Mesh and MeshMaterial fields stay unchanged */
Trade::SceneData filtered = SceneTools::filterFieldEntries(scene, {
    {Trade::SceneField::Translation, transformationsToKeep},
    {Trade::SceneField::Rotation, transformationsToKeep},
    {Trade::SceneField::Light, lightsToKeep}
});

At the moment, Trade::SceneFieldType::Bit and string fields can't be filtered, only passed through.

Trade::SceneData Magnum::SceneTools::filterFieldEntries(const Trade::SceneData& scene, std::initializer_list<Containers::Pair<UnsignedInt, Containers::BitArrayView>> entriesToKeep) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::SceneData Magnum::SceneTools::filterFieldEntries(const Trade::SceneData& scene, Containers::ArrayView<const Containers::Pair<Trade::SceneField, Containers::BitArrayView>> entriesToKeep) new in Git master

Filter individual entries of named fields in a scene.

Translates field names in entriesToKeep to field IDs using Trade::SceneData::fieldId() and delegates to filterFieldEntries(const Trade::SceneData&, Containers::ArrayView<const Containers::Pair<UnsignedInt, Containers::BitArrayView>>). Expects that all listed fields exist in scene, see the referenced function documentation for other expectations.

Trade::SceneData Magnum::SceneTools::filterFieldEntries(const Trade::SceneData& scene, std::initializer_list<Containers::Pair<Trade::SceneField, Containers::BitArrayView>> entriesToKeep) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::SceneData Magnum::SceneTools::filterObjects(const Trade::SceneData& scene, Containers::BitArrayView objectsToKeep) new in Git master

Filter objects in a scene.

Returns a copy of scene containing the same fields but only with entries mapped to objects for which the corresponding bit in objectsToKeep is set. The size of objectsToKeep is expected to be equal to Trade::SceneData::mappingBound().

Fields that don't contain any entries mapped to filtered-out objects are passed through unchanged. The data filtering is performed using filterFieldEntries() which then delegates to combineFields() for repacking the data, see their documentation for more information.

Note that this function performs only filtering of the data, it doesn't change the data in any other way. If there are references to the removed objects from other fields such as Trade::SceneField::Parent, it's the responsibility of the caller to deal with them either before or after calling this API, otherwise the returned data may end up being unusable.

void Magnum::SceneTools::flattenMeshHierarchy2DInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {})

Flatten a 2D mesh hierarchy into an existing array.

Parameters
scene in Input scene
transformations out Where to put the calculated transformations
globalTransformation in Global transformation to prepend

void Magnum::SceneTools::flattenMeshHierarchy3DInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {})

Flatten a 3D mesh hierarchy into an existing array.

Parameters
scene in Input scene
transformations out Where to put the calculated transformations
globalTransformation in Global transformation to prepend

void Magnum::SceneTools::flattenTransformationHierarchy2DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {})

Flatten a 2D transformation hierarchy for given field ID into an existing array.

void Magnum::SceneTools::flattenTransformationHierarchy3DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {})

Flatten a 3D transformation hierarchy for given field ID into an existing array.

Containers::Array<Containers::Pair<UnsignedInt, Int>> Magnum::SceneTools::parentsBreadthFirst(const Trade::SceneData& scene) new in Git master

Retrieve parents in a breadth-first order.

Extracts the Trade::SceneField::Parent field mapping and data from scene and converts it to match the following rules:

  • a parent object reference appears always before any of its children
  • the array is clustered so children sharing the same parent are together

This form is useful primarily for calculating absolute object transformations, for example:

Trade::SceneData scene = ;

/* Put all transformations into an array indexed by object ID. Objects
   implicitly have an identity transformation, first element is reserved for
   the global transformation. */
Containers::Array<Matrix4> transformations{std::size_t(scene.mappingBound() + 1)};
for(const Containers::Pair<UnsignedInt, Matrix4>& transformation:
    scene.transformations3DAsArray())
{
    transformations[transformation.first() + 1] = transformation.second();
}

/* Go through ordered parents and compose absolute transformations for all
   nodes in the hierarchy, objects in the root use transformations[0]. The
   function ensures that the parent transformation is already calculated when
   referenced by child nodes. */
for(const Containers::Pair<UnsignedInt, Int>& parent:
    SceneTools::parentsBreadthFirst(scene))
{
    transformations[parent.first() + 1] =
        transformations[parent.second() + 1]*
        transformations[parent.first() + 1];
}

The operation is done in an $ \mathcal{O}(n) $ execution time and memory complexity, with $ n $ being Trade::SceneData::mappingBound(). The Trade::SceneField::Parent field is expected to be contained in the scene, having no cycles (i.e., every node listed just once) and not being sparse (i.e., every node listed in the field reachable from the root).

void Magnum::SceneTools::parentsBreadthFirstInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<UnsignedInt>& mappingDestination, const Containers::StridedArrayView1D<Int>& parentDestination) new in Git master

Retrieve parents in a breadth-first order into a pre-allocated view.

Like parentsBreadthFirst(), but puts the result into mappingDestination and parentDestination instead of allocating a new array. Expect that both views have a size equal to size of the Trade::SceneField::Parent view in scene.

Containers::Array<Containers::Pair<UnsignedInt, UnsignedInt>> Magnum::SceneTools::childrenDepthFirst(const Trade::SceneData& scene) new in Git master

Retrieve children in a depth-first order.

Extracts the Trade::SceneField::Parent field mapping and data from scene and converts it to a list of (object index, children count) pairs such that:

  • children of given object are directly following the object itself
  • the count includes direct children as well as nested children, next object in the same level, if exists, is thus after another count items

Objects in particular level keep the same order as they had in the Trade::SceneField::Parent field. Size of the returned list is equal to the Trade::SceneField::Parent field size. Implicitly, the whole returned list contains (nested) children of the root, which implies that the first returned object is the first top-level object (i.e., with a parent equal to -1), and size of the list is the count of all objects.

This form is useful primarily for marking and extracting subtrees, for example:

Trade::SceneData scene = ;

Containers::Array<Containers::Pair<UnsignedInt, UnsignedInt>> childrenRanges =
    SceneTools::childrenDepthFirst(scene);

/* Bit array of objects to keep from the scene */
UnsignedInt objectToLookFor = ;
Containers::BitArray objectsToKeep{ValueInit, std::size_t(scene.mappingBound())};

/* Look for the object in the list */
for(const Containers::Pair<UnsignedInt, UnsignedInt>& i: childrenRanges) {
    if(i.first() != objectToLookFor) continue;

    /* Right after the object appearing in the list is all its (nested)
       children, mark them in the bit array */
    for(const Containers::Pair<UnsignedInt, UnsignedInt>& j:
        childrenRanges.sliceSize(&i, i.second() + 1))
            objectsToKeep.set(j.first());

    break;
}

/* Filter the scene to contain just given object and its children, and reparent
   it to be in scene root */
Trade::SceneData filtered = SceneTools::filterObjects(scene, objectsToKeep);
filtered.mutableField<Int>(Trade::SceneField::Parent)[
    filtered.fieldObjectOffset(Trade::SceneField::Parent, objectToLookFor)
] = -1;

The operation is done in an $ \mathcal{O}(n) $ execution time and memory complexity, with $ n $ being Trade::SceneData::mappingBound(). The Trade::SceneField::Parent field is expected to be contained in the scene, having no cycles (i.e., every node listed just once) and not being sparse (i.e., every node listed in the field reachable from the root).

void Magnum::SceneTools::childrenDepthFirstInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<UnsignedInt>& mappingDestination, const Containers::StridedArrayView1D<UnsignedInt>& childCountDestination) new in Git master

Retrieve childrem in a depth-first order into a pre-allocated view.

Like childrenDepthFirst(), but puts the result into mappingDestination and childCountDestination instead of allocating a new array. Expect that both views have a size equal to size of the Trade::SceneField::Parent view in scene.

Containers::Array<Matrix3> Magnum::SceneTools::absoluteFieldTransformations2D(const Trade::SceneData& scene, UnsignedInt fieldId, const Matrix3& globalTransformation = {}) new in Git master

Calculate absolute 2D transformations for given field.

For all entries of given field in scene returns an absolute transformation of the object they're attached to in the scene with globalTransformation prepended. The Trade::SceneField::Parent field is expected to be contained in the scene, having no cycles or duplicates, the scene is expected to be 2D and fieldId is expected to be less than Trade::SceneData::fieldCount(). If the field is empty, the function returns an empty array.

The operation is done in an $ \mathcal{O}(m + n) $ execution time and memory complexity, with $ m $ being size of fieldId and $ n $ being Trade::SceneData::mappingBound(). The function calls parentsBreadthFirst() internally.

The returned data are in the same order as object mapping entries in fieldId. Fields attached to objects without a Trade::SceneField::Parent or to objects in loose hierarchy subtrees will have their transformation set to an unspecified value.

This function can be used for example to flatten a mesh hierarchy, bake the transformations to actual meshes and then concatenate them together into a single mesh:

Trade::SceneData scene = ;
Containers::Array<Trade::MeshData> meshes = ;

Containers::Array<Containers::Pair<UnsignedInt, Containers::Pair<UnsignedInt, Int>>>
    meshesMaterials = scene.meshesMaterialsAsArray();
Containers::Array<Matrix3> transformations =
    SceneTools::absoluteFieldTransformations2D(scene, Trade::SceneField::Mesh);

/* Since a mesh can be referenced multiple times, we can't operate in-place */
Containers::Array<Trade::MeshData> flattenedMeshes;
for(std::size_t i = 0; i != meshesMaterials.size(); ++i) {
    arrayAppend(flattenedMeshes, MeshTools::transform2D(
        meshes[meshesMaterials[i].second().first()], transformations[i]));
}

Trade::MeshData concatenated = MeshTools::concatenate(flattenedMeshes);

Containers::Array<Matrix3> Magnum::SceneTools::absoluteFieldTransformations2D(const Trade::SceneData& scene, Trade::SceneField field, const Matrix3& globalTransformation = {}) new in Git master

Calculate absolute 2D transformations for given named field.

Translates field to a field ID using Trade::SceneData::fieldId() and delegates to absoluteFieldTransformations2D(const Trade::SceneData&, UnsignedInt, const Matrix3&). The field is expected to exist in scene.

void Magnum::SceneTools::absoluteFieldTransformations2DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {}) new in Git master

Calculate absolute 2D transformations for given field into an existing array.

Parameters
scene in Input scene
fieldId in Field to calculate the transformations for
transformations out Where to put the calculated transformations
globalTransformation in Global transformation to prepend

A variant of absoluteFieldTransformations2D(const Trade::SceneData&, UnsignedInt, const Matrix3&) that fills existing memory instead of allocating a new array. The transformations array is expected to have the same size as the fieldId.

void Magnum::SceneTools::absoluteFieldTransformations2DInto(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<Matrix3>& transformations, const Matrix3& globalTransformation = {}) new in Git master

Calculate absolute 2D transformations for given named field into an existing array.

Translates field to a field ID using Trade::SceneData::fieldId() and delegates to absoluteFieldTransformations2DInto(const Trade::SceneData&, UnsignedInt, const Containers::StridedArrayView1D<Matrix3>&, const Matrix3&) The field is expected to exist in scene.

Containers::Array<Matrix4> Magnum::SceneTools::absoluteFieldTransformations3D(const Trade::SceneData& scene, UnsignedInt fieldId, const Matrix4& globalTransformation = {}) new in Git master

Calculate absolute 2D transformations for given field.

For all entries of given field in scene returns an absolute transformation of the object they're attached to in the scene with globalTransformation prepended. The Trade::SceneField::Parent field is expected to be contained in the scene, having no cycles or duplicates, the scene is expected to be 3D and fieldId is expected to be less than Trade::SceneData::fieldCount(). If the field is empty, the function returns an empty array.

The operation is done in an $ \mathcal{O}(m + n) $ execution time and memory complexity, with $ m $ being size of fieldId and $ n $ being Trade::SceneData::mappingBound(). The function calls parentsBreadthFirst() internally.

The returned data are in the same order as object mapping entries in fieldId. Fields attached to objects without a Trade::SceneField::Parent or to objects in loose hierarchy subtrees will have their transformation set to an unspecified value.

This function can be used for example to flatten a mesh hierarchy, bake the transformations to actual meshes and then concatenate them together into a single mesh:

Trade::SceneData scene = ;
Containers::Array<Trade::MeshData> meshes = ;

Containers::Array<Containers::Pair<UnsignedInt, Containers::Pair<UnsignedInt, Int>>>
    meshesMaterials = scene.meshesMaterialsAsArray();
Containers::Array<Matrix4> transformations =
    SceneTools::absoluteFieldTransformations3D(scene, Trade::SceneField::Mesh);

/* Since a mesh can be referenced multiple times, we can't operate in-place */
Containers::Array<Trade::MeshData> flattenedMeshes;
for(std::size_t i = 0; i != meshesMaterials.size(); ++i) {
    arrayAppend(flattenedMeshes, MeshTools::transform3D(
        meshes[meshesMaterials[i].second().first()], transformations[i]));
}

Trade::MeshData concatenated = MeshTools::concatenate(flattenedMeshes);

Containers::Array<Matrix4> Magnum::SceneTools::absoluteFieldTransformations3D(const Trade::SceneData& scene, Trade::SceneField field, const Matrix4& globalTransformation = {}) new in Git master

Calculate absolute 3D transformations for given named field.

Translates field to a field ID using Trade::SceneData::fieldId() and delegates to absoluteFieldTransformations3D(const Trade::SceneData&, UnsignedInt, const Matrix4&). The field is expected to exist in scene.

void Magnum::SceneTools::absoluteFieldTransformations3DInto(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {}) new in Git master

Calculate absolute 3D transformations for given field into an existing array.

Parameters
scene in Input scene
fieldId in Field to calculate the transformations for
transformations out Where to put the calculated transformations
globalTransformation in Global transformation to prepend

A variant of absoluteFieldTransformations3D(const Trade::SceneData&, UnsignedInt, const Matrix4&) that fills existing memory instead of allocating a new array. The transformations array is expected to have the same size as the fieldId.

void Magnum::SceneTools::absoluteFieldTransformations3DInto(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<Matrix4>& transformations, const Matrix4& globalTransformation = {}) new in Git master

Calculate absolute 3D transformations for given named field into an existing array.

Translates field to a field ID using Trade::SceneData::fieldId() and delegates to absoluteFieldTransformations3DInto(const Trade::SceneData&, UnsignedInt, const Containers::StridedArrayView1D<Matrix4>&, const Matrix4&) The field is expected to exist in scene.

Trade::SceneData Magnum::SceneTools::mapIndexField(const Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master

Map an index field in a scene.

Maps a field containing data indices, such as Trade::SceneField::Mesh or Trade::SceneField::Camera, to different indices by iterating through the field at index fieldId and replacing a particular value with mapping[value]. If the field has a signed type (such as is the case with Trade::SceneField::MeshMaterial), -1 is treated as an "unset" value and preserved verbatim.

Expects that fieldId is less than Trade::SceneData::fieldCount(), the field is Trade::SceneFieldType::UnsignedInt, Int, UnsignedShort, Short, UnsignedByte or Byte and is not an array, and that the mapping array is large enough to cover all field values.

The output field is always a Trade::SceneFieldType::UnsignedInt if the input type is unsigned and Trade::SceneFieldType::Int if it's signed. See also mapIndexField(Trade::SceneData&&, UnsignedInt, const Containers::StridedArrayView1D<const UnsignedInt>&) for a potentially more efficient operation instead of always performing a full copy, you can also do an in-place mapping using mapIndexFieldInPlace(Trade::SceneData&, UnsignedInt, const Containers::StridedArrayView1D<const UnsignedInt>&) which doesn't change the field type but additionally expects that the mapping values don't overflow given type.

Trade::SceneData Magnum::SceneTools::mapIndexField(const Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master

Map a named index field in a scene.

Translates field to a field ID using Trade::SceneData::fieldId() and delegates to mapIndexField(const Trade::SceneData&, UnsignedInt, const Containers::StridedArrayView1D<const UnsignedInt>&). The field is expected to exist in scene.

Trade::SceneData Magnum::SceneTools::mapIndexField(Trade::SceneData&& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master

Map an index field in a scene.

Compared to mapIndexField(const Trade::SceneData&, UnsignedInt, const Containers::StridedArrayView1D<const UnsignedInt>&) this function can perform the mapping in-place, transferring the data ownership to the returned instance if the data is owned and mutable and the field at index fieldId is Trade::SceneFieldType::UnsignedInt or Trade::SceneFieldType::Int.

Trade::SceneData Magnum::SceneTools::mapIndexField(Trade::SceneData&& scene, Trade::SceneField field, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master

Map a named index field in a scene.

Translates field to a field ID using Trade::SceneData::fieldId() and delegates to mapIndexField(Trade::SceneData&&, UnsignedInt, const Containers::StridedArrayView1D<const UnsignedInt>&). The field is expected to exist in scene.

void Magnum::SceneTools::mapIndexFieldInPlace(Trade::SceneData& scene, UnsignedInt fieldId, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master

Map an index field in a scene in-place.

Parameters
scene in/out Scene
fieldId in Field to map
mapping in Index value mapping

Maps a field containing data indices, such as Trade::SceneField::Mesh or Trade::SceneField::Camera, to different indices by iterating through the field at index fieldId and replacing a particular value with mapping[value]. If the field has a signed type (such as is the case with Trade::SceneField::MeshMaterial), -1 is treated as an "unset" value and preserved verbatim.

Expects that the scene has mutable data, fieldId is less than Trade::SceneData::fieldCount(), the field is Trade::SceneFieldType::UnsignedInt, Int, UnsignedShort, Short, UnsignedByte or Byte and is not an array, the mapping array is large enough to cover all field values and the mapping values don't overflow given type.

If you need to map to a larger index range that doesn't fit into the original field type, use mapIndexField(const Trade::SceneData&, UnsignedInt, const Containers::StridedArrayView1D<const UnsignedInt>&) instead.

void Magnum::SceneTools::mapIndexFieldInPlace(Trade::SceneData& scene, Trade::SceneField field, const Containers::StridedArrayView1D<const UnsignedInt>& mapping) new in Git master

Map a named index field in a scene in-place.

Parameters
scene in/out Scene
field in Field to map
mapping in Index value mapping

Translates field to a field ID using Trade::SceneData::fieldId() and delegates to mapIndexFieldInPlace(Trade::SceneData&, UnsignedInt, const Containers::StridedArrayView1D<const UnsignedInt>&). The field is expected to exist in scene.