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. 1642
      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.
- @ref Trade::SceneData constructor taking a @ref std::vector of 2D and 3D
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.
- @cpp Trade::SceneData::children2D() @ce and
@cpp Trade::SceneData::children3D() @ce are deprecated in favor of the
@ -828,7 +828,7 @@ See also:
desired use case anymore.
- @ref Trade::SceneData constructor taking a @ref std::vector of 2D and 3D
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.
- The deprecated @cpp Trade::AbstractImporter::object*DCount() @ce,
@cpp Trade::AbstractImporter::object*DForName() @ce,

10
src/Magnum/MeshTools/sceneconverter.cpp

@ -386,8 +386,8 @@ used.)")
struct SceneInfo {
UnsignedInt scene;
Trade::SceneObjectType objectType;
UnsignedLong objectCount;
Trade::SceneMappingType mappingType;
UnsignedLong mappingBound;
Containers::Array<SceneFieldInfo> fields;
std::size_t dataSize;
std::string name;
@ -410,8 +410,8 @@ used.)")
SceneInfo info{};
info.scene = i;
info.objectType = scene->objectType();
info.objectCount = scene->objectCount();
info.mappingType = scene->mappingType();
info.mappingBound = scene->mappingBound();
info.dataSize = scene->data().size();
info.name = importer->sceneName(i);
for(UnsignedInt j = 0; j != scene->fieldCount(); ++j) {
@ -666,7 +666,7 @@ used.)")
d << "Scene" << info.scene << Debug::nospace << ":";
if(!info.name.empty()) d << info.name;
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)";
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
the restriction for unique-functioning objects. */
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())
_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
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) {
if(!_cachedScenes->scenes[i] ||
!_cachedScenes->scenes[i]->is2D() ||
_cachedScenes->scenes[i]->objectCount() <= id)
_cachedScenes->scenes[i]->mappingBound() <= id)
continue;
if(Containers::Optional<Int> parent = _cachedScenes->scenes[i]->parentFor(id))
@ -643,7 +643,7 @@ Containers::Pointer<ObjectData2D> AbstractImporter::doObject2D(const UnsignedInt
populateCachedScenes();
/* 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
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
@ -652,7 +652,7 @@ Containers::Pointer<ObjectData2D> AbstractImporter::doObject2D(const UnsignedInt
std::size_t sceneCandidate = ~std::size_t{};
for(std::size_t i = 0; i != _cachedScenes->scenes.size(); ++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;
break;
}
@ -796,7 +796,7 @@ std::string AbstractImporter::doObject3DName(const UnsignedInt id) {
for(UnsignedInt i = 0; i != _cachedScenes->scenes.size(); ++i) {
if(!_cachedScenes->scenes[i] ||
!_cachedScenes->scenes[i]->is3D() ||
_cachedScenes->scenes[i]->objectCount() <= id)
_cachedScenes->scenes[i]->mappingBound() <= id)
continue;
if(Containers::Optional<Int> parent = _cachedScenes->scenes[i]->parentFor(id))
@ -821,7 +821,7 @@ Containers::Pointer<ObjectData3D> AbstractImporter::doObject3D(const UnsignedInt
populateCachedScenes();
/* 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
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
@ -830,7 +830,7 @@ Containers::Pointer<ObjectData3D> AbstractImporter::doObject3D(const UnsignedInt
std::size_t sceneCandidate = ~std::size_t{};
for(std::size_t i = 0; i != _cachedScenes->scenes.size(); ++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;
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
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]);
if(fields[i].objectType() == SceneObjectType::UnsignedByte)
if(fields[i].mappingType() == SceneMappingType::UnsignedByte)
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);
else if(fields[i].objectType() == SceneObjectType::UnsignedInt)
else if(fields[i].mappingType() == SceneMappingType::UnsignedInt)
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);
else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
}
}
/* Combine fields of varying object type together into a SceneData of a single
given objectType. The fields are expected to point to existing object/field
memory, which will be then copied to the resulting scene. If you supply a
field with null object or field data, the object or field data will not get
copied, only a placeholder for copying the data later will be allocated. If
you however need to have placeholder object data shared among
Offset-only fields are not allowed.
/* Combine fields of varying mapping type together into a SceneData of a single
given mappingType. The fields are expected to point to existing
mapping/field memory, which will be then copied to the resulting scene. If
you supply a field with null mapping or field data, the mapping or field
data will not get copied, only a placeholder for copying the data later will
be allocated. If you however need to have placeholder mapping data shared
among multiple fields you have to allocate them upfront. Offset-only fields
are not allowed.
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. */
/** @todo when published, add an initializer_list overload and turn all
internal asserts into (tested!) message asserts */
inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLong objectCount, const Containers::ArrayView<const SceneFieldData> fields) {
const std::size_t objectTypeSize = sceneObjectTypeSize(objectType);
const std::size_t objectTypeAlignment = sceneObjectTypeAlignment(objectType);
inline SceneData sceneCombine(const SceneMappingType mappingType, const UnsignedLong mappingBound, const Containers::ArrayView<const SceneFieldData> fields) {
const std::size_t mappingTypeSize = sceneMappingTypeSize(mappingType);
const std::size_t mappingTypeAlignment = sceneMappingTypeAlignment(mappingType);
/* Go through all fields and collect ArrayTuple allocations for these */
std::unordered_map<const void*, UnsignedInt> objectMappings;
@ -110,12 +111,12 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
const SceneFieldData& field = fields[i];
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. */
std::pair<std::unordered_map<const void*, UnsignedInt>::iterator, bool> inserted;
if(field.objectData().data())
inserted = objectMappings.emplace(field.objectData().data(), itemViewOffset);
if(field.objectData().data() && !inserted.second) {
if(field.mappingData().data())
inserted = objectMappings.emplace(field.mappingData().data(), itemViewOffset);
if(field.mappingData().data() && !inserted.second) {
itemViewMappings[i].first() = inserted.first->second;
/* Expect that fields sharing the same object mapping view have the
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());
} else {
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;
}
@ -162,13 +163,13 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
CORRADE_INTERNAL_ASSERT(!outData.deleter());
/* Copy the object data over and cast them as necessary */
if(objectType == SceneObjectType::UnsignedByte)
if(mappingType == SceneMappingType::UnsignedByte)
sceneCombineCopyObjects<UnsignedByte>(fields, itemViews, itemViewMappings);
else if(objectType == SceneObjectType::UnsignedShort)
else if(mappingType == SceneMappingType::UnsignedShort)
sceneCombineCopyObjects<UnsignedShort>(fields, itemViews, itemViewMappings);
else if(objectType == SceneObjectType::UnsignedInt)
else if(mappingType == SceneMappingType::UnsignedInt)
sceneCombineCopyObjects<UnsignedInt>(fields, itemViews, itemViewMappings);
else if(objectType == SceneObjectType::UnsignedLong)
else if(mappingType == SceneMappingType::UnsignedLong)
sceneCombineCopyObjects<UnsignedLong>(fields, itemViews, itemViewMappings);
/* 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()};
}
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
@ -205,7 +206,7 @@ inline SceneData sceneCombine(const SceneObjectType objectType, const UnsignedLo
internal asserts into (tested!) message asserts */
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) */
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) {
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
once this is more than a private backwards-compatibility utility
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());
++objectAttachmentCount[object];
}
@ -249,25 +250,25 @@ inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Con
}
/* 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 */
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);
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 */
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));
for(std::size_t i = 0; i != newParentObjects.size(); ++i) {
newParentObjects[i] = newObjectOffset + i;
for(std::size_t i = 0; i != newParentMapping.size(); ++i) {
newParentMapping[i] = newObjectOffset + i;
newParents[i] = -1;
}
/* Clear the objectAttachmentCount array to reuse it below */
/** @todo use a BitArray instead once it exists? */
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
children */
@ -277,7 +278,7 @@ inline SceneData sceneConvertToSingleFunctionObjects(const SceneData& scene, Con
const Containers::Optional<UnsignedInt> fieldId = scene.findFieldId(field);
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
mapping array is shared among multiple fields, in which case
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 */
newParents[newParentIndex] = fieldObject;
/* Assign the field to the new object */
fieldObject = newParentObjects[newParentIndex];
fieldObject = newParentMapping[newParentIndex];
/* Move to the next reserved object */
++newParentIndex;
} 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 {
if(id == 7)
return SceneData{SceneObjectType::UnsignedByte, 0, nullptr, {}, &state};
return SceneData{SceneObjectType::UnsignedByte, 0, nullptr, {}};
return SceneData{SceneMappingType::UnsignedByte, 0, nullptr, {}, &state};
return SceneData{SceneMappingType::UnsignedByte, 0, nullptr, {}};
}
} importer;
@ -1899,21 +1899,21 @@ void AbstractImporterTest::sceneDeprecatedFallback2D() {
/* This one has seven objects, but no fields for them so it should
get skipped */
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
without even querying any fieldFor() API (as those would
assert) */
if(id == 1)
return SceneData{SceneObjectType::UnsignedShort, 0, nullptr, {}};
return SceneData{SceneMappingType::UnsignedShort, 0, nullptr, {}};
/* This one is the one */
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();
}
private:
SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 7, std::move(data), {
} importer{SceneData{SceneMappingType::UnsignedInt, 7, std::move(data), {
SceneFieldData{SceneField::Parent,
transformations.slice(&Transform::object),
transformations.slice(&Transform::parent)},
@ -2171,21 +2171,21 @@ void AbstractImporterTest::sceneDeprecatedFallback3D() {
/* This one has seven objects, but no fields for them so it should
get skipped */
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
without even querying any fieldFor() API (as those would
assert) */
if(id == 1)
return SceneData{SceneObjectType::UnsignedShort, 0, nullptr, {}};
return SceneData{SceneMappingType::UnsignedShort, 0, nullptr, {}};
/* This one is the one */
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();
}
private:
SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 7, std::move(data), {
} importer{SceneData{SceneMappingType::UnsignedInt, 7, std::move(data), {
SceneFieldData{SceneField::Parent,
transformations.slice(&Transform::object),
transformations.slice(&Transform::parent)},
@ -2356,12 +2356,12 @@ void AbstractImporterTest::sceneDeprecatedFallbackParentless2D() {
UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; }
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:
SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, {
} importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Transformation,
view.slice(&Field::object),
view.slice(&Field::transformation)}
@ -2431,12 +2431,12 @@ void AbstractImporterTest::sceneDeprecatedFallbackParentless3D() {
UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; }
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:
SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, {
} importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Transformation,
view.slice(&Field::object),
view.slice(&Field::transformation)}
@ -2506,17 +2506,17 @@ void AbstractImporterTest::sceneDeprecatedFallbackTransformless2D() {
UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; }
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:
SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, {
} importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Parent,
view.slice(&Field::object),
view.slice(&Field::parent)},
/* 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);
@ -2612,17 +2612,17 @@ void AbstractImporterTest::sceneDeprecatedFallbackTransformless3D() {
UnsignedInt doSceneCount() const override { return 1; }
UnsignedLong doObjectCount() const override { return 6; }
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:
SceneData _data;
} importer{SceneData{SceneObjectType::UnsignedInt, 6, {}, fields, {
} importer{SceneData{SceneMappingType::UnsignedInt, 6, {}, fields, {
SceneFieldData{SceneField::Parent,
view.slice(&Field::object),
view.slice(&Field::parent)},
/* 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);
@ -2747,20 +2747,20 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects2D() {
{30, 1, -1}
}, 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::Mesh, meshes.slice(&Mesh::object), meshes.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshes.slice(&Mesh::object), meshes.slice(&Mesh::meshMaterial)},
SceneFieldData{SceneField::Camera, cameras.slice(&Camera::object), cameras.slice(&Camera::camera)},
/* 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::Mesh, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::meshMaterial)},
/* 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 {
@ -2784,19 +2784,19 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects2D() {
/* This scene should get skipped when querying names as it's not
2D */
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
little objects */
if(id == 1)
return SceneData{SceneObjectType::UnsignedByte, 32, nullptr, {
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedByte, nullptr, SceneFieldType::Matrix3x3, nullptr}
return SceneData{SceneMappingType::UnsignedByte, 32, nullptr, {
SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedByte, nullptr, SceneFieldType::Matrix3x3, nullptr}
}};
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
newly added objects */
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();
}
@ -3014,20 +3014,20 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects3D() {
{30, 1, -1}
}, 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::Mesh, meshes.slice(&Mesh::object), meshes.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshes.slice(&Mesh::object), meshes.slice(&Mesh::meshMaterial)},
SceneFieldData{SceneField::Camera, cameras.slice(&Camera::object), cameras.slice(&Camera::camera)},
/* 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::Mesh, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::mesh)},
SceneFieldData{SceneField::MeshMaterial, meshesSecondary.slice(&Mesh::object), meshesSecondary.slice(&Mesh::meshMaterial)},
/* 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 {
@ -3051,19 +3051,19 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects3D() {
/* This scene should get skipped when querying names as it's not
2D */
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
little objects */
if(id == 1)
return SceneData{SceneObjectType::UnsignedByte, 32, nullptr, {
SceneFieldData{SceneField::Transformation, SceneObjectType::UnsignedByte, nullptr, SceneFieldType::Matrix4x4, nullptr}
return SceneData{SceneMappingType::UnsignedByte, 32, nullptr, {
SceneFieldData{SceneField::Transformation, SceneMappingType::UnsignedByte, nullptr, SceneFieldType::Matrix4x4, nullptr}
}};
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
newly added objects */
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();
}
@ -3282,13 +3282,13 @@ void AbstractImporterTest::sceneDeprecatedFallbackBoth2DAnd3DScene() {
return {};
}
Containers::Optional<SceneData> doScene(UnsignedInt id) override {
if(id == 0) return SceneData{SceneObjectType::UnsignedInt, 7, nullptr, {
SceneFieldData{SceneField::Parent, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr},
SceneFieldData{SceneField::Translation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Vector2, nullptr},
if(id == 0) return SceneData{SceneMappingType::UnsignedInt, 7, nullptr, {
SceneFieldData{SceneField::Parent, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr},
SceneFieldData{SceneField::Translation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Vector2, nullptr},
}};
if(id == 1) return SceneData{SceneObjectType::UnsignedInt, 7, nullptr, {
SceneFieldData{SceneField::Parent, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr},
SceneFieldData{SceneField::Translation, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Vector3, nullptr},
if(id == 1) return SceneData{SceneMappingType::UnsignedInt, 7, nullptr, {
SceneFieldData{SceneField::Parent, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr},
SceneFieldData{SceneField::Translation, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Vector3, nullptr},
}};
CORRADE_INTERNAL_ASSERT_UNREACHABLE();
}
@ -3432,14 +3432,14 @@ void AbstractImporterTest::sceneNonOwningDeleters() {
UnsignedInt doSceneCount() const override { return 1; }
Containers::Optional<SceneData> doScene(UnsignedInt) override {
return SceneData{SceneObjectType::UnsignedInt, 0,
return SceneData{SceneMappingType::UnsignedInt, 0,
Containers::Array<char>{data, 1, Implementation::nonOwnedArrayDeleter},
sceneFieldDataNonOwningArray(fields)};
}
char data[1];
SceneFieldData fields[1]{
SceneFieldData{SceneField::Parent, SceneObjectType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr}
SceneFieldData{SceneField::Parent, SceneMappingType::UnsignedInt, nullptr, SceneFieldType::Int, nullptr}
};
} importer;
@ -3462,7 +3462,7 @@ void AbstractImporterTest::sceneCustomDataDeleter() {
UnsignedInt doSceneCount() const override { return 1; }
Int doSceneForName(const std::string&) override { return 0; }
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) {}},
{}};
}
@ -3493,10 +3493,10 @@ void AbstractImporterTest::sceneCustomFieldDataDeleter() {
UnsignedInt doSceneCount() const override { return 1; }
Int doSceneForName(const std::string&) override { return 0; }
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;
std::ostringstream out;

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

2
src/Magnum/Trade/Trade.h

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

Loading…
Cancel
Save