Magnum::SceneTools namespace new in Git master

Scene tools.

Scene manipulation and optimization tools.

This library is built if 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 flattenMeshHierarchy2D(const Trade::SceneData& scene, const Matrix3& globalTransformation) -> Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix3>> new in Git master
Flatten a 2D mesh hierarchy.
auto flattenMeshHierarchy2D(const Trade::SceneData& scene) -> Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix3>> new in Git master
auto flattenMeshHierarchy3D(const Trade::SceneData& scene, const Matrix4& globalTransformation) -> Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix4>> new in Git master
Flatten a 3D mesh hierarchy.
auto flattenMeshHierarchy3D(const Trade::SceneData& scene) -> Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix4>> new in Git master
auto orderClusterParents(const Trade::SceneData& scene) -> Containers::Array<Containers::Pair<UnsignedInt, Int>> new in Git master
Calculate ordered and clustered parents.
void orderClusterParentsInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<UnsignedInt>& mappingDestination, const Containers::StridedArrayView1D<Int>& parentDestination) new in Git master
Calculate ordered and clustered parents into a pre-allocated view.

Function documentation

Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix3>> Magnum::SceneTools::flattenMeshHierarchy2D(const Trade::SceneData& scene, const Matrix3& globalTransformation) new in Git master

Flatten a 2D mesh hierarchy.

For all Trade::SceneField::Mesh entries that are a part of a hierarchy returns a triple of mesh ID, Trade::SceneField::MeshMaterial and its absolute transformation in the scene with globalTransformation prepended. The Trade::SceneField::Parent field is expected to be contained in the scene, having no cycles or duplicates, and the scene is expected to be 2D. If Trade::SceneField::Mesh is not present or is empty, returns an empty array. You can then use MeshTools::transform2D() to apply the transformations to actual meshes:

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

/* Since a mesh can be referenced multiple times, we can't operate in-place */
Containers::Array<Trade::MeshData> flattenedMeshes;
for(const Containers::Triple<UnsignedInt, Int, Matrix3>& meshTransformation:
    SceneTools::flattenMeshHierarchy2D(scene))
{
    arrayAppend(flattenedMeshes, MeshTools::transform2D(
        meshes[meshTransformation.first()], meshTransformation.third()));
}

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

Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix3>> Magnum::SceneTools::flattenMeshHierarchy2D(const Trade::SceneData& scene) 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.

Same as above with globalTransformation set to an identity matrix.

Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix4>> Magnum::SceneTools::flattenMeshHierarchy3D(const Trade::SceneData& scene, const Matrix4& globalTransformation) new in Git master

Flatten a 3D mesh hierarchy.

For all Trade::SceneField::Mesh entries that are a part of a hierarchy returns a triple of mesh ID, Trade::SceneField::MeshMaterial and its absolute transformation in the scene with globalTransformation prepended. The Trade::SceneField::Parent field is expected to be contained in the scene, having no cycles or duplicates, and the scene is expected to be 3D. If Trade::SceneField::Mesh is not present or is empty, returns an empty array. You can then use MeshTools::transform3D() to apply the transformations to actual meshes:

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

/* Since a mesh can be referenced multiple times, we can't operate in-place */
Containers::Array<Trade::MeshData> flattenedMeshes;
for(const Containers::Triple<UnsignedInt, Int, Matrix4>& meshTransformation:
    SceneTools::flattenMeshHierarchy3D(scene))
{
    arrayAppend(flattenedMeshes, MeshTools::transform3D(
        meshes[meshTransformation.first()], meshTransformation.third()));
}

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

Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix4>> Magnum::SceneTools::flattenMeshHierarchy3D(const Trade::SceneData& scene) 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.

Same as above with globalTransformation set to an identity matrix.

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

Calculate ordered and clustered parents.

Extracts the Trade::SceneField::Parent field 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::orderClusterParents(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::orderClusterParentsInto(const Trade::SceneData& scene, const Containers::StridedArrayView1D<UnsignedInt>& mappingDestination, const Containers::StridedArrayView1D<Int>& parentDestination) new in Git master

Calculate ordered and clustered parents into a pre-allocated view.

Like orderClusterParents(), 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.