Browse Source

Trade: rename SceneData "objects" to "mapping".

Now it's a field and its corresponding object mapping, instead of
field and "objects":

 - Goes better with the concept that there's not really any materialized
   "object" anywhere, just fields mapped to them.
 - No more weird singular/plural difference between field() and
   objects(), it's field() and mapping() now.
 - The objectCount() that actually wasn't really object count is now a
   mappingBound(), an upper bound for object IDs contained in the object
   mapping views. Which is quite self-explanatory without having to
   mention every time that the range may be sparse.
pull/525/head
Vladimír Vondruš 4 years ago
parent
commit
5df37d2934
  1. 4
      doc/changelog.dox
  2. 10
      src/Magnum/MeshTools/sceneconverter.cpp
  3. 18
      src/Magnum/Trade/AbstractImporter.cpp
  4. 75
      src/Magnum/Trade/Implementation/sceneTools.h
  5. 549
      src/Magnum/Trade/SceneData.cpp
  6. 498
      src/Magnum/Trade/SceneData.h
  7. 98
      src/Magnum/Trade/Test/AbstractImporterTest.cpp
  8. 1640
      src/Magnum/Trade/Test/SceneDataTest.cpp
  9. 210
      src/Magnum/Trade/Test/SceneToolsTest.cpp
  10. 2
      src/Magnum/Trade/Trade.h

4
doc/changelog.dox

@ -634,7 +634,7 @@ See also:
etc. etc.
- @ref Trade::SceneData constructor taking a @ref std::vector of 2D and 3D - @ref Trade::SceneData constructor taking a @ref std::vector of 2D and 3D
children is deprecated in favor of the new scene representation. Use children is deprecated in favor of the new scene representation. Use
@ref Trade::SceneData::SceneData(SceneObjectType, UnsignedLong, Containers::Array<char>&&, Containers::Array<SceneFieldData>&&, const void*) @ref Trade::SceneData::SceneData(SceneMappingType, UnsignedLong, Containers::Array<char>&&, Containers::Array<SceneFieldData>&&, const void*)
instead. instead.
- @cpp Trade::SceneData::children2D() @ce and - @cpp Trade::SceneData::children2D() @ce and
@cpp Trade::SceneData::children3D() @ce are deprecated in favor of the @cpp Trade::SceneData::children3D() @ce are deprecated in favor of the
@ -828,7 +828,7 @@ See also:
desired use case anymore. desired use case anymore.
- @ref Trade::SceneData constructor taking a @ref std::vector of 2D and 3D - @ref Trade::SceneData constructor taking a @ref std::vector of 2D and 3D
children that got deprecated in favor of children that got deprecated in favor of
@ref Trade::SceneData::SceneData(SceneObjectType, UnsignedLong, Containers::Array<char>&&, Containers::Array<SceneFieldData>&&, const void*) @ref Trade::SceneData::SceneData(SceneMappingType, UnsignedLong, Containers::Array<char>&&, Containers::Array<SceneFieldData>&&, const void*)
no longer accepts a scene that has both 2D and 3D children. no longer accepts a scene that has both 2D and 3D children.
- The deprecated @cpp Trade::AbstractImporter::object*DCount() @ce, - The deprecated @cpp Trade::AbstractImporter::object*DCount() @ce,
@cpp Trade::AbstractImporter::object*DForName() @ce, @cpp Trade::AbstractImporter::object*DForName() @ce,

10
src/Magnum/MeshTools/sceneconverter.cpp

@ -386,8 +386,8 @@ used.)")
struct SceneInfo { struct SceneInfo {
UnsignedInt scene; UnsignedInt scene;
Trade::SceneObjectType objectType; Trade::SceneMappingType mappingType;
UnsignedLong objectCount; UnsignedLong mappingBound;
Containers::Array<SceneFieldInfo> fields; Containers::Array<SceneFieldInfo> fields;
std::size_t dataSize; std::size_t dataSize;
std::string name; std::string name;
@ -410,8 +410,8 @@ used.)")
SceneInfo info{}; SceneInfo info{};
info.scene = i; info.scene = i;
info.objectType = scene->objectType(); info.mappingType = scene->mappingType();
info.objectCount = scene->objectCount(); info.mappingBound = scene->mappingBound();
info.dataSize = scene->data().size(); info.dataSize = scene->data().size();
info.name = importer->sceneName(i); info.name = importer->sceneName(i);
for(UnsignedInt j = 0; j != scene->fieldCount(); ++j) { for(UnsignedInt j = 0; j != scene->fieldCount(); ++j) {
@ -666,7 +666,7 @@ used.)")
d << "Scene" << info.scene << Debug::nospace << ":"; d << "Scene" << info.scene << Debug::nospace << ":";
if(!info.name.empty()) d << info.name; if(!info.name.empty()) d << info.name;
d << Debug::newline; d << Debug::newline;
d << " " << info.objectCount << "objects," << info.objectType d << " bound:" << info.mappingBound << "objects," << info.mappingType
<< "(" << Debug::nospace << Utility::formatString("{:.1f}", info.dataSize/1024.0f) << "kB)"; << "(" << Debug::nospace << Utility::formatString("{:.1f}", info.dataSize/1024.0f) << "kB)";
for(const SceneFieldInfo& field: info.fields) { for(const SceneFieldInfo& field: info.fields) {

18
src/Magnum/Trade/AbstractImporter.cpp

@ -538,13 +538,13 @@ void AbstractImporter::populateCachedScenes() {
except for the above, also because it doesn't take into account except for the above, also because it doesn't take into account
the restriction for unique-functioning objects. */ the restriction for unique-functioning objects. */
if(_cachedScenes->scenes[i]->is2D()) if(_cachedScenes->scenes[i]->is2D())
_cachedScenes->object2DCount = Math::max(_cachedScenes->object2DCount, UnsignedInt(_cachedScenes->scenes[i]->objectCount())); _cachedScenes->object2DCount = Math::max(_cachedScenes->object2DCount, UnsignedInt(_cachedScenes->scenes[i]->mappingBound()));
if(_cachedScenes->scenes[i]->is3D()) if(_cachedScenes->scenes[i]->is3D())
_cachedScenes->object3DCount = Math::max(_cachedScenes->object3DCount, UnsignedInt(_cachedScenes->scenes[i]->objectCount())); _cachedScenes->object3DCount = Math::max(_cachedScenes->object3DCount, UnsignedInt(_cachedScenes->scenes[i]->mappingBound()));
/* Ensure the newly added objects for each scene don't overlap each /* Ensure the newly added objects for each scene don't overlap each
other */ other */
newObjectOffset = Math::max(newObjectOffset, _cachedScenes->scenes[i]->objectCount()); newObjectOffset = Math::max(newObjectOffset, _cachedScenes->scenes[i]->mappingBound());
} }
} }
@ -618,7 +618,7 @@ std::string AbstractImporter::doObject2DName(const UnsignedInt id) {
for(UnsignedInt i = 0; i != _cachedScenes->scenes.size(); ++i) { for(UnsignedInt i = 0; i != _cachedScenes->scenes.size(); ++i) {
if(!_cachedScenes->scenes[i] || if(!_cachedScenes->scenes[i] ||
!_cachedScenes->scenes[i]->is2D() || !_cachedScenes->scenes[i]->is2D() ||
_cachedScenes->scenes[i]->objectCount() <= id) _cachedScenes->scenes[i]->mappingBound() <= id)
continue; continue;
if(Containers::Optional<Int> parent = _cachedScenes->scenes[i]->parentFor(id)) if(Containers::Optional<Int> parent = _cachedScenes->scenes[i]->parentFor(id))
@ -643,7 +643,7 @@ Containers::Pointer<ObjectData2D> AbstractImporter::doObject2D(const UnsignedInt
populateCachedScenes(); populateCachedScenes();
/* Find the first 2D scene with this object, which we'll detect from the /* Find the first 2D scene with this object, which we'll detect from the
object count reported for the scene, whether it's 2D or 3D, and a mapping bound reported for the scene, whether it's 2D or 3D, and a
presence of a parent attribute. If a parent attribute is not present, it presence of a parent attribute. If a parent attribute is not present, it
means the object isn't a part of this scene, in which case we skip it. means the object isn't a part of this scene, in which case we skip it.
It could also mean isn't a part of the hierarchy and is standalone It could also mean isn't a part of the hierarchy and is standalone
@ -652,7 +652,7 @@ Containers::Pointer<ObjectData2D> AbstractImporter::doObject2D(const UnsignedInt
std::size_t sceneCandidate = ~std::size_t{}; std::size_t sceneCandidate = ~std::size_t{};
for(std::size_t i = 0; i != _cachedScenes->scenes.size(); ++i) { for(std::size_t i = 0; i != _cachedScenes->scenes.size(); ++i) {
const Containers::Optional<SceneData>& scene = _cachedScenes->scenes[i]; const Containers::Optional<SceneData>& scene = _cachedScenes->scenes[i];
if(scene && scene->is2D() && id < scene->objectCount() && scene->parentFor(id)) { if(scene && scene->is2D() && id < scene->mappingBound() && scene->parentFor(id)) {
sceneCandidate = i; sceneCandidate = i;
break; break;
} }
@ -796,7 +796,7 @@ std::string AbstractImporter::doObject3DName(const UnsignedInt id) {
for(UnsignedInt i = 0; i != _cachedScenes->scenes.size(); ++i) { for(UnsignedInt i = 0; i != _cachedScenes->scenes.size(); ++i) {
if(!_cachedScenes->scenes[i] || if(!_cachedScenes->scenes[i] ||
!_cachedScenes->scenes[i]->is3D() || !_cachedScenes->scenes[i]->is3D() ||
_cachedScenes->scenes[i]->objectCount() <= id) _cachedScenes->scenes[i]->mappingBound() <= id)
continue; continue;
if(Containers::Optional<Int> parent = _cachedScenes->scenes[i]->parentFor(id)) if(Containers::Optional<Int> parent = _cachedScenes->scenes[i]->parentFor(id))
@ -821,7 +821,7 @@ Containers::Pointer<ObjectData3D> AbstractImporter::doObject3D(const UnsignedInt
populateCachedScenes(); populateCachedScenes();
/* Find the first 3D scene with this object, which we'll detect from the /* Find the first 3D scene with this object, which we'll detect from the
object count reported for the scene, whether it's 2D or 3D, and a mapping bound reported for the scene, whether it's 2D or 3D, and a
presence of a parent attribute. If a parent attribute is not present, it presence of a parent attribute. If a parent attribute is not present, it
means the object isn't a part of this scene, in which case we skip it. means the object isn't a part of this scene, in which case we skip it.
It could also mean isn't a part of the hierarchy and is standalone It could also mean isn't a part of the hierarchy and is standalone
@ -830,7 +830,7 @@ Containers::Pointer<ObjectData3D> AbstractImporter::doObject3D(const UnsignedInt
std::size_t sceneCandidate = ~std::size_t{}; std::size_t sceneCandidate = ~std::size_t{};
for(std::size_t i = 0; i != _cachedScenes->scenes.size(); ++i) { for(std::size_t i = 0; i != _cachedScenes->scenes.size(); ++i) {
const Containers::Optional<SceneData>& scene = _cachedScenes->scenes[i]; const Containers::Optional<SceneData>& scene = _cachedScenes->scenes[i];
if(scene && scene->is3D() && id < scene->objectCount() && scene->parentFor(id)) { if(scene && scene->is3D() && id < scene->mappingBound() && scene->parentFor(id)) {
sceneCandidate = i; sceneCandidate = i;
break; break;
} }

75
src/Magnum/Trade/Implementation/sceneTools.h

@ -59,29 +59,30 @@ template<class T> void sceneCombineCopyObjects(const Containers::ArrayView<const
/* If the field has null object data, no need to copy anything. This /* If the field has null object data, no need to copy anything. This
covers reserved fields but also fields of zero size. */ covers reserved fields but also fields of zero size. */
if(!fields[i].objectData()) continue; if(!fields[i].mappingData()) continue;
const Containers::StridedArrayView1D<const void> src = fields[i].objectData(); const Containers::StridedArrayView1D<const void> src = fields[i].mappingData();
const Containers::StridedArrayView1D<T> dst = Containers::arrayCast<1, T>(itemViews[mapping]); const Containers::StridedArrayView1D<T> dst = Containers::arrayCast<1, T>(itemViews[mapping]);
if(fields[i].objectType() == SceneObjectType::UnsignedByte) if(fields[i].mappingType() == SceneMappingType::UnsignedByte)
copyOrCastInto(Containers::arrayCast<const UnsignedByte>(src), dst); copyOrCastInto(Containers::arrayCast<const UnsignedByte>(src), dst);
else if(fields[i].objectType() == SceneObjectType::UnsignedShort) else if(fields[i].mappingType() == SceneMappingType::UnsignedShort)
copyOrCastInto(Containers::arrayCast<const UnsignedShort>(src), dst); copyOrCastInto(Containers::arrayCast<const UnsignedShort>(src), dst);
else if(fields[i].objectType() == SceneObjectType::UnsignedInt) else if(fields[i].mappingType() == SceneMappingType::UnsignedInt)
copyOrCastInto(Containers::arrayCast<const UnsignedInt>(src), dst); copyOrCastInto(Containers::arrayCast<const UnsignedInt>(src), dst);
else if(fields[i].objectType() == SceneObjectType::UnsignedLong) else if(fields[i].mappingType() == SceneMappingType::UnsignedLong)
copyOrCastInto(Containers::arrayCast<const UnsignedLong>(src), dst); copyOrCastInto(Containers::arrayCast<const UnsignedLong>(src), dst);
else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }
} }
/* Combine fields of varying object type together into a SceneData of a single /* Combine fields of varying mapping type together into a SceneData of a single
given objectType. The fields are expected to point to existing object/field given mappingType. The fields are expected to point to existing
memory, which will be then copied to the resulting scene. If you supply a mapping/field memory, which will be then copied to the resulting scene. If
field with null object or field data, the object or field data will not get you supply a field with null mapping or field data, the mapping or field
copied, only a placeholder for copying the data later will be allocated. If data will not get copied, only a placeholder for copying the data later will
you however need to have placeholder object data shared among be allocated. If you however need to have placeholder mapping data shared
Offset-only fields are not allowed. among multiple fields you have to allocate them upfront. Offset-only fields
are not allowed.
The resulting fields are always tightly packed (not interleaved). The resulting fields are always tightly packed (not interleaved).
@ -90,9 +91,9 @@ template<class T> void sceneCombineCopyObjects(const Containers::ArrayView<const
with different lengths will assert. */ with different lengths will assert. */
/** @todo when published, add an initializer_list overload and turn all /** @todo when published, add an initializer_list overload and turn all
internal asserts into (tested!) message asserts */ internal asserts into (tested!) message asserts */
inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLong objectCount, const Containers::ArrayView<const SceneFieldData> fields) { inline SceneData sceneCombine(const SceneMappingType mappingType, const UnsignedLong mappingBound, const Containers::ArrayView<const SceneFieldData> fields) {
const std::size_t objectTypeSize = sceneObjectTypeSize(objectType); const std::size_t mappingTypeSize = sceneMappingTypeSize(mappingType);
const std::size_t objectTypeAlignment = sceneObjectTypeAlignment(objectType); const std::size_t mappingTypeAlignment = sceneMappingTypeAlignment(mappingType);
/* Go through all fields and collect ArrayTuple allocations for these */ /* Go through all fields and collect ArrayTuple allocations for these */
std::unordered_map<const void*, UnsignedInt> objectMappings; std::unordered_map<const void*, UnsignedInt> objectMappings;
@ -110,12 +111,12 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
const SceneFieldData& field = fields[i]; const SceneFieldData& field = fields[i];
CORRADE_INTERNAL_ASSERT(!field.isOffsetOnly()); CORRADE_INTERNAL_ASSERT(!field.isOffsetOnly());
/* Object data. Allocate if the view is a placeholder of if it wasn't /* Mapping data. Allocate if the view is a placeholder of if it wasn't
used by other fields yet. */ used by other fields yet. */
std::pair<std::unordered_map<const void*, UnsignedInt>::iterator, bool> inserted; std::pair<std::unordered_map<const void*, UnsignedInt>::iterator, bool> inserted;
if(field.objectData().data()) if(field.mappingData().data())
inserted = objectMappings.emplace(field.objectData().data(), itemViewOffset); inserted = objectMappings.emplace(field.mappingData().data(), itemViewOffset);
if(field.objectData().data() && !inserted.second) { if(field.mappingData().data() && !inserted.second) {
itemViewMappings[i].first() = inserted.first->second; itemViewMappings[i].first() = inserted.first->second;
/* Expect that fields sharing the same object mapping view have the /* Expect that fields sharing the same object mapping view have the
exact same length (the length gets stored in the output view exact same length (the length gets stored in the output view
@ -145,7 +146,7 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
CORRADE_INTERNAL_ASSERT(itemViews[inserted.first->second].size()[0] == field.size()); CORRADE_INTERNAL_ASSERT(itemViews[inserted.first->second].size()[0] == field.size());
} else { } else {
itemViewMappings[i].first() = itemViewOffset; itemViewMappings[i].first() = itemViewOffset;
arrayAppend(items, InPlaceInit, NoInit, std::size_t(field.size()), objectTypeSize, objectTypeAlignment, itemViews[itemViewOffset]); arrayAppend(items, InPlaceInit, NoInit, std::size_t(field.size()), mappingTypeSize, mappingTypeAlignment, itemViews[itemViewOffset]);
++itemViewOffset; ++itemViewOffset;
} }
@ -162,13 +163,13 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
CORRADE_INTERNAL_ASSERT(!outData.deleter()); CORRADE_INTERNAL_ASSERT(!outData.deleter());
/* Copy the object data over and cast them as necessary */ /* Copy the object data over and cast them as necessary */
if(objectType == SceneObjectType::UnsignedByte) if(mappingType == SceneMappingType::UnsignedByte)
sceneCombineCopyObjects<UnsignedByte>(fields, itemViews, itemViewMappings); sceneCombineCopyObjects<UnsignedByte>(fields, itemViews, itemViewMappings);
else if(objectType == SceneObjectType::UnsignedShort) else if(mappingType == SceneMappingType::UnsignedShort)
sceneCombineCopyObjects<UnsignedShort>(fields, itemViews, itemViewMappings); sceneCombineCopyObjects<UnsignedShort>(fields, itemViews, itemViewMappings);
else if(objectType == SceneObjectType::UnsignedInt) else if(mappingType == SceneMappingType::UnsignedInt)
sceneCombineCopyObjects<UnsignedInt>(fields, itemViews, itemViewMappings); sceneCombineCopyObjects<UnsignedInt>(fields, itemViews, itemViewMappings);
else if(objectType == SceneObjectType::UnsignedLong) else if(mappingType == SceneMappingType::UnsignedLong)
sceneCombineCopyObjects<UnsignedLong>(fields, itemViews, itemViewMappings); sceneCombineCopyObjects<UnsignedLong>(fields, itemViews, itemViewMappings);
/* Copy the field data over. No special handling needed here. */ /* Copy the field data over. No special handling needed here. */
@ -187,7 +188,7 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
outFields[i] = SceneFieldData{fields[i].name(), itemViews[itemViewMappings[i].first()], fields[i].fieldType(), itemViews[itemViewMappings[i].second()], fields[i].fieldArraySize()}; outFields[i] = SceneFieldData{fields[i].name(), itemViews[itemViewMappings[i].first()], fields[i].fieldType(), itemViews[itemViewMappings[i].second()], fields[i].fieldArraySize()};
} }
return SceneData{objectType, objectCount, std::move(outData), std::move(outFields)}; return SceneData{mappingType, mappingBound, std::move(outData), std::move(outFields)};
} }
/* Creates a SceneData copy where each object has at most one of the fields /* Creates a SceneData copy where each object has at most one of the fields
@ -205,7 +206,7 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
internal asserts into (tested!) message asserts */ internal asserts into (tested!) message asserts */
inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Containers::ArrayView<const SceneField> fieldsToConvert, const UnsignedInt newObjectOffset) { inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Containers::ArrayView<const SceneField> fieldsToConvert, const UnsignedInt newObjectOffset) {
/** @todo assert for really high object counts (where this cast would fail) */ /** @todo assert for really high object counts (where this cast would fail) */
Containers::Array<UnsignedInt> objectAttachmentCount{ValueInit, std::size_t(scene.objectCount())}; Containers::Array<UnsignedInt> objectAttachmentCount{ValueInit, std::size_t(scene.mappingBound())};
for(const SceneField field: fieldsToConvert) { for(const SceneField field: fieldsToConvert) {
CORRADE_INTERNAL_ASSERT(field != SceneField::Parent); CORRADE_INTERNAL_ASSERT(field != SceneField::Parent);
@ -217,7 +218,7 @@ inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Con
/** @todo use a statically-allocated array & Into() in a loop instead /** @todo use a statically-allocated array & Into() in a loop instead
once this is more than a private backwards-compatibility utility once this is more than a private backwards-compatibility utility
where PERF WHATEVER WHO CARES */ where PERF WHATEVER WHO CARES */
for(const UnsignedInt object: scene.objectsAsArray(*fieldId)) { for(const UnsignedInt object: scene.mappingAsArray(*fieldId)) {
CORRADE_INTERNAL_ASSERT(object < objectAttachmentCount.size()); CORRADE_INTERNAL_ASSERT(object < objectAttachmentCount.size());
++objectAttachmentCount[object]; ++objectAttachmentCount[object];
} }
@ -249,25 +250,25 @@ inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Con
} }
/* Combine the fields into a new SceneData */ /* Combine the fields into a new SceneData */
SceneData out = sceneCombine(SceneObjectType::UnsignedInt, Math::max(scene.objectCount(), UnsignedLong(newObjectOffset) + objectsToAdd), fields); SceneData out = sceneCombine(SceneMappingType::UnsignedInt, Math::max(scene.mappingBound(), UnsignedLong(newObjectOffset) + objectsToAdd), fields);
/* Copy existing parent object/field data to a prefix of the output */ /* Copy existing parent object/field data to a prefix of the output */
const Containers::StridedArrayView1D<UnsignedInt> outParentObjects = out.mutableObjects<UnsignedInt>(parentFieldId); const Containers::StridedArrayView1D<UnsignedInt> outParentMapping = out.mutableMapping<UnsignedInt>(parentFieldId);
const Containers::StridedArrayView1D<Int> outParents = out.mutableField<Int>(parentFieldId); const Containers::StridedArrayView1D<Int> outParents = out.mutableField<Int>(parentFieldId);
CORRADE_INTERNAL_ASSERT_OUTPUT(scene.parentsInto(0, outParentObjects, outParents) == scene.fieldSize(parentFieldId)); CORRADE_INTERNAL_ASSERT_OUTPUT(scene.parentsInto(0, outParentMapping, outParents) == scene.fieldSize(parentFieldId));
/* List new objects at the end of the extended parent field */ /* List new objects at the end of the extended parent field */
const Containers::StridedArrayView1D<UnsignedInt> newParentObjects = outParentObjects.suffix(scene.fieldSize(parentFieldId)); const Containers::StridedArrayView1D<UnsignedInt> newParentMapping = outParentMapping.suffix(scene.fieldSize(parentFieldId));
const Containers::StridedArrayView1D<Int> newParents = outParents.suffix(scene.fieldSize(parentFieldId)); const Containers::StridedArrayView1D<Int> newParents = outParents.suffix(scene.fieldSize(parentFieldId));
for(std::size_t i = 0; i != newParentObjects.size(); ++i) { for(std::size_t i = 0; i != newParentMapping.size(); ++i) {
newParentObjects[i] = newObjectOffset + i; newParentMapping[i] = newObjectOffset + i;
newParents[i] = -1; newParents[i] = -1;
} }
/* Clear the objectAttachmentCount array to reuse it below */ /* Clear the objectAttachmentCount array to reuse it below */
/** @todo use a BitArray instead once it exists? */ /** @todo use a BitArray instead once it exists? */
constexpr UnsignedInt zero[1]{}; constexpr UnsignedInt zero[1]{};
Utility::copy(Containers::stridedArrayView(zero).broadcasted<0>(scene.objectCount()), objectAttachmentCount); Utility::copy(Containers::stridedArrayView(zero).broadcasted<0>(scene.mappingBound()), objectAttachmentCount);
/* For objects with multiple fields move the extra fields to newly added /* For objects with multiple fields move the extra fields to newly added
children */ children */
@ -277,7 +278,7 @@ inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Con
const Containers::Optional<UnsignedInt> fieldId = scene.findFieldId(field); const Containers::Optional<UnsignedInt> fieldId = scene.findFieldId(field);
if(!fieldId) continue; if(!fieldId) continue;
for(UnsignedInt& fieldObject: out.mutableObjects<UnsignedInt>(*fieldId)) { for(UnsignedInt& fieldObject: out.mutableMapping<UnsignedInt>(*fieldId)) {
/* If the object is not new (could happen when an object /* If the object is not new (could happen when an object
mapping array is shared among multiple fields, in which case mapping array is shared among multiple fields, in which case
it *might* have been updated already to an ID larger than it *might* have been updated already to an ID larger than
@ -288,7 +289,7 @@ inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Con
/* Use the old object as a parent of the new object */ /* Use the old object as a parent of the new object */
newParents[newParentIndex] = fieldObject; newParents[newParentIndex] = fieldObject;
/* Assign the field to the new object */ /* Assign the field to the new object */
fieldObject = newParentObjects[newParentIndex]; fieldObject = newParentMapping[newParentIndex];
/* Move to the next reserved object */ /* Move to the next reserved object */
++newParentIndex; ++newParentIndex;
} else ++objectAttachmentCount[fieldObject]; } else ++objectAttachmentCount[fieldObject];

549
src/Magnum/Trade/SceneData.cpp

File diff suppressed because it is too large Load Diff

498
src/Magnum/Trade/SceneData.h

File diff suppressed because it is too large Load Diff

98
src/Magnum/Trade/Test/AbstractImporterTest.cpp

@ -1703,8 +1703,8 @@ void AbstractImporterTest::scene() {
} }
Containers::Optional<SceneData> doScene(UnsignedInt id) override { Containers::Optional<SceneData> doScene(UnsignedInt id) override {
if(id == 7) if(id == 7)
return SceneData{SceneObjectType::UnsignedByte, 0, nullptr, {}, &state}; return SceneData{SceneMappingType::UnsignedByte, 0, nullptr, {}, &state};
return SceneData{SceneObjectType::UnsignedByte, 0, nullptr, {}}; return SceneData{SceneMappingType::UnsignedByte, 0, nullptr, {}};
} }
} importer; } importer;
@ -1899,21 +1899,21 @@ void AbstractImporterTest::sceneDeprecatedFallback2D() {
/* This one has seven objects, but no fields for them so it should /* This one has seven objects, but no fields for them so it should
get skipped */ get skipped */
if(id == 0) if(id == 0)
return SceneData{SceneObjectType::UnsignedByte, 7, nullptr, {}}; return SceneData{SceneMappingType::UnsignedByte, 7, nullptr, {}};
/* This one has no objects, so it should get skipped as well /* This one has no objects, so it should get skipped as well
without even querying any fieldFor() API (as those would without even querying any fieldFor() API (as those would
assert) */ assert) */
if(id == 1) if(id == 1)
return SceneData{SceneObjectType::UnsignedShort, 0, nullptr, {}}; return SceneData{SceneMappingType::UnsignedShort, 0, nullptr, {}};
/* This one is the one */ /* This one is the one */
if(id == 2) if(id == 2)
return SceneData{SceneObjectType::UnsignedInt, 7, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 7, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); CORRADE_INTERNAL_ASSERT_UNREACHABLE();
} }
private: private:
SceneData _data; SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 7, std::move(data), { } importer{SceneData{SceneMappingType::UnsignedInt, 7, std::move(data), {
SceneFieldData{SceneField::Parent, SceneFieldData{SceneField::Parent,
transformations.slice(&Transform::object), transformations.slice(&Transform::object),
transformations.slice(&Transform::parent)}, transformations.slice(&Transform::parent)},
@ -2171,21 +2171,21 @@ void AbstractImporterTest::sceneDeprecatedFallback3D() {
/* This one has seven objects, but no fields for them so it should /* This one has seven objects, but no fields for them so it should
get skipped */ get skipped */
if(id == 0) if(id == 0)
return SceneData{SceneObjectType::UnsignedByte, 7, nullptr, {}}; return SceneData{SceneMappingType::UnsignedByte, 7, nullptr, {}};
/* This one has no objects, so it should get skipped as well /* This one has no objects, so it should get skipped as well
without even querying any fieldFor() API (as those would without even querying any fieldFor() API (as those would
assert) */ assert) */
if(id == 1) if(id == 1)
return SceneData{SceneObjectType::UnsignedShort, 0, nullptr, {}}; return SceneData{SceneMappingType::UnsignedShort, 0, nullptr, {}};
/* This one is the one */ /* This one is the one */
if(id == 2) if(id == 2)
return SceneData{SceneObjectType::UnsignedInt, 7, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 7, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); CORRADE_INTERNAL_ASSERT_UNREACHABLE();
} }
private: private:
SceneData _data; SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 7, std::move(data), { } importer{SceneData{SceneMappingType::UnsignedInt, 7, std::move(data), {
SceneFieldData{SceneField::Parent, SceneFieldData{SceneField::Parent,
transformations.slice(&Transform::object), transformations.slice(&Transform::object),
transformations.slice(&Transform::parent)}, transformations.slice(&Transform::parent)},
@ -2356,12 +2356,12 @@ void AbstractImporterTest::sceneDeprecatedFallbackParentless2D() {
UnsignedInt doSceneCount() const override { return 1; } UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; } UnsignedLong doObjectCount() const override { return 6; }
Containers::Optional<SceneData> doScene(UnsignedInt) override { Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
} }
private: private:
SceneData _data; SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, { } importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Transformation, SceneFieldData{SceneField::Transformation,
view.slice(&Field::object), view.slice(&Field::object),
view.slice(&Field::transformation)} view.slice(&Field::transformation)}
@ -2431,12 +2431,12 @@ void AbstractImporterTest::sceneDeprecatedFallbackParentless3D() {
UnsignedInt doSceneCount() const override { return 1; } UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; } UnsignedLong doObjectCount() const override { return 6; }
Containers::Optional<SceneData> doScene(UnsignedInt) override { Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
} }
private: private:
SceneData _data; SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, { } importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Transformation, SceneFieldData{SceneField::Transformation,
view.slice(&Field::object), view.slice(&Field::object),
view.slice(&Field::transformation)} view.slice(&Field::transformation)}
@ -2506,17 +2506,17 @@ void AbstractImporterTest::sceneDeprecatedFallbackTransformless2D() {
UnsignedInt doSceneCount() const override { return 1; } UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; } UnsignedLong doObjectCount() const override { return 6; }
Containers::Optional<SceneData> doScene(UnsignedInt) override { Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
} }
private: private:
SceneData _data; SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, { } importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Parent, SceneFieldData{SceneField::Parent,
view.slice(&Field::object), view.slice(&Field::object),
view.slice(&Field::parent)}, view.slice(&Field::parent)},
/* Required in order to have the scene recognized as 2D */ /* Required in order to have the scene recognized as 2D */
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Matrix3x3, nullptr} SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Matrix3x3, nullptr}
}}}; }}};
CORRADE_COMPARE(importer.sceneCount(), 1); CORRADE_COMPARE(importer.sceneCount(), 1);
@ -2612,17 +2612,17 @@ void AbstractImporterTest::sceneDeprecatedFallbackTransformless3D() {
UnsignedInt doSceneCount() const override { return 1; } UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; } UnsignedLong doObjectCount() const override { return 6; }
Containers::Optional<SceneData> doScene(UnsignedInt) override { Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 6, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
} }
private: private:
SceneData _data; SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, { } importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Parent, SceneFieldData{SceneField::Parent,
view.slice(&Field::object), view.slice(&Field::object),
view.slice(&Field::parent)}, view.slice(&Field::parent)},
/* Required in order to have the scene recognized as 3D */ /* Required in order to have the scene recognized as 3D */
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Matrix4x4, nullptr} SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Matrix4x4, nullptr}
}}}; }}};
CORRADE_COMPARE(importer.sceneCount(), 1); CORRADE_COMPARE(importer.sceneCount(), 1);
@ -2747,20 +2747,20 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects2D() {
{30, 1, -1} {30, 1, -1}
}, meshesSecondary); }, meshesSecondary);
SceneData data{SceneObjectType::UnsignedInt, 32, std::move(dataData), { SceneData data{SceneMappingType::UnsignedInt, 32, std::move(dataData), {
SceneFieldData{SceneField::Parent, parents.slice(&Parent::object), parents.slice(&Parent::parent)}, SceneFieldData{SceneField::Parent, parents.slice(&Parent::object), parents.slice(&Parent::parent)},
SceneFieldData{SceneField::Mesh, meshes.slice(&Mesh::object), meshes.slice(&Mesh::mesh)}, SceneFieldData{SceneField::Mesh, meshes.slice(&Mesh::object), meshes.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshes.slice(&Mesh::object), meshes.slice(&Mesh::meshMaterial)}, SceneFieldData{SceneField::MeshMaterial, meshes.slice(&Mesh::object), meshes.slice(&Mesh::meshMaterial)},
SceneFieldData{SceneField::Camera, cameras.slice(&Camera::object), cameras.slice(&Camera::camera)}, SceneFieldData{SceneField::Camera, cameras.slice(&Camera::object), cameras.slice(&Camera::camera)},
/* Just to disambiguate this as a 2D scene */ /* Just to disambiguate this as a 2D scene */
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Matrix3x3, nullptr}, SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Matrix3x3, nullptr},
}}; }};
SceneData dataSecondary{SceneObjectType::UnsignedInt, 31, std::move(dataDataSecondary), { SceneData dataSecondary{SceneMappingType::UnsignedInt, 31, std::move(dataDataSecondary), {
SceneFieldData{SceneField::Parent, parentsSecondary.slice(&Parent::object), parentsSecondary.slice(&Parent::parent)}, SceneFieldData{SceneField::Parent, parentsSecondary.slice(&Parent::object), parentsSecondary.slice(&Parent::parent)},
SceneFieldData{SceneField::Mesh, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::mesh)}, SceneFieldData{SceneField::Mesh, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::meshMaterial)}, SceneFieldData{SceneField::MeshMaterial, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::meshMaterial)},
/* Just to disambiguate this as a 2D scene */ /* Just to disambiguate this as a 2D scene */
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Matrix3x3, nullptr}, SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Matrix3x3, nullptr},
}}; }};
struct Importer: AbstractImporter { struct Importer: AbstractImporter {
@ -2784,19 +2784,19 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects2D() {
/* This scene should get skipped when querying names as it's not /* This scene should get skipped when querying names as it's not
2D */ 2D */
if(id == 0) if(id == 0)
return SceneData{SceneObjectType::UnsignedByte, 32, nullptr, {}}; return SceneData{SceneMappingType::UnsignedByte, 32, nullptr, {}};
/* This scene should get skipped when querying names as it has too /* This scene should get skipped when querying names as it has too
little objects */ little objects */
if(id == 1) if(id == 1)
return SceneData{SceneObjectType::UnsignedByte, 32, nullptr, { return SceneData{SceneMappingType::UnsignedByte, 32, nullptr, {
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedByte, nullptr, SceneFieldType::Matrix3x3, nullptr} SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedByte, nullptr, SceneFieldType::Matrix3x3, nullptr}
}}; }};
if(id == 2) if(id == 2)
return SceneData{SceneObjectType::UnsignedInt, 32, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 32, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
/* A secondary scene, which should have non-overlapping IDs for the /* A secondary scene, which should have non-overlapping IDs for the
newly added objects */ newly added objects */
if(id == 3) if(id == 3)
return SceneData{SceneObjectType::UnsignedInt, 31, {}, _dataSecondary.data(), sceneFieldDataNonOwningArray(_dataSecondary.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 31, {}, _dataSecondary.data(), sceneFieldDataNonOwningArray(_dataSecondary.fieldData())};
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); CORRADE_INTERNAL_ASSERT_UNREACHABLE();
} }
@ -3014,20 +3014,20 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects3D() {
{30, 1, -1} {30, 1, -1}
}, meshesSecondary); }, meshesSecondary);
SceneData data{SceneObjectType::UnsignedInt, 32, std::move(dataData), { SceneData data{SceneMappingType::UnsignedInt, 32, std::move(dataData), {
SceneFieldData{SceneField::Parent, parents.slice(&Parent::object), parents.slice(&Parent::parent)}, SceneFieldData{SceneField::Parent, parents.slice(&Parent::object), parents.slice(&Parent::parent)},
SceneFieldData{SceneField::Mesh, meshes.slice(&Mesh::object), meshes.slice(&Mesh::mesh)}, SceneFieldData{SceneField::Mesh, meshes.slice(&Mesh::object), meshes.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshes.slice(&Mesh::object), meshes.slice(&Mesh::meshMaterial)}, SceneFieldData{SceneField::MeshMaterial, meshes.slice(&Mesh::object), meshes.slice(&Mesh::meshMaterial)},
SceneFieldData{SceneField::Camera, cameras.slice(&Camera::object), cameras.slice(&Camera::camera)}, SceneFieldData{SceneField::Camera, cameras.slice(&Camera::object), cameras.slice(&Camera::camera)},
/* Just to disambiguate this as a 3D scene */ /* Just to disambiguate this as a 3D scene */
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Matrix4x4, nullptr}, SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Matrix4x4, nullptr},
}}; }};
SceneData dataSecondary{SceneObjectType::UnsignedInt, 31, std::move(dataDataSecondary), { SceneData dataSecondary{SceneMappingType::UnsignedInt, 31, std::move(dataDataSecondary), {
SceneFieldData{SceneField::Parent, parentsSecondary.slice(&Parent::object), parentsSecondary.slice(&Parent::parent)}, SceneFieldData{SceneField::Parent, parentsSecondary.slice(&Parent::object), parentsSecondary.slice(&Parent::parent)},
SceneFieldData{SceneField::Mesh, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::mesh)}, SceneFieldData{SceneField::Mesh, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::meshMaterial)}, SceneFieldData{SceneField::MeshMaterial, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::meshMaterial)},
/* Just to disambiguate this as a 3D scene */ /* Just to disambiguate this as a 3D scene */
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Matrix4x4, nullptr}, SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Matrix4x4, nullptr},
}}; }};
struct Importer: AbstractImporter { struct Importer: AbstractImporter {
@ -3051,19 +3051,19 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects3D() {
/* This scene should get skipped when querying names as it's not /* This scene should get skipped when querying names as it's not
2D */ 2D */
if(id == 0) if(id == 0)
return SceneData{SceneObjectType::UnsignedByte, 32, nullptr, {}}; return SceneData{SceneMappingType::UnsignedByte, 32, nullptr, {}};
/* This scene should get skipped when querying names as it has too /* This scene should get skipped when querying names as it has too
little objects */ little objects */
if(id == 1) if(id == 1)
return SceneData{SceneObjectType::UnsignedByte, 32, nullptr, { return SceneData{SceneMappingType::UnsignedByte, 32, nullptr, {
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedByte, nullptr, SceneFieldType::Matrix4x4, nullptr} SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedByte, nullptr, SceneFieldType::Matrix4x4, nullptr}
}}; }};
if(id == 2) if(id == 2)
return SceneData{SceneObjectType::UnsignedInt, 32, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 32, {}, _data.data(), sceneFieldDataNonOwningArray(_data.fieldData())};
/* A secondary scene, which should have non-overlapping IDs for the /* A secondary scene, which should have non-overlapping IDs for the
newly added objects */ newly added objects */
if(id == 3) if(id == 3)
return SceneData{SceneObjectType::UnsignedInt, 31, {}, _dataSecondary.data(), sceneFieldDataNonOwningArray(_dataSecondary.fieldData())}; return SceneData{SceneMappingType::UnsignedInt, 31, {}, _dataSecondary.data(), sceneFieldDataNonOwningArray(_dataSecondary.fieldData())};
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); CORRADE_INTERNAL_ASSERT_UNREACHABLE();
} }
@ -3282,13 +3282,13 @@ void AbstractImporterTest::sceneDeprecatedFallbackBoth2DAnd3DScene() {
return {}; return {};
} }
Containers::Optional<SceneData> doScene(UnsignedInt id) override { Containers::Optional<SceneData> doScene(UnsignedInt id) override {
if(id == 0) return SceneData{SceneObjectType::UnsignedInt, 7, nullptr, { if(id == 0) return SceneData{SceneMappingType::UnsignedInt, 7, nullptr, {
SceneFieldData{SceneField::Parent, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr}, SceneFieldData{SceneField::Parent, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr},
SceneFieldData{SceneField::Translation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Vector2, nullptr}, SceneFieldData{SceneField::Translation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Vector2, nullptr},
}}; }};
if(id == 1) return SceneData{SceneObjectType::UnsignedInt, 7, nullptr, { if(id == 1) return SceneData{SceneMappingType::UnsignedInt, 7, nullptr, {
SceneFieldData{SceneField::Parent, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr}, SceneFieldData{SceneField::Parent, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr},
SceneFieldData{SceneField::Translation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Vector3, nullptr}, SceneFieldData{SceneField::Translation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Vector3, nullptr},
}}; }};
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); CORRADE_INTERNAL_ASSERT_UNREACHABLE();
} }
@ -3432,14 +3432,14 @@ void AbstractImporterTest::sceneNonOwningDeleters() {
UnsignedInt doSceneCount() const override { return 1; } UnsignedInt doSceneCount() const override { return 1; }
Containers::Optional<SceneData> doScene(UnsignedInt) override { Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 0, return SceneData{SceneMappingType::UnsignedInt, 0,
Containers::Array<char>{data, 1, Implementation::nonOwnedArrayDeleter}, Containers::Array<char>{data, 1, Implementation::nonOwnedArrayDeleter},
sceneFieldDataNonOwningArray(fields)}; sceneFieldDataNonOwningArray(fields)};
} }
char data[1]; char data[1];
SceneFieldData fields[1]{ SceneFieldData fields[1]{
SceneFieldData{SceneField::Parent, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr} SceneFieldData{SceneField::Parent, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr}
}; };
} importer; } importer;
@ -3462,7 +3462,7 @@ void AbstractImporterTest::sceneCustomDataDeleter() {
UnsignedInt doSceneCount() const override { return 1; } UnsignedInt doSceneCount() const override { return 1; }
Int doSceneForName(const std::string&) override { return 0; } Int doSceneForName(const std::string&) override { return 0; }
Containers::Optional<SceneData> doScene(UnsignedInt) override { Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 0, return SceneData{SceneMappingType::UnsignedInt, 0,
Containers::Array<char>{data, 1, [](char*, std::size_t) {}}, Containers::Array<char>{data, 1, [](char*, std::size_t) {}},
{}}; {}};
} }
@ -3493,10 +3493,10 @@ void AbstractImporterTest::sceneCustomFieldDataDeleter() {
UnsignedInt doSceneCount() const override { return 1; } UnsignedInt doSceneCount() const override { return 1; }
Int doSceneForName(const std::string&) override { return 0; } Int doSceneForName(const std::string&) override { return 0; }
Containers::Optional<SceneData> doScene(UnsignedInt) override { Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 0, nullptr, Containers::Array<SceneFieldData>{&parents, 1, [](SceneFieldData*, std::size_t) {}}}; return SceneData{SceneMappingType::UnsignedInt, 0, nullptr, Containers::Array<SceneFieldData>{&parents, 1, [](SceneFieldData*, std::size_t) {}}};
} }
SceneFieldData parents{SceneField::Parent, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr}; SceneFieldData parents{SceneField::Parent, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr};
} importer; } importer;
std::ostringstream out; std::ostringstream out;

1640
src/Magnum/Trade/Test/SceneDataTest.cpp

File diff suppressed because it is too large Load Diff

210
src/Magnum/Trade/Test/SceneToolsTest.cpp

@ -47,12 +47,12 @@ struct SceneToolsTest: TestSuite::Tester {
struct { struct {
const char* name; const char* name;
SceneObjectType objectType; SceneMappingType objectType;
} CombineData[]{ } CombineData[]{
{"UnsignedByte output", SceneObjectType::UnsignedByte}, {"UnsignedByte output", SceneMappingType::UnsignedByte},
{"UnsignedShort output", SceneObjectType::UnsignedShort}, {"UnsignedShort output", SceneMappingType::UnsignedShort},
{"UnsignedInt output", SceneObjectType::UnsignedInt}, {"UnsignedInt output", SceneMappingType::UnsignedInt},
{"UnsignedLong output", SceneObjectType::UnsignedLong}, {"UnsignedLong output", SceneMappingType::UnsignedLong},
}; };
struct { struct {
@ -86,76 +86,76 @@ void SceneToolsTest::combine() {
/* Testing the four possible object types, it should be possible to combine /* Testing the four possible object types, it should be possible to combine
them */ them */
const UnsignedInt meshObjects[]{45, 78, 23}; const UnsignedInt meshMappingData[]{45, 78, 23};
const UnsignedByte meshes[]{3, 5, 17}; const UnsignedByte meshFieldData[]{3, 5, 17};
const UnsignedShort parentObjects[]{33, 25}; const UnsignedShort parentMappingData[]{33, 25};
const Short parents[]{-1, 33}; const Short parentData[]{-1, 33};
const UnsignedByte translationObjects[]{16}; const UnsignedByte translationMappingData[]{16};
const Vector2d translations[]{{1.5, -0.5}}; const Vector2d translationFieldData[]{{1.5, -0.5}};
const UnsignedLong fooObjects[]{15, 23}; const UnsignedLong fooMappingData[]{15, 23};
const Int foos[]{0, 1, 2, 3}; const Int fooFieldData[]{0, 1, 2, 3};
SceneData scene = Implementation::sceneCombine(data.objectType, 167, Containers::arrayView({ SceneData scene = Implementation::sceneCombine(data.objectType, 167, Containers::arrayView({
SceneFieldData{SceneField::Mesh, Containers::arrayView(meshObjects), Containers::arrayView(meshes)}, SceneFieldData{SceneField::Mesh, Containers::arrayView(meshMappingData), Containers::arrayView(meshFieldData)},
SceneFieldData{SceneField::Parent, Containers::arrayView(parentObjects), Containers::arrayView(parents)}, SceneFieldData{SceneField::Parent, Containers::arrayView(parentMappingData), Containers::arrayView(parentData)},
SceneFieldData{SceneField::Translation, Containers::arrayView(translationObjects), Containers::arrayView(translations)}, SceneFieldData{SceneField::Translation, Containers::arrayView(translationMappingData), Containers::arrayView(translationFieldData)},
/* Array field */ /* Array field */
SceneFieldData{sceneFieldCustom(15), Containers::arrayView(fooObjects), Containers::StridedArrayView2D<const Int>{foos, {2, 2}}}, SceneFieldData{sceneFieldCustom(15), Containers::arrayView(fooMappingData), Containers::StridedArrayView2D<const Int>{fooFieldData, {2, 2}}},
/* Empty field */ /* Empty field */
SceneFieldData{SceneField::Camera, Containers::ArrayView<const UnsignedByte>{}, Containers::ArrayView<const UnsignedShort>{}} SceneFieldData{SceneField::Camera, Containers::ArrayView<const UnsignedByte>{}, Containers::ArrayView<const UnsignedShort>{}}
})); }));
CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable); CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable);
CORRADE_COMPARE(scene.objectType(), data.objectType); CORRADE_COMPARE(scene.mappingType(), data.objectType);
CORRADE_COMPARE(scene.objectCount(), 167); CORRADE_COMPARE(scene.mappingBound(), 167);
CORRADE_COMPARE(scene.fieldCount(), 5); CORRADE_COMPARE(scene.fieldCount(), 5);
CORRADE_COMPARE(scene.fieldName(0), SceneField::Mesh); CORRADE_COMPARE(scene.fieldName(0), SceneField::Mesh);
CORRADE_COMPARE(scene.fieldType(0), SceneFieldType::UnsignedByte); CORRADE_COMPARE(scene.fieldType(0), SceneFieldType::UnsignedByte);
CORRADE_COMPARE(scene.fieldArraySize(0), 0); CORRADE_COMPARE(scene.fieldArraySize(0), 0);
CORRADE_COMPARE_AS(scene.objectsAsArray(0), Containers::arrayView<UnsignedInt>({ CORRADE_COMPARE_AS(scene.mappingAsArray(0), Containers::arrayView<UnsignedInt>({
45, 78, 23 45, 78, 23
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<UnsignedByte>(0), CORRADE_COMPARE_AS(scene.field<UnsignedByte>(0),
Containers::arrayView(meshes), Containers::arrayView(meshFieldData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE(scene.fieldName(1), SceneField::Parent); CORRADE_COMPARE(scene.fieldName(1), SceneField::Parent);
CORRADE_COMPARE(scene.fieldType(1), SceneFieldType::Short); CORRADE_COMPARE(scene.fieldType(1), SceneFieldType::Short);
CORRADE_COMPARE(scene.fieldArraySize(1), 0); CORRADE_COMPARE(scene.fieldArraySize(1), 0);
CORRADE_COMPARE_AS(scene.objectsAsArray(1), Containers::arrayView<UnsignedInt>({ CORRADE_COMPARE_AS(scene.mappingAsArray(1), Containers::arrayView<UnsignedInt>({
33, 25 33, 25
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<Short>(1), CORRADE_COMPARE_AS(scene.field<Short>(1),
Containers::arrayView(parents), Containers::arrayView(parentData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE(scene.fieldName(2), SceneField::Translation); CORRADE_COMPARE(scene.fieldName(2), SceneField::Translation);
CORRADE_COMPARE(scene.fieldType(2), SceneFieldType::Vector2d); CORRADE_COMPARE(scene.fieldType(2), SceneFieldType::Vector2d);
CORRADE_COMPARE(scene.fieldArraySize(2), 0); CORRADE_COMPARE(scene.fieldArraySize(2), 0);
CORRADE_COMPARE_AS(scene.objectsAsArray(2), CORRADE_COMPARE_AS(scene.mappingAsArray(2),
Containers::arrayView<UnsignedInt>({16}), Containers::arrayView<UnsignedInt>({16}),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<Vector2d>(2), CORRADE_COMPARE_AS(scene.field<Vector2d>(2),
Containers::arrayView(translations), Containers::arrayView(translationFieldData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE(scene.fieldName(3), sceneFieldCustom(15)); CORRADE_COMPARE(scene.fieldName(3), sceneFieldCustom(15));
CORRADE_COMPARE(scene.fieldType(3), SceneFieldType::Int); CORRADE_COMPARE(scene.fieldType(3), SceneFieldType::Int);
CORRADE_COMPARE(scene.fieldArraySize(3), 2); CORRADE_COMPARE(scene.fieldArraySize(3), 2);
CORRADE_COMPARE_AS(scene.objectsAsArray(3), CORRADE_COMPARE_AS(scene.mappingAsArray(3),
Containers::arrayView<UnsignedInt>({15, 23}), Containers::arrayView<UnsignedInt>({15, 23}),
TestSuite::Compare::Container); TestSuite::Compare::Container);
/** @todo clean up once it's possible to compare multidimensional /** @todo clean up once it's possible to compare multidimensional
containers */ containers */
CORRADE_COMPARE_AS(scene.field<Int[]>(3)[0], CORRADE_COMPARE_AS(scene.field<Int[]>(3)[0],
(Containers::StridedArrayView2D<const Int>{foos, {2, 2}})[0], (Containers::StridedArrayView2D<const Int>{fooFieldData, {2, 2}})[0],
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<Int[]>(3)[1], CORRADE_COMPARE_AS(scene.field<Int[]>(3)[1],
(Containers::StridedArrayView2D<const Int>{foos, {2, 2}})[1], (Containers::StridedArrayView2D<const Int>{fooFieldData, {2, 2}})[1],
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE(scene.fieldName(4), SceneField::Camera); CORRADE_COMPARE(scene.fieldName(4), SceneField::Camera);
@ -165,33 +165,33 @@ void SceneToolsTest::combine() {
} }
void SceneToolsTest::combineAlignment() { void SceneToolsTest::combineAlignment() {
const UnsignedShort meshObjects[]{15, 23, 47}; const UnsignedShort meshMappingData[]{15, 23, 47};
const UnsignedByte meshes[]{0, 1, 2}; const UnsignedByte meshFieldData[]{0, 1, 2};
const UnsignedShort translationObjects[]{5}; /* 1 byte padding before */ const UnsignedShort translationMappingData[]{5}; /* 1 byte padding before */
const Vector2d translations[]{{1.5, 3.0}}; /* 4 byte padding before */ const Vector2d translationFieldData[]{{1.5, 3.0}}; /* 4 byte padding before */
SceneData scene = Implementation::sceneCombine(SceneObjectType::UnsignedShort, 167, Containers::arrayView({ SceneData scene = Implementation::sceneCombine(SceneMappingType::UnsignedShort, 167, Containers::arrayView({
SceneFieldData{SceneField::Mesh, Containers::arrayView(meshObjects), Containers::arrayView(meshes)}, SceneFieldData{SceneField::Mesh, Containers::arrayView(meshMappingData), Containers::arrayView(meshFieldData)},
SceneFieldData{SceneField::Translation, Containers::arrayView(translationObjects), Containers::arrayView(translations)} SceneFieldData{SceneField::Translation, Containers::arrayView(translationMappingData), Containers::arrayView(translationFieldData)}
})); }));
CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable); CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable);
CORRADE_COMPARE(scene.objectType(), SceneObjectType::UnsignedShort); CORRADE_COMPARE(scene.mappingType(), SceneMappingType::UnsignedShort);
CORRADE_COMPARE(scene.objectCount(), 167); CORRADE_COMPARE(scene.mappingBound(), 167);
CORRADE_COMPARE(scene.fieldCount(), 2); CORRADE_COMPARE(scene.fieldCount(), 2);
CORRADE_COMPARE(scene.fieldName(0), SceneField::Mesh); CORRADE_COMPARE(scene.fieldName(0), SceneField::Mesh);
CORRADE_COMPARE(scene.fieldType(0), SceneFieldType::UnsignedByte); CORRADE_COMPARE(scene.fieldType(0), SceneFieldType::UnsignedByte);
CORRADE_COMPARE(scene.fieldArraySize(0), 0); CORRADE_COMPARE(scene.fieldArraySize(0), 0);
CORRADE_COMPARE_AS(scene.objects<UnsignedShort>(0), CORRADE_COMPARE_AS(scene.mapping<UnsignedShort>(0),
Containers::arrayView(meshObjects), Containers::arrayView(meshMappingData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<UnsignedByte>(0), CORRADE_COMPARE_AS(scene.field<UnsignedByte>(0),
Containers::arrayView(meshes), Containers::arrayView(meshFieldData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.objects(0).data()), 2, TestSuite::Compare::Divisible); CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.mapping(0).data()), 2, TestSuite::Compare::Divisible);
CORRADE_COMPARE(scene.objects(0).data(), scene.data()); CORRADE_COMPARE(scene.mapping(0).data(), scene.data());
CORRADE_COMPARE(scene.objects(0).stride()[0], 2); CORRADE_COMPARE(scene.mapping(0).stride()[0], 2);
CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.field(0).data()), 1, TestSuite::Compare::Divisible); CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.field(0).data()), 1, TestSuite::Compare::Divisible);
CORRADE_COMPARE(scene.field(0).data(), scene.data() + 3*2); CORRADE_COMPARE(scene.field(0).data(), scene.data() + 3*2);
CORRADE_COMPARE(scene.field(0).stride()[0], 1); CORRADE_COMPARE(scene.field(0).stride()[0], 1);
@ -199,60 +199,60 @@ void SceneToolsTest::combineAlignment() {
CORRADE_COMPARE(scene.fieldName(1), SceneField::Translation); CORRADE_COMPARE(scene.fieldName(1), SceneField::Translation);
CORRADE_COMPARE(scene.fieldType(1), SceneFieldType::Vector2d); CORRADE_COMPARE(scene.fieldType(1), SceneFieldType::Vector2d);
CORRADE_COMPARE(scene.fieldArraySize(1), 0); CORRADE_COMPARE(scene.fieldArraySize(1), 0);
CORRADE_COMPARE_AS(scene.objects<UnsignedShort>(1), CORRADE_COMPARE_AS(scene.mapping<UnsignedShort>(1),
Containers::arrayView(translationObjects), Containers::arrayView(translationMappingData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<Vector2d>(1), CORRADE_COMPARE_AS(scene.field<Vector2d>(1),
Containers::arrayView(translations), Containers::arrayView(translationFieldData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.objects(1).data()), 2, TestSuite::Compare::Divisible); CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.mapping(1).data()), 2, TestSuite::Compare::Divisible);
CORRADE_COMPARE(scene.objects(1).data(), scene.data() + 3*2 + 3 + 1); CORRADE_COMPARE(scene.mapping(1).data(), scene.data() + 3*2 + 3 + 1);
CORRADE_COMPARE(scene.objects(1).stride()[0], 2); CORRADE_COMPARE(scene.mapping(1).stride()[0], 2);
CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.field(1).data()), 8, TestSuite::Compare::Divisible); CORRADE_COMPARE_AS(reinterpret_cast<std::ptrdiff_t>(scene.field(1).data()), 8, TestSuite::Compare::Divisible);
CORRADE_COMPARE(scene.field(1).data(), scene.data() + 3*2 + 3 + 1 + 2 + 4); CORRADE_COMPARE(scene.field(1).data(), scene.data() + 3*2 + 3 + 1 + 2 + 4);
CORRADE_COMPARE(scene.field(1).stride()[0], 16); CORRADE_COMPARE(scene.field(1).stride()[0], 16);
} }
void SceneToolsTest::combineObjectsShared() { void SceneToolsTest::combineObjectsShared() {
const UnsignedShort meshObjects[]{15, 23, 47}; const UnsignedShort meshMappingData[]{15, 23, 47};
const UnsignedByte meshes[]{0, 1, 2}; const UnsignedByte meshFieldData[]{0, 1, 2};
const Int meshMaterials[]{72, -1, 23}; const Int meshMaterialFieldData[]{72, -1, 23};
const UnsignedShort translationRotationObjects[]{14, 22}; const UnsignedShort translationRotationMappingData[]{14, 22};
const Vector2 translations[]{{-1.0f, 25.3f}, {2.2f, 2.1f}}; const Vector2 translationFieldData[]{{-1.0f, 25.3f}, {2.2f, 2.1f}};
const Complex rotations[]{Complex::rotation(35.0_degf), Complex::rotation(22.5_degf)}; const Complex rotationFieldData[]{Complex::rotation(35.0_degf), Complex::rotation(22.5_degf)};
SceneData scene = Implementation::sceneCombine(SceneObjectType::UnsignedInt, 173, Containers::arrayView({ SceneData scene = Implementation::sceneCombine(SceneMappingType::UnsignedInt, 173, Containers::arrayView({
/* Deliberately in an arbitrary order to avoid false assumptions like /* Deliberately in an arbitrary order to avoid false assumptions like
fields sharing the same object mapping always being after each fields sharing the same object mapping always being after each
other */ other */
SceneFieldData{SceneField::Mesh, Containers::arrayView(meshObjects), Containers::arrayView(meshes)}, SceneFieldData{SceneField::Mesh, Containers::arrayView(meshMappingData), Containers::arrayView(meshFieldData)},
SceneFieldData{SceneField::Translation, Containers::arrayView(translationRotationObjects), Containers::arrayView(translations)}, SceneFieldData{SceneField::Translation, Containers::arrayView(translationRotationMappingData), Containers::arrayView(translationFieldData)},
SceneFieldData{SceneField::MeshMaterial, Containers::arrayView(meshObjects), Containers::arrayView(meshMaterials)}, SceneFieldData{SceneField::MeshMaterial, Containers::arrayView(meshMappingData), Containers::arrayView(meshMaterialFieldData)},
SceneFieldData{SceneField::Rotation, Containers::arrayView(translationRotationObjects), Containers::arrayView(rotations)} SceneFieldData{SceneField::Rotation, Containers::arrayView(translationRotationMappingData), Containers::arrayView(rotationFieldData)}
})); }));
CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable); CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable);
CORRADE_COMPARE(scene.objectType(), SceneObjectType::UnsignedInt); CORRADE_COMPARE(scene.mappingType(), SceneMappingType::UnsignedInt);
CORRADE_COMPARE(scene.objectCount(), 173); CORRADE_COMPARE(scene.mappingBound(), 173);
CORRADE_COMPARE(scene.fieldCount(), 4); CORRADE_COMPARE(scene.fieldCount(), 4);
CORRADE_COMPARE(scene.fieldSize(SceneField::Mesh), 3); CORRADE_COMPARE(scene.fieldSize(SceneField::Mesh), 3);
CORRADE_COMPARE(scene.fieldSize(SceneField::MeshMaterial), 3); CORRADE_COMPARE(scene.fieldSize(SceneField::MeshMaterial), 3);
CORRADE_COMPARE(scene.objects(SceneField::Mesh).data(), scene.objects(SceneField::MeshMaterial).data()); CORRADE_COMPARE(scene.mapping(SceneField::Mesh).data(), scene.mapping(SceneField::MeshMaterial).data());
CORRADE_COMPARE(scene.fieldSize(SceneField::Translation), 2); CORRADE_COMPARE(scene.fieldSize(SceneField::Translation), 2);
CORRADE_COMPARE(scene.fieldSize(SceneField::Rotation), 2); CORRADE_COMPARE(scene.fieldSize(SceneField::Rotation), 2);
CORRADE_COMPARE(scene.objects(SceneField::Translation).data(), scene.objects(SceneField::Rotation).data()); CORRADE_COMPARE(scene.mapping(SceneField::Translation).data(), scene.mapping(SceneField::Rotation).data());
} }
void SceneToolsTest::combineObjectsPlaceholderFieldPlaceholder() { void SceneToolsTest::combineObjectsPlaceholderFieldPlaceholder() {
const UnsignedShort meshObjects[]{15, 23, 47}; const UnsignedShort meshMappingData[]{15, 23, 47};
const UnsignedByte meshes[]{0, 1, 2}; const UnsignedByte meshFieldData[]{0, 1, 2};
SceneData scene = Implementation::sceneCombine(SceneObjectType::UnsignedShort, 173, Containers::arrayView({ SceneData scene = Implementation::sceneCombine(SceneMappingType::UnsignedShort, 173, Containers::arrayView({
SceneFieldData{SceneField::Camera, Containers::ArrayView<UnsignedByte>{nullptr, 1}, Containers::ArrayView<UnsignedShort>{nullptr, 1}}, SceneFieldData{SceneField::Camera, Containers::ArrayView<UnsignedByte>{nullptr, 1}, Containers::ArrayView<UnsignedShort>{nullptr, 1}},
SceneFieldData{SceneField::Mesh, Containers::arrayView(meshObjects), Containers::arrayView(meshes)}, SceneFieldData{SceneField::Mesh, Containers::arrayView(meshMappingData), Containers::arrayView(meshFieldData)},
/* Looks like sharing object mapping with the Camera field, but /* Looks like sharing object mapping with the Camera field, but
actually both are placeholders */ actually both are placeholders */
SceneFieldData{SceneField::Light, Containers::ArrayView<UnsignedShort>{nullptr, 2}, Containers::ArrayView<UnsignedInt>{nullptr, 2}}, SceneFieldData{SceneField::Light, Containers::ArrayView<UnsignedShort>{nullptr, 2}, Containers::ArrayView<UnsignedInt>{nullptr, 2}},
@ -261,73 +261,73 @@ void SceneToolsTest::combineObjectsPlaceholderFieldPlaceholder() {
})); }));
CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable); CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable);
CORRADE_COMPARE(scene.objectType(), SceneObjectType::UnsignedShort); CORRADE_COMPARE(scene.mappingType(), SceneMappingType::UnsignedShort);
CORRADE_COMPARE(scene.objectCount(), 173); CORRADE_COMPARE(scene.mappingBound(), 173);
CORRADE_COMPARE(scene.fieldCount(), 4); CORRADE_COMPARE(scene.fieldCount(), 4);
CORRADE_COMPARE(scene.fieldType(SceneField::Camera), SceneFieldType::UnsignedShort); CORRADE_COMPARE(scene.fieldType(SceneField::Camera), SceneFieldType::UnsignedShort);
CORRADE_COMPARE(scene.fieldSize(SceneField::Camera), 1); CORRADE_COMPARE(scene.fieldSize(SceneField::Camera), 1);
CORRADE_COMPARE(scene.fieldArraySize(SceneField::Camera), 0); CORRADE_COMPARE(scene.fieldArraySize(SceneField::Camera), 0);
CORRADE_COMPARE(scene.objects(SceneField::Camera).data(), scene.data()); CORRADE_COMPARE(scene.mapping(SceneField::Camera).data(), scene.data());
CORRADE_COMPARE(scene.objects(SceneField::Camera).stride()[0], 2); CORRADE_COMPARE(scene.mapping(SceneField::Camera).stride()[0], 2);
CORRADE_COMPARE(scene.field(SceneField::Camera).data(), scene.data() + 2); CORRADE_COMPARE(scene.field(SceneField::Camera).data(), scene.data() + 2);
CORRADE_COMPARE(scene.field(SceneField::Camera).stride()[0], 2); CORRADE_COMPARE(scene.field(SceneField::Camera).stride()[0], 2);
CORRADE_COMPARE(scene.fieldType(SceneField::Mesh), SceneFieldType::UnsignedByte); CORRADE_COMPARE(scene.fieldType(SceneField::Mesh), SceneFieldType::UnsignedByte);
CORRADE_COMPARE(scene.fieldArraySize(SceneField::Mesh), 0); CORRADE_COMPARE(scene.fieldArraySize(SceneField::Mesh), 0);
CORRADE_COMPARE_AS(scene.objects<UnsignedShort>(SceneField::Mesh), CORRADE_COMPARE_AS(scene.mapping<UnsignedShort>(SceneField::Mesh),
Containers::arrayView(meshObjects), Containers::arrayView(meshMappingData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<UnsignedByte>(SceneField::Mesh), CORRADE_COMPARE_AS(scene.field<UnsignedByte>(SceneField::Mesh),
Containers::arrayView(meshes), Containers::arrayView(meshFieldData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE(scene.fieldType(SceneField::Light), SceneFieldType::UnsignedInt); CORRADE_COMPARE(scene.fieldType(SceneField::Light), SceneFieldType::UnsignedInt);
CORRADE_COMPARE(scene.fieldSize(SceneField::Light), 2); CORRADE_COMPARE(scene.fieldSize(SceneField::Light), 2);
CORRADE_COMPARE(scene.fieldArraySize(SceneField::Light), 0); CORRADE_COMPARE(scene.fieldArraySize(SceneField::Light), 0);
CORRADE_COMPARE(scene.objects(SceneField::Light).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1); CORRADE_COMPARE(scene.mapping(SceneField::Light).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1);
CORRADE_COMPARE(scene.objects(SceneField::Light).stride()[0], 2); CORRADE_COMPARE(scene.mapping(SceneField::Light).stride()[0], 2);
CORRADE_COMPARE(scene.field(SceneField::Light).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1 + 2*2 + 2); CORRADE_COMPARE(scene.field(SceneField::Light).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1 + 2*2 + 2);
CORRADE_COMPARE(scene.field(SceneField::Light).stride()[0], 4); CORRADE_COMPARE(scene.field(SceneField::Light).stride()[0], 4);
CORRADE_COMPARE(scene.fieldType(sceneFieldCustom(15)), SceneFieldType::Short); CORRADE_COMPARE(scene.fieldType(sceneFieldCustom(15)), SceneFieldType::Short);
CORRADE_COMPARE(scene.fieldSize(sceneFieldCustom(15)), 2); CORRADE_COMPARE(scene.fieldSize(sceneFieldCustom(15)), 2);
CORRADE_COMPARE(scene.fieldArraySize(sceneFieldCustom(15)), 4); CORRADE_COMPARE(scene.fieldArraySize(sceneFieldCustom(15)), 4);
CORRADE_COMPARE(scene.objects(sceneFieldCustom(15)).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1 + 2*2 + 2 + 2*4); CORRADE_COMPARE(scene.mapping(sceneFieldCustom(15)).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1 + 2*2 + 2 + 2*4);
CORRADE_COMPARE(scene.objects(sceneFieldCustom(15)).stride()[0], 2); CORRADE_COMPARE(scene.mapping(sceneFieldCustom(15)).stride()[0], 2);
CORRADE_COMPARE(scene.field(sceneFieldCustom(15)).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1 + 2*2 + 2 + 2*4 + 2*2); CORRADE_COMPARE(scene.field(sceneFieldCustom(15)).data(), scene.data() + 2 + 2 + 3*2 + 3 + 1 + 2*2 + 2 + 2*4 + 2*2);
CORRADE_COMPARE(scene.field(sceneFieldCustom(15)).stride()[0], 4*2); CORRADE_COMPARE(scene.field(sceneFieldCustom(15)).stride()[0], 4*2);
} }
void SceneToolsTest::combineObjectSharedFieldPlaceholder() { void SceneToolsTest::combineObjectSharedFieldPlaceholder() {
const UnsignedInt meshObjects[]{15, 23, 47}; const UnsignedInt meshMappingData[]{15, 23, 47};
const UnsignedByte meshes[]{0, 1, 2}; const UnsignedByte meshFieldData[]{0, 1, 2};
SceneData scene = Implementation::sceneCombine(SceneObjectType::UnsignedInt, 173, Containers::arrayView({ SceneData scene = Implementation::sceneCombine(SceneMappingType::UnsignedInt, 173, Containers::arrayView({
SceneFieldData{SceneField::Mesh, Containers::arrayView(meshObjects), Containers::arrayView(meshes)}, SceneFieldData{SceneField::Mesh, Containers::arrayView(meshMappingData), Containers::arrayView(meshFieldData)},
SceneFieldData{SceneField::MeshMaterial, Containers::arrayView(meshObjects), Containers::ArrayView<Int>{nullptr, 3}}, SceneFieldData{SceneField::MeshMaterial, Containers::arrayView(meshMappingData), Containers::ArrayView<Int>{nullptr, 3}},
})); }));
CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable); CORRADE_COMPARE(scene.dataFlags(), DataFlag::Owned|DataFlag::Mutable);
CORRADE_COMPARE(scene.objectType(), SceneObjectType::UnsignedInt); CORRADE_COMPARE(scene.mappingType(), SceneMappingType::UnsignedInt);
CORRADE_COMPARE(scene.objectCount(), 173); CORRADE_COMPARE(scene.mappingBound(), 173);
CORRADE_COMPARE(scene.fieldCount(), 2); CORRADE_COMPARE(scene.fieldCount(), 2);
CORRADE_COMPARE(scene.fieldType(SceneField::Mesh), SceneFieldType::UnsignedByte); CORRADE_COMPARE(scene.fieldType(SceneField::Mesh), SceneFieldType::UnsignedByte);
CORRADE_COMPARE(scene.fieldArraySize(SceneField::Mesh), 0); CORRADE_COMPARE(scene.fieldArraySize(SceneField::Mesh), 0);
CORRADE_COMPARE_AS(scene.objects<UnsignedInt>(0), CORRADE_COMPARE_AS(scene.mapping<UnsignedInt>(0),
Containers::arrayView(meshObjects), Containers::arrayView(meshMappingData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE_AS(scene.field<UnsignedByte>(0), CORRADE_COMPARE_AS(scene.field<UnsignedByte>(0),
Containers::arrayView(meshes), Containers::arrayView(meshFieldData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE(scene.fieldType(SceneField::MeshMaterial), SceneFieldType::Int); CORRADE_COMPARE(scene.fieldType(SceneField::MeshMaterial), SceneFieldType::Int);
CORRADE_COMPARE(scene.fieldSize(SceneField::MeshMaterial), 3); CORRADE_COMPARE(scene.fieldSize(SceneField::MeshMaterial), 3);
CORRADE_COMPARE(scene.fieldArraySize(SceneField::MeshMaterial), 0); CORRADE_COMPARE(scene.fieldArraySize(SceneField::MeshMaterial), 0);
CORRADE_COMPARE(scene.objects(SceneField::MeshMaterial).data(), scene.objects(SceneField::Mesh).data()); CORRADE_COMPARE(scene.mapping(SceneField::MeshMaterial).data(), scene.mapping(SceneField::Mesh).data());
CORRADE_COMPARE_AS(scene.objects<UnsignedInt>(SceneField::MeshMaterial), CORRADE_COMPARE_AS(scene.mapping<UnsignedInt>(SceneField::MeshMaterial),
Containers::arrayView(meshObjects), Containers::arrayView(meshMappingData),
TestSuite::Compare::Container); TestSuite::Compare::Container);
CORRADE_COMPARE(scene.field(SceneField::MeshMaterial).data(), scene.data() + 3*4 + 3 + 1); CORRADE_COMPARE(scene.field(SceneField::MeshMaterial).data(), scene.data() + 3*4 + 3 + 1);
CORRADE_COMPARE(scene.field(SceneField::MeshMaterial).stride()[0], 4); CORRADE_COMPARE(scene.field(SceneField::MeshMaterial).stride()[0], 4);
@ -340,13 +340,13 @@ void SceneToolsTest::convertToSingleFunctionObjects() {
/* Haha now I can use sceneCombine() to conveniently prepare the initial /* Haha now I can use sceneCombine() to conveniently prepare the initial
state here, without having to mess with an ArrayTuple */ state here, without having to mess with an ArrayTuple */
const UnsignedShort parentObjects[]{15, 21, 22, 23, 1}; const UnsignedShort parentMappingData[]{15, 21, 22, 23, 1};
const Byte parents[]{-1, -1, 21, 22, -1}; const Byte parentFieldData[]{-1, -1, 21, 22, -1};
/* Two objects have two and three mesh assignments respectively, meaning we /* Two objects have two and three mesh assignments respectively, meaning we
need three extra */ need three extra */
const UnsignedShort meshObjects[]{15, 23, 23, 23, 1, 15, 21}; const UnsignedShort meshMappingData[]{15, 23, 23, 23, 1, 15, 21};
const Containers::Pair<UnsignedInt, Int> meshesMaterials[]{ const Containers::Pair<UnsignedInt, Int> meshMaterialFieldData[]{
{6, 4}, {6, 4},
{1, 0}, {1, 0},
{2, 3}, {2, 3},
@ -358,13 +358,13 @@ void SceneToolsTest::convertToSingleFunctionObjects() {
/* One camera is attached to an object that already has a mesh, meaning we /* One camera is attached to an object that already has a mesh, meaning we
need a third extra object */ need a third extra object */
const UnsignedShort cameraObjects[]{22, 1}; const UnsignedShort cameraMappingData[]{22, 1};
const UnsignedInt cameras[]{1, 5}; const UnsignedInt cameraFieldData[]{1, 5};
SceneData original = Implementation::sceneCombine(SceneObjectType::UnsignedShort, data.originalObjectCount, Containers::arrayView({ SceneData original = Implementation::sceneCombine(SceneMappingType::UnsignedShort, data.originalObjectCount, Containers::arrayView({
SceneFieldData{SceneField::Parent, Containers::arrayView(parentObjects), Containers::arrayView(parents)}, SceneFieldData{SceneField::Parent, Containers::arrayView(parentMappingData), Containers::arrayView(parentFieldData)},
SceneFieldData{SceneField::Mesh, Containers::arrayView(meshObjects), Containers::StridedArrayView1D<const UnsignedInt>{meshesMaterials, &meshesMaterials[0].first(), Containers::arraySize(meshesMaterials), sizeof(meshesMaterials[0])}}, SceneFieldData{SceneField::Mesh, Containers::arrayView(meshMappingData), Containers::StridedArrayView1D<const UnsignedInt>{meshMaterialFieldData, &meshMaterialFieldData[0].first(), Containers::arraySize(meshMaterialFieldData), sizeof(meshMaterialFieldData[0])}},
SceneFieldData{SceneField::MeshMaterial, Containers::arrayView(meshObjects), Containers::StridedArrayView1D<const Int>{meshesMaterials, &meshesMaterials[0].second(), Containers::arraySize(meshesMaterials), sizeof(meshesMaterials[0])}}, SceneFieldData{SceneField::MeshMaterial, Containers::arrayView(meshMappingData), Containers::StridedArrayView1D<const Int>{meshMaterialFieldData, &meshMaterialFieldData[0].second(), Containers::arraySize(meshMaterialFieldData), sizeof(meshMaterialFieldData[0])}},
SceneFieldData{SceneField::Camera, Containers::arrayView(cameraObjects), Containers::arrayView(cameras)}, SceneFieldData{SceneField::Camera, Containers::arrayView(cameraMappingData), Containers::arrayView(cameraFieldData)},
})); }));
SceneData scene = Implementation::sceneConvertToSingleFunctionObjects(original, Containers::arrayView({ SceneData scene = Implementation::sceneConvertToSingleFunctionObjects(original, Containers::arrayView({
@ -379,7 +379,7 @@ void SceneToolsTest::convertToSingleFunctionObjects() {
/* There should be three more objects, or the original count preserved if /* There should be three more objects, or the original count preserved if
it's large enough */ it's large enough */
CORRADE_COMPARE(scene.objectCount(), data.expectedObjectCount); CORRADE_COMPARE(scene.mappingBound(), data.expectedObjectCount);
/* Object 1 should have a new child that has the camera, as it has a mesh */ /* Object 1 should have a new child that has the camera, as it has a mesh */
CORRADE_COMPARE_AS(scene.childrenFor(1), CORRADE_COMPARE_AS(scene.childrenFor(1),

2
src/Magnum/Trade/Trade.h

@ -100,7 +100,7 @@ class PbrSpecularGlossinessMaterialData;
class PhongMaterialData; class PhongMaterialData;
class TextureData; class TextureData;
enum class SceneObjectType: UnsignedByte; enum class SceneMappingType: UnsignedByte;
enum class SceneField: UnsignedInt; enum class SceneField: UnsignedInt;
enum class SceneFieldType: UnsignedShort; enum class SceneFieldType: UnsignedShort;
class SceneFieldData; class SceneFieldData;

Loading…
Cancel
Save