Browse Source

Trade: high-level documentation for SceneData.

pull/525/head
Vladimír Vondruš 5 years ago
parent
commit
1fbb87e732
  1. 1610
      doc/artwork/scenedata-dod.svg
  2. 1290
      doc/artwork/scenedata-tree.svg
  3. 229
      doc/snippets/MagnumTrade.cpp
  4. 7
      doc/snippets/README.md
  5. 148
      doc/snippets/scenedata-dod.svg
  6. 255
      doc/snippets/scenedata-tree.svg
  7. 273
      src/Magnum/Trade/SceneData.h

1610
doc/artwork/scenedata-dod.svg

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 108 KiB

1290
doc/artwork/scenedata-tree.svg

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 83 KiB

229
doc/snippets/MagnumTrade.cpp

@ -24,8 +24,11 @@
*/
#include <unordered_map>
#include <Corrade/Containers/ArrayTuple.h>
#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Utility/Algorithms.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Directory.h>
#include <Corrade/Utility/Resource.h>
@ -51,6 +54,11 @@
#include "Magnum/Trade/PbrSpecularGlossinessMaterialData.h"
#include "Magnum/Trade/PbrMetallicRoughnessMaterialData.h"
#include "Magnum/Trade/PhongMaterialData.h"
#include "Magnum/Trade/SceneData.h"
#include "Magnum/SceneGraph/Drawable.h"
#include "Magnum/SceneGraph/Scene.h"
#include "Magnum/SceneGraph/Object.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.h"
#ifdef MAGNUM_TARGET_GL
#include "Magnum/GL/Texture.h"
#include "Magnum/GL/TextureFormat.h"
@ -73,6 +81,7 @@
#endif
#define DOXYGEN_ELLIPSIS(...) __VA_ARGS__
#define DOXYGEN_IGNORE(...) __VA_ARGS__
using namespace Magnum;
using namespace Magnum::Math::Literals;
@ -872,4 +881,224 @@ CORRADE_IGNORE_DEPRECATED_POP
}
#endif
{
/* [SceneFieldData-usage] */
Containers::StridedArrayView1D<UnsignedInt> transformationMapping = DOXYGEN_ELLIPSIS({});
Containers::StridedArrayView1D<Matrix4> transformations = DOXYGEN_ELLIPSIS({});
Trade::SceneFieldData field{Trade::SceneField::Transformation,
transformationMapping, transformations};
/* [SceneFieldData-usage] */
}
{
/* [SceneFieldData-usage-offset-only] */
struct Node {
UnsignedInt object;
Int parent;
Matrix4 transform;
};
/* Layout defined statically, 120 objects in total */
constexpr Trade::SceneFieldData parents{Trade::SceneField::Parent, 120,
Trade::SceneMappingType::UnsignedInt, offsetof(Node, object), 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}};
/* [SceneFieldData-usage-offset-only] */
}
{
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
/* [SceneData-usage1] */
Trade::SceneData data = DOXYGEN_ELLIPSIS(Trade::SceneData{{}, 0, nullptr, nullptr});
if(!data.is3D() ||
!data.hasField(Trade::SceneField::Parent) ||
!data.hasField(Trade::SceneField::Mesh))
Fatal{} << "Oh noes!";
Scene3D scene;
Containers::Array<Object3D*> objects{std::size_t(data.mappingBound())};
/* [SceneData-usage1] */
/* [SceneData-usage2] */
auto parents = data.parentsAsArray();
for(Containers::Pair<UnsignedInt, Int>& parent: parents)
objects[parent.first()] = new Object3D{};
/* [SceneData-usage2] */
/* [SceneData-usage3] */
for(Containers::Pair<UnsignedInt, Int>& parent: parents)
objects[parent.first()]->setParent(
parent.second() == -1 ? &scene : objects[parent.second()]
);
/* [SceneData-usage3] */
/* [SceneData-usage4] */
for(Containers::Pair<UnsignedInt, Matrix4>& transformation:
data.transformations3DAsArray())
{
if(Object3D* const object = objects[transformation.first()])
object->setTransformation(transformation.second());
}
/* [SceneData-usage4] */
/* [SceneData-usage5] */
class Drawable: public SceneGraph::Drawable3D {
public:
explicit Drawable(Object3D& object, UnsignedInt mesh, Int material, DOXYGEN_ELLIPSIS(int))DOXYGEN_IGNORE(: SceneGraph::Drawable3D{object} {
static_cast<void>(mesh);
static_cast<void>(material);
} int foo);
DOXYGEN_ELLIPSIS(void draw(const Matrix4&, SceneGraph::Camera3D&) override {})
};
for(const Containers::Pair<UnsignedInt, Containers::Pair<UnsignedInt, Int>>&
meshMaterial: data.meshesMaterialsAsArray())
{
if(Object3D* const object = objects[meshMaterial.first()])
new Drawable{*object, meshMaterial.second().first(),
meshMaterial.second().second(), DOXYGEN_ELLIPSIS(0)};
}
/* [SceneData-usage5] */
/* [SceneData-usage-advanced] */
Containers::StridedArrayView1D<const UnsignedInt> transformationMapping =
data.mapping<UnsignedInt>(Trade::SceneField::Transformation);
Containers::StridedArrayView1D<const Matrix4> transformations =
data.field<Matrix4>(Trade::SceneField::Transformation);
for(std::size_t i = 0; i != transformationMapping.size(); ++i) {
if(Object3D* const object = objects[transformationMapping[i]])
object->setTransformation(transformations[i]);
}
/* [SceneData-usage-advanced] */
}
{
Trade::SceneData data{{}, 0, nullptr, nullptr};
/* [SceneData-per-object] */
Containers::Pointer<Trade::AbstractImporter> importer = DOXYGEN_ELLIPSIS({});
for(const Containers::Pair<UnsignedInt, Int>& meshMaterial:
data.meshesMaterialsFor(importer->objectForName("Chair")))
{
Debug{} << "Mesh:" << importer->meshName(meshMaterial.first());
if(meshMaterial.second() != -1)
Debug{} << "With a material:" << importer->materialName(meshMaterial.second());
}
/* [SceneData-per-object] */
}
{
Trade::SceneData data{{}, 0, nullptr, nullptr};
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
Containers::Array<Object3D*> objects;
/* [SceneData-usage-mutable] */
Containers::StridedArrayView1D<const UnsignedInt> transformationMapping =
data.mapping<UnsignedInt>(Trade::SceneField::Transformation);
Containers::StridedArrayView1D<Matrix4> mutableTransformations =
data.mutableField<Matrix4>(Trade::SceneField::Transformation);
for(std::size_t i = 0; i != transformationMapping.size(); ++i) {
if(Object3D* const object = objects[transformationMapping[i]])
mutableTransformations[i] = object->transformation();
}
/* [SceneData-usage-mutable] */
}
{
const std::size_t nodeCount{}, meshAssignmentCount{};
/* [SceneData-populating] */
struct Common {
UnsignedShort object;
Short parent;
Matrix4 transformation;
};
Containers::StridedArrayView1D<Common> common;
Containers::ArrayView<UnsignedShort> meshMaterialMapping;
Containers::ArrayView<UnsignedShort> meshes;
Containers::ArrayView<UnsignedShort> meshMaterials;
Containers::Array<char> data = Containers::ArrayTuple{
{nodeCount, common},
{meshAssignmentCount, meshMaterialMapping},
{meshAssignmentCount, meshes},
{meshAssignmentCount, meshMaterials}
};
// populate the views ...
Trade::SceneData scene{
Trade::SceneMappingType::UnsignedShort, nodeCount,
std::move(data), {
Trade::SceneFieldData{Trade::SceneField::Parent,
common.slice(&Common::object), common.slice(&Common::parent)},
Trade::SceneFieldData{Trade::SceneField::Transformation,
common.slice(&Common::object), common.slice(&Common::transformation)},
Trade::SceneFieldData{Trade::SceneField::Mesh,
meshMaterialMapping, meshes},
Trade::SceneFieldData{Trade::SceneField::MeshMaterial,
meshMaterialMapping, meshMaterials}
}};
/* [SceneData-populating] */
}
{
std::size_t nodeCount{};
/* [SceneData-populating-custom1] */
DOXYGEN_ELLIPSIS()
Containers::ArrayView<UnsignedShort> cellMapping;
Containers::ArrayView<Matrix4> cellFrustums;
Containers::StridedArrayView2D<Int> cellLights;
Containers::Array<char> data = Containers::ArrayTuple{
DOXYGEN_ELLIPSIS()
{32*24, cellMapping},
{32*24, cellFrustums},
{{32*24, 8}, cellLights},
};
for(std::size_t i = 0; i != cellMapping.size(); ++i) {
cellMapping[i] = nodeCount + i;
cellFrustums[i] = DOXYGEN_ELLIPSIS({});
for(std::size_t j = 0; j != cellLights[i].size(); ++j)
cellLights[i][j] = DOXYGEN_ELLIPSIS({});
}
/* [SceneData-populating-custom1] */
/* [SceneData-populating-custom2] */
constexpr Trade::SceneField CellFrustum = Trade::sceneFieldCustom(0x00);
constexpr Trade::SceneField CellLights = Trade::sceneFieldCustom(0x01);
Trade::SceneData scene{
Trade::SceneMappingType::UnsignedShort, nodeCount + cellMapping.size(),
std::move(data), {
DOXYGEN_ELLIPSIS()
Trade::SceneFieldData{CellFrustum, cellMapping, cellFrustums},
Trade::SceneFieldData{CellLights, cellMapping, cellLights},
}};
/* [SceneData-populating-custom2] */
}
{
constexpr Trade::SceneField CellFrustum = Trade::sceneFieldCustom(0);
constexpr Trade::SceneField CellLights = Trade::sceneFieldCustom(1);
Trade::SceneData scene{{}, 0, nullptr, nullptr};
/* [SceneData-populating-custom-retrieve] */
Containers::StridedArrayView1D<const Matrix4> cellFrustums =
scene.field<Matrix4>(CellFrustum);
Containers::StridedArrayView2D<const Int> cellLights =
scene.field<Int[]>(CellLights);
/* [SceneData-populating-custom-retrieve] */
static_cast<void>(cellFrustums);
static_cast<void>(cellLights);
}
}

7
doc/snippets/README.md

@ -14,12 +14,13 @@ smaller file sizes:
The output printed by the application can be used to update the example output
in `doc/getting-started.dox`.
### triangulate.svg
### triangulate.svg, scenedata-tree.svg, scenedata-dod.svg
Created by Inkscape from `doc/artwork/triangulate.svg` by saving as Optimized
SVG and:
- cleaning up the `<svg>` header
- cleaning up the `<svg>` header (removing `version`, `xmlns`)
- converting to a `style=""`, *keeping* `viewBox`
- adding `class="m-image"`
- removing metadata and the background layer
- removing metadata, the background layer and all layers that have
`display: none`

148
doc/snippets/scenedata-dod.svg

@ -0,0 +1,148 @@
<svg class="m-image" style="width: 530px; height: 240px;" viewBox="0 0 140.23 63.5">
<g transform="translate(-1.3229 -1.3229)" stroke-width=".5">
<g transform="matrix(2 0 0 2 -67.469 -96.573)">
<rect x="37.042" y="63.5" width="15.875" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="40.784985" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" style="line-height:1.25" xml:space="preserve"><tspan x="40.784985" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">materials</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -67.469 -78.052)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">skins</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -67.469 -109.8)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">meshes</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -67.469 -107.16)">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transforms</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -67.469 -125.68)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">parents</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -67.469 -93.927)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.926247" y="68.158577" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.926247" y="68.158577" stroke-width=".13229"><tspan x="44.926247" y="68.158577" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">lights</tspan></tspan></text>
</g>
<g transform="matrix(2 0 0 2 -67.469 -85.99)">
<path d="m37.042 66.146h15.875v2.6458h-15.875z" fill="#747474" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">cameras</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -34.396 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">7</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -23.813 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">1</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -13.229 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">0</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -2.6458 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">5</tspan></text>
</g>
<g transform="matrix(2 0 0 2 7.9375 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">3</tspan></text>
</g>
<g transform="matrix(2 0 0 2 18.521 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">6</tspan></text>
</g>
<g transform="matrix(2 0 0 2 29.104 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">2</tspan></text>
</g>
<g transform="matrix(2 0 0 2 39.687 -125.68)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">4</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -30.427 -107.16)">
<rect x="37.042" y="60.854" width="9.2604" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.68034" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.68034" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">1</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -11.906 -107.16)">
<rect x="37.042" y="60.854" width="9.2604" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.68034" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.68034" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">0</tspan></text>
</g>
<g transform="matrix(2 0 0 2 6.6146 -107.16)">
<rect x="37.042" y="60.854" width="9.2604" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.68034" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.68034" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">5</tspan></text>
</g>
<g transform="matrix(2 0 0 2 25.135 -107.16)">
<rect x="37.042" y="60.854" width="9.2604" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.68034" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.68034" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">6</tspan></text>
</g>
<g transform="matrix(2 0 0 2 43.656 -107.16)">
<rect x="37.042" y="60.854" width="9.2604" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.68034" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.68034" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">2</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -30.427 -85.99)">
<path d="m37.042 66.146h2.6458v2.6458h-2.6458z" fill="#747474" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="38.349766" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.349766" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">1</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -30.427 -93.927)">
<path d="m37.042 66.146h2.6458v2.6458h-2.6458z" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="38.349766" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.349766" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">1</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -30.427 -78.052)">
<path d="m37.042 66.146h2.6458v2.6458h-2.6458z" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="38.349766" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.349766" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">5</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -25.135 -93.927)">
<path d="m37.042 66.146h2.6458v2.6458h-2.6458z" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="38.349766" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.349766" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">0</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -19.844 -93.927)">
<path d="m37.042 66.146h2.6458v2.6458h-2.6458z" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="38.349766" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.349766" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">4</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -30.427 -96.573)">
<rect x="37.042" y="63.5" width="3.9687" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="42.993736" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.973122" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">5</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -22.49 -96.573)">
<rect x="37.042" y="63.5" width="3.9687" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="42.993736" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.973122" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">6</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -14.552 -96.573)">
<rect x="37.042" y="63.5" width="3.9687" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="42.993736" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.973122" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">3</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -6.6146 -96.573)">
<rect x="37.042" y="63.5" width="3.9687" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="42.993736" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.973122" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">2</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -34.396 -109.8)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">5</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -23.813 -109.8)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">6</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -13.229 -109.8)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">3</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -2.6458 -109.8)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">2</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -25.135 -78.052)">
<path d="m37.042 66.146h2.6458v2.6458h-2.6458z" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="38.349766" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.349766" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">2</tspan></text>
</g>
<g transform="matrix(2 0 0 2 7.9375 -109.8)">
<rect x="39.026" y="66.146" width="5.2917" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="-inkscape-stroke:none;font-variation-settings:normal"/>
<text x="41.618961" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="41.618961" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">6</tspan></text>
</g>
<g transform="matrix(2 0 0 2 1.3229 -96.573)">
<rect x="37.042" y="63.5" width="3.9687" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="42.993736" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="38.973122" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">6</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 27 KiB

255
doc/snippets/scenedata-tree.svg

@ -0,0 +1,255 @@
<svg class="m-image" style="width: 620px; height: 440px" viewBox="0 0 164.04 116.42">
<g transform="translate(-6.6146 -39.687)" display="none" fill="none" stroke-width=".39688">
<g stroke="#c7cf2f">
<path d="m31.75 93.927c8.4877 0.10627-3.0463-18.647 5.2917-18.521"/>
<path d="m52.917 75.406c8.4877 0.10627-3.0463-12.032 5.2917-11.906"/>
<path d="m31.75 62.177c8.4877 0.10627 18.12 1.1971 26.458 1.3229"/>
<path d="m31.75 62.177c8.4877 0.10627-3.0463 13.103 5.2917 13.229"/>
<path d="m15.875 62.177c-10.062 0.0058-8.338 31.624 4e-6 31.75"/>
<path d="m74.083 63.5c12.343 0.023409-26.975 30.498-42.333 30.427"/>
</g>
<g stroke="#3bd267">
<path d="m52.917 72.76c8.4877 0.10627 7.0188-6.5655 0-6.6146" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m52.917 72.76c8.4877 0.10627 7.7839-2.6664 0-2.6458" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m52.917 72.76c8.4877 0.10627 7.0188 5.3407 0 5.2917"/>
</g>
<g stroke="#747474">
<path d="m37.042 72.76c-11.059 0.040797 1.7271-13.18-5.2917-13.229" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m51.594 92.604c-11.059 0.040797-12.825-33.024-19.844-33.073" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m70.115 82.021c-11.059 0.040797-31.346-22.441-38.365-22.49" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
<g stroke="#3bd267">
<path d="m52.917 72.76c8.4877 0.10627 8.5948-27.6 1.5761-27.649" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m85.99 82.021c8.4877 0.10627-24.478-36.86-31.497-36.909" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m85.99 82.021c8.4877 0.10627-26.054-15.826-33.073-15.875" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m85.99 82.021c8.4877 0.10627 7.0188-2.5968 0-2.6458" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m85.99 82.021c8.4877 0.10627 7.0188-6.5655 0-6.6146" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m67.469 92.604c8.4877 0.10627 7.0188-6.5655 4e-6 -6.6146" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m67.469 92.604c8.4877 0.10627 7.0188-2.5968 0-2.6458" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m67.469 92.604c8.4877 0.10627-7.5333-26.409-14.552-26.458" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m67.469 92.604c8.4877 0.10627 7.0188 2.6949 0 2.6458" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m67.469 92.604c8.4877 0.10627-5.9573-47.444-12.976-47.493" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
<g stroke="#747474">
<path d="m31.75 59.531c8.4877 0.10627 29.761-14.371 22.743-14.42" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m31.75 59.531c8.4877 0.10627 7.0188-3.9197 4e-6 -3.9688" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m70.115 82.021c-11.059 0.040797-31.346-22.441-38.365-22.49" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
<g stroke="#c7cf2f">
<path d="m31.75 55.562c8.4877 0.10627 7.0188 6.6636-8e-6 6.6146" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m31.75 89.958c8.4877 0.10627 7.0188 4.0178-4e-6 3.9688" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m52.917 66.146c8.4877 0.10627 7.0188 9.3095 0 9.2604" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m74.083 59.531c8.4877 0.10627 7.0188 4.0178 0 3.9687" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m37.042 66.146c-15.875 1e-6 1.7271 27.83-5.2917 27.781" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m38.618 45.111c-18.157 0.17354 0.15104 48.865-6.8677 48.816" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m54.493 45.111c8.4877 0.10627-6.3079 17.8 3.7156 18.389" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m38.618 45.111c-16.175 0.10989 21.318 30.344 14.299 30.295" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
</g>
<g transform="translate(-7.9375)" display="none">
<g transform="translate(-9.2604 -26.458)" display="inline">
<rect x="37.042" y="63.5" width="15.875" height="2.6458" display="inline" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<text x="41.234787" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".26458" style="line-height:1.25" xml:space="preserve"><tspan x="41.234787" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".26458" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">materials</tspan></text>
</g>
<rect x="46.302" y="37.042" width="3.9026" height="2.6458" display="inline" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<g transform="translate(-9.2604 -25.135)" display="inline">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" display="inline" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">textures</tspan></text>
</g>
<g transform="translate(-9.2604 -33.073)" display="inline">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" display="inline" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">meshes</tspan></text>
</g>
<rect x="46.302" y="33.073" width="7.8714" height="2.6458" display="inline" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<g transform="translate(-9.2604 -35.719)" display="inline">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" display="inline" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transforms</tspan></text>
</g>
<rect x="46.302" y="25.135" width="2.5797" height="2.6458" display="inline" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<g transform="translate(-9.2604 -44.979)" display="inline">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" display="inline" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">parents</tspan></text>
</g>
<rect x="46.302" y="21.167" width="2.5797" height="2.6458" display="inline" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<g transform="translate(-9.2604 -37.042)" display="inline">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" display="inline" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<text x="44.926247" y="68.158577" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.926247" y="68.158577" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">physics</tspan></text>
</g>
<g transform="translate(-9.2604 -51.594)" display="inline">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" display="inline" fill="#747474" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".13229" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">camera</tspan></text>
</g>
<g fill="#c7cf2f" fill-rule="evenodd" stroke="#2f363f" stroke-width=".13229">
<rect x="46.335" y="29.104" width="5.2255" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="51.627" y="29.104" width="5.2255" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="62.243" y="29.104" width="5.2255" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="56.918" y="29.104" width="5.2255" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
<g fill="#2f83cc" fill-rule="evenodd" stroke="#2f363f" stroke-width=".13229">
<rect x="49.014" y="21.167" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="51.66" y="21.167" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="54.306" y="21.167" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="56.918" y="21.167" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="56.918" y="21.167" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
<g fill="#a5c9ea" fill-rule="evenodd" stroke="#2f363f" stroke-width=".13229">
<rect x="49.014" y="25.135" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="51.627" y="25.135" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="54.306" y="25.135" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="56.952" y="25.135" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="59.597" y="25.135" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="62.243" y="25.135" width="2.5797" height="2.6458" display="inline" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
<g fill-rule="evenodd" stroke="#2f363f" stroke-width=".13229">
<rect x="59.531" y="21.167" width="2.5797" height="2.6458" display="inline" fill="#2f83cc" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="54.306" y="33.073" width="7.8714" height="2.6458" display="inline" fill="#3bd267" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="62.21" y="33.073" width="7.8714" height="2.6458" display="inline" fill="#3bd267" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="49.642" y="37.042" width="3.9026" height="2.6458" display="inline" fill="#cd3431" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="52.983" y="37.042" width="3.9026" height="2.6458" display="inline" fill="#cd3431" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="46.302" y="41.01" width="10.517" height="2.6458" display="inline" fill="#2f83cc" stop-color="#000000" style="font-variation-settings:normal"/>
<rect x="56.918" y="41.01" width="10.517" height="2.6458" display="inline" fill="#2f83cc" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
</g>
<g transform="matrix(1.8788 0 0 1.913 -12.427 -75.924)" stroke-width=".52747">
<rect x="6.6146" y="39.687" width="87.312" height="60.854" fill="#2f363f" stop-color="#000000"/>
</g>
<g transform="matrix(2 0 0 2 -13.229 -79.375)" fill="none" stroke="#2f83cc" stroke-width=".066146">
<path d="m44.979 64.823c-0.04047 7.8835 32.952 0.94798 33.073 9.1281" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m44.979 64.823c-0.04047 7.8835 14.431 11.664 14.552 19.844" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m44.979 64.823c-0.04047 7.8835-21.287 15.5-21.167 23.68" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m23.813 54.24c-0.04047 7.8835-6.7353 12.987-6.6146 21.167" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m46.555 43.656c-0.04047 7.8835 19.47 6.2397 19.591 14.42" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m46.555 43.656c-0.04047 7.8835-22.863 2.4032-22.743 10.583" stop-color="#000000" style="font-variation-settings:normal"/>
<path d="m46.555 43.656c-0.04047 7.8835-1.6968 12.987-1.5761 21.167" stop-color="#000000" style="font-variation-settings:normal"/>
</g>
<g transform="matrix(2 0 0 2 -13.229 -66.146)">
<rect x="37.042" y="63.5" width="15.875" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.234787" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" style="line-height:1.25" xml:space="preserve"><tspan x="41.234787" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">material</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -13.229 -76.729)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">mesh</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -13.229 -66.146)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">skin</tspan></text>
</g>
<g transform="matrix(2 0 0 2 52.917 -47.625)">
<rect x="37.042" y="63.5" width="15.875" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.234787" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" style="line-height:1.25" xml:space="preserve"><tspan x="41.234787" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">material</tspan></text>
</g>
<g transform="matrix(2 0 0 2 52.917 -58.208)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">mesh</tspan></text>
</g>
<g transform="matrix(2 0 0 2 29.104 -89.958)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.926247" y="68.158577" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.926247" y="68.158577" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">light</tspan></text>
</g>
<g transform="matrix(2 0 0 2 15.875 -26.458)">
<rect x="37.042" y="63.5" width="15.875" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.234787" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" style="line-height:1.25" xml:space="preserve"><tspan x="41.234787" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">material</tspan></text>
</g>
<g transform="matrix(2 0 0 2 15.875 -37.042)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">mesh</tspan></text>
</g>
<g transform="matrix(2 0 0 2 15.875 -26.458)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#2f83cc" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">skin</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -55.629 -29.104)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.926247" y="68.158577" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.926247" y="68.158577" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">light</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -55.563 -97.896)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#747474" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">camera</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -55.563 -92.604)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#c7cf2f" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.926247" y="68.158577" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.926247" y="68.158577" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">light</tspan></text>
</g>
<g transform="matrix(2 0 0 2 29.104 -84.667)">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -68.792 -50.271)" opacity=".25">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" opacity="1" stop-color="#000000" stroke="#a5c9ea" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
<g transform="matrix(2 0 0 2 52.917 -52.917)">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
<g transform="matrix(2 0 0 2 15.875 -31.75)">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -55.563 -66.146)" stroke-width=".5">
<g transform="translate(21.167 -2.6458)">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
</g>
<g transform="matrix(2 0 0 2 -55.562 -92.604)">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -68.792 -55.563)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">mesh</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -10.583 -113.77)" opacity=".25">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" opacity="1" stop-color="#000000" stroke="#a5c9ea" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -55.563 -23.813)" opacity=".25">
<rect x="37.042" y="60.854" width="15.875" height="2.6458" fill="#a5c9ea" fill-rule="evenodd" opacity="1" stop-color="#000000" stroke="#a5c9ea" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="45.033138" y="62.930618" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="45.033138" y="62.930618" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">transform</tspan></text>
</g>
<g transform="matrix(2 0 0 2 -68.858 -44.979)">
<rect x="37.042" y="63.5" width="15.875" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="41.234787" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" style="line-height:1.25" xml:space="preserve"><tspan x="41.234787" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">material</tspan></text>
</g>
<g transform="translate(-5.353e-7 2.8443)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">3</tspan></text>
</g>
<g transform="translate(55.562 -18.322)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">5</tspan></text>
</g>
<g transform="translate(58.737 -60.656)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">7</tspan></text>
</g>
<g transform="translate(97.896 -31.552)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">0</tspan></text>
</g>
<g transform="translate(121.71 .19843)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">6</tspan></text>
</g>
<g transform="translate(84.667 21.365)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">2</tspan></text>
</g>
<g transform="translate(13.229 -39.489)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">1</tspan></text>
</g>
<g transform="translate(13.229 29.303)">
<path transform="scale(.26458)" d="m80 240.25c-6.525 0-11.825 5.2458-11.912 11.75v7h23.824v-7c-0.0876-6.5042-5.3871-11.75-11.912-11.75z" fill="#2f83cc" stop-color="#000000" stroke="#2f363f" stroke-width=".5" style="font-variation-settings:normal"/>
<text x="21.217466" y="67.397049" fill="#000000" font-family="sans-serif" font-size="21.167px" stroke-width=".26458" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="21.217466" y="67.397049" font-family="'Source Sans Pro'" font-size="4.2333px" stroke-width=".26458" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">4</tspan></text>
</g>
<g transform="matrix(2 0 0 2 52.851 -37.042)">
<rect x="37.042" y="63.5" width="15.875" height="2.6458" fill="#cd3431" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="49.767071" y="65.563751" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.940006" y="65.563751" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">material #2</tspan></text>
</g>
<g transform="matrix(2 0 0 2 52.851 -47.625)">
<rect x="37.042" y="66.146" width="15.875" height="2.6458" fill="#3bd267" fill-rule="evenodd" stop-color="#000000" stroke="#2f363f" stroke-width=".066146" style="font-variation-settings:normal"/>
<text x="44.968582" y="68.209587" fill="#000000" font-family="sans-serif" font-size="10.583px" stroke-width=".13229" text-align="center" text-anchor="middle" style="line-height:1.25" xml:space="preserve"><tspan x="44.968582" y="68.209587" font-family="'Source Sans Pro'" font-size="2.1167px" stroke-width=".13229" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">mesh #2</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 39 KiB

273
src/Magnum/Trade/SceneData.h

@ -533,6 +533,28 @@ MAGNUM_TRADE_EXPORT UnsignedInt sceneFieldTypeAlignment(SceneFieldType type);
Convenience type for populating @ref SceneData, see its documentation for an
introduction.
@section Trade-SceneFieldData-usage Usage
The most straightforward usage is constructing an instance from a
@ref SceneField and a strided view for the field data and object mapping. The
@ref SceneMappingType and @ref SceneFieldType get inferred from the view types:
@snippet MagnumTrade.cpp SceneFieldData-usage
Alternatively, you can pass typeless @cpp const void @ce or 2D views and supply
@ref SceneMappingType and @ref SceneFieldType explicitly.
@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:
@snippet MagnumTrade.cpp SceneFieldData-usage-offset-only
*/
class MAGNUM_TRADE_EXPORT SceneFieldData {
public:
@ -779,8 +801,255 @@ Containers::Array<SceneFieldData> MAGNUM_TRADE_EXPORT sceneFieldDataNonOwningArr
/**
@brief Scene data
Contains scene hierarchy, object transformations and association of mesh,
material, camera, light and other resources with particular objects.
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().
@section Trade-SceneData-representation Data representation and terminology
@m_div{m-container-inflate m-col-l-9 m-left-l}
@htmlinclude scenedata-tree.svg
@m_enddiv
The usual mental image of a scene is a tree hierarchy with varying amount of
data attached to each node, like shown in the first diagram. The @ref SceneData
however decouples the hierarchy from the data and stores everything in linear
arrays, like in the second diagram.
This allows for a more efficient storage, as only the actually needed
information is stored. For example, three nodes in the tree have an implicit
transformation, which we can simply omit, or because there might be way less
materials than meshes, their references can be in a smaller type. It's also
more flexible --- having multiple meshes per node is just about having multiple
entries associated with the same node.
@m_div{m-clearfix-l} @m_enddiv
@m_div{m-container-inflate m-col-l-8 m-right-l}
@htmlinclude scenedata-dod.svg
@m_enddiv
From a high-level perspective, the scene data storage can thought of as a set
of *Fields*, with field entries mapped to *Objects*. Scene *Nodes* are a
special case of *Objects*.
An *Object* is an arbitrary numeric identifier, not containing anything on its
own. All objects referenced by a particular scene are contained in a range from
@cpp 0 @ce up to @ref mappingBound() minus one. The range is allowed to be
sparse.
A *Field* is a list of data --- for example transformations, mesh IDs, or
parent objects. The @ref SceneField enum lists all predefined fields together
with possible restrictions and the expected @ref SceneFieldType they're
expected to be in. Custom fields are supported as well. Field entries are
mapped to objects with the same 8-, 16-, 32- or 64-bit type for all fields,
indicated with @ref SceneMappingType. Generally there's a 1:N mapping between
objects and fields (not all objects need to have a transformation, a single
object can reference multiple meshes...), but certain field types expect
various restrictions (such as an object allowed to only have one parent or
transformation).
Finally, scene *Nodes* are *Objects* that have the @ref SceneField::Parent
field associated. An *Object* thus doesn't have to represent just a node in the
hierarchy. For example, a scene can also contain an alternative representation
in the form of an octree, and thus some objects would be nodes and some octree
cells.
@subsection Trade-SceneData-representation-multi-scene Object identifiers and multiple scenes
For a standalone scene, a common case is that the object identifiers form a
contigous range of numbers, and each of the objects has at least one field
assigned.
The @ref AbstractImporter supports files with multiple scenes. All imported
scenes share a single object range, from @cpp 0 @ce to
@ref AbstractImporter::objectCount(). A particular object can be part of any of
the scenes, causing the @ref SceneData::mappingBound() ranges to be sparse ---
a particular scene having certain object IDs that have no fields assigned. This
is something to be aware of when consuming the scene data, that not all objects
identifiers in the mapping range may actually exist.
It's also possible for a single object identifier to be contained in multiple
scenes at the same time --- for example, when two scenes are variants of the
same model, with most data shared but certain textures or colors different.
Another theoretical use case is that an object could identify a building in a
3D scene and a corresponding area on a map in a 2D scene. There's no set of
rules the objects should follow, but such identifier reusal should not be
abused for completely unrelated objects.
@todoc mention handles and how they would affect the basic use below (aaaa!)
@section Trade-SceneData-usage Basic usage
A simple goal could be to populate a @ref SceneGraph with a node hierarchy
and attach drawables for meshes where appropriate. First we check if the scene
is 3D with @ref is3D(), because if it's not, it could mean it's either 2D or
that it has no transformation field altogether, suggesting a need for
specialized handling. It's also of no use for this example if there's no node
hierarchy, or if there are no meshes we could draw.
Then we create the scene instance and an array of pointers that will act as a
map from object identifiers to live objects. The @ref mappingBound() is an
upper bound to all object identifiers referenced by the scene, but as mentioned
above, not all of them may be actual nodes so we don't allocate actual scene
graph object instances for them yet. Alternatively, for very sparse ranges, a hashmap could be also used here.
@snippet MagnumTrade.cpp SceneData-usage1
<b></b>
@m_class{m-noindent}
Next we go through objects that have an associated parent using
@ref parentsAsArray(). Those are the actual nodes we want, so we allocate a
scene graph object for each ...
@snippet MagnumTrade.cpp SceneData-usage2
@m_class{m-noindent}
<b></b>
... and then we assign a proper parent, or add it directly to the scene if the
parent is @cpp -1 @ce. We do this in a separate pass to ensure the parent
object is already allocated by the time we pass it to
@ref SceneGraph::Object::setParent() --- generally there's no guarantee that a
parent appears in the field before its children.
@snippet MagnumTrade.cpp SceneData-usage3
With the hierarchy done, we assign transformations. The transformation field
can be present for only a subset of the nodes, with the rest implicitly having
an indentity transformation, but it can also be present for objects that aren't
nodes, so we only set it for objects present in our hierarchy. The
@ref transformations3DAsArray() function also conveniently converts separate
transformation / rotation / scaling fields into a matrix for us, if the scene
contains only those.
@snippet MagnumTrade.cpp SceneData-usage4
Finally, assuming there's a `Drawable` class derived from
@ref SceneGraph::Drawable that accepts a mesh and material ID (retrieving them
subsequently from @ref AbstractImporter::mesh() /
@relativeref{AbstractImporter,material()}, for example), the process of
assigning actual meshes to corresponding scene nodes is just another
@cpp for @ce loop over @ref meshesMaterialsAsArray():
@snippet MagnumTrade.cpp SceneData-usage5
<b></b>
@m_class{m-note m-success}
@par
The full process of importing a scene including meshes, materials and
textures is shown in the @ref examples-viewer example.
@section Trade-SceneData-usage-advanced Advanced usage
The @ref parentsAsArray(), ... functions shown above always return a
newly-allocated @relativeref{Corrade,Containers::Array} instance in a
well-defined canonical type. While that's convenient and fine at a smaller
scale, it may prove problematic with huge scenes. Or maybe the internal
representation is already optimized for best processing efficiency and the
convenience functions would ruin that. The @ref SceneData class thus provides
access directly to the stored object mapping and field data using the
@ref mapping() and @ref field() accessors.
However, since each @ref SceneField can be in a variety of types, you're
expected to either check that the type is indeed what you expect using
@ref fieldType(SceneField) const, or at least check with documentation of the
corresponding importer. For example, because glTF files represent the scene
in a textual form, @ref CgltfImporter will always parse the data into canonical
32-bit types. With that assumption, the above snippet that used
@ref transformations3DAsArray() can be rewritten to a zero-copy form like this:
@snippet MagnumTrade.cpp SceneData-usage-advanced
@section Trade-SceneData-usage-per-object Per-object access
While the designated way to access scene data is by iterating through the field
and object arrays, it's also possible to directly look at fields for a
particular object without having to do a lookup on your own and with simplified
error handling. The @ref parentFor(), @ref childrenFor(),
@ref transformation3DFor(), @ref meshesMaterialsFor() and other functions
return either an @relativeref{Corrade,Containers::Optional} or an
@relativeref{Corrade,Containers::Array} depending on whether there's expected
just one occurence of the field or more, returning an empty optional or array
if the field is not present in the scene or if the object was not found in the
field array.
For example, together with an @ref AbstractImporter instance the scene comes
from, the following snippet lists meshes and material names that are associated
with a "Chair" object, assuming such object exists:
@snippet MagnumTrade.cpp SceneData-per-object
Since these APIs perform a linear lookup through the field and object arrays,
these are suited mainly for introspection and debugging purposes. Retrieving
field data for many objects is better achieved by accessing the field data
directly.
@section Trade-SceneData-usage-mutable Mutable data access
The interfaces implicitly provide @cpp const @ce views on the contained object
and field data through the @ref data(), @ref mapping() and @ref field()
accessors. This is done because in general case the data can also refer to a
memory-mapped file or constant memory. In cases when it's desirable to modify
the data in-place, there's the @ref mutableData(), @ref mutableMapping() and
@ref mutableField() set of functions. To use these, you need to check that
the data are mutable using @ref dataFlags() first. The following snippet
updates all transformations with the live state of a scene imported earlier,
for example in order to bake in a certain animation state:
@snippet MagnumTrade.cpp SceneData-usage-mutable
@section Trade-SceneData-populating Populating an instance
The actual data in a @ref SceneData instance are represented as a single block
of contiguous memory, which all object and field views point to. This is
easiest to achieve with an @relativeref{Corrade,Containers::ArrayTuple}. In the
example below, all objects have a parent and a transformation field, which are
stored together in a @cpp struct @ce, while a subset of them has a mesh and a
material assigned, which are stored in separate arrays. And because the scene
is small, we save space by using just 16-bit indices for everything.
@snippet MagnumTrade.cpp SceneData-populating
Note that the above layout is just an example, you're free to choose any
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-custom Custom scene fields and non-node objects
Let's say that, in addition to the node hierarchy from above, our scene
contains also a precomputed [camera-space light culling grid](https://wickedengine.net/2018/01/10/optimizing-tile-based-light-culling/),
where each cell of the grid contains a list of lights that affect given area of
the screen. And we want to add it into the @ref SceneData for verification with
external tools.
For simplicity let's assume we have a 32x24 grid and the shader we have can
work with up to 8 lights. So there will be a fixed-size array for each of those
cells, and we save calculated frustums for inspection as well. For the new data
we allocate object IDs from a range after `nodeCount`, and copy in the actual
data.
@snippet MagnumTrade.cpp SceneData-populating-custom1
Then, similarly as with @ref MeshData, the scene can have custom fields as
well, created with @ref sceneFieldCustom(). We create one for the cell light
reference array and one for the cell frustum and then use them to annotate
the views allocated above. Note that we also increased the total object count
to include the light culling grid cells as well.
@snippet MagnumTrade.cpp SceneData-populating-custom2
Later, the fields can be retrieved back using the same custom identifiers.
The light references are actually a 2D array (8 lights for each cell), so a
@cpp [] @ce needs to be used:
@snippet MagnumTrade.cpp SceneData-populating-custom-retrieve
@see @ref AbstractImporter::scene()
*/

Loading…
Cancel
Save