mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
508 lines
21 KiB
508 lines
21 KiB
/* |
|
This file is part of Magnum. |
|
|
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
|
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz> |
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a |
|
copy of this software and associated documentation files (the "Software"), |
|
to deal in the Software without restriction, including without limitation |
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
and/or sell copies of the Software, and to permit persons to whom the |
|
Software is furnished to do so, subject to the following conditions: |
|
|
|
The above copyright notice and this permission notice shall be included |
|
in all copies or substantial portions of the Software. |
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
DEALINGS IN THE SOFTWARE. |
|
*/ |
|
|
|
#include <sstream> |
|
#include <Corrade/Containers/Triple.h> |
|
#include <Corrade/TestSuite/Tester.h> |
|
#include <Corrade/TestSuite/Compare/Container.h> |
|
#include <Corrade/Utility/DebugStl.h> |
|
|
|
/* There's no better way to disable file deprecation warnings */ |
|
#define _MAGNUM_NO_DEPRECATED_FLATTENMESHHIERARCHY |
|
|
|
#include "Magnum/Math/Matrix3.h" |
|
#include "Magnum/Math/Matrix4.h" |
|
#include "Magnum/SceneTools/FlattenMeshHierarchy.h" |
|
#include "Magnum/Trade/SceneData.h" |
|
|
|
namespace Magnum { namespace SceneTools { namespace Test { namespace { |
|
|
|
struct FlattenMeshHierarchyTest: TestSuite::Tester { |
|
explicit FlattenMeshHierarchyTest(); |
|
|
|
void test2D(); |
|
void test3D(); |
|
void not2DNot3D(); |
|
void noParentField(); |
|
void noMeshField(); |
|
|
|
void into2D(); |
|
void into3D(); |
|
void intoInvalidSize(); |
|
}; |
|
|
|
using namespace Math::Literals; |
|
|
|
const struct { |
|
const char* name; |
|
Matrix3 globalTransformation2D; |
|
Matrix4 globalTransformation3D; |
|
std::size_t transformationsToExclude, meshesToExclude; |
|
std::size_t expectedOutputSize; |
|
} TestData[]{ |
|
{"", {}, {}, |
|
2, 0, |
|
5}, |
|
{"global transformation", |
|
Matrix3::scaling(Vector2{0.5f}), Matrix4::scaling(Vector3{0.5f}), |
|
2, 0, |
|
5}, |
|
{"transformations not part of the hierarchy", {}, {}, |
|
0, 0, |
|
5}, |
|
{"no meshes", {}, {}, |
|
2, 5, |
|
0}, |
|
}; |
|
|
|
const struct { |
|
const char* name; |
|
Matrix3 globalTransformation2D; |
|
Matrix4 globalTransformation3D; |
|
std::size_t expectedOutputSize; |
|
} IntoData[]{ |
|
{"", {}, {}, |
|
5}, |
|
{"global transformation", |
|
Matrix3::scaling(Vector2{0.5f}), Matrix4::scaling(Vector3{0.5f}), |
|
5}, |
|
}; |
|
|
|
FlattenMeshHierarchyTest::FlattenMeshHierarchyTest() { |
|
addInstancedTests({&FlattenMeshHierarchyTest::test2D, |
|
&FlattenMeshHierarchyTest::test3D}, |
|
Containers::arraySize(TestData)); |
|
|
|
addTests({&FlattenMeshHierarchyTest::not2DNot3D, |
|
&FlattenMeshHierarchyTest::noParentField, |
|
&FlattenMeshHierarchyTest::noMeshField}); |
|
|
|
addInstancedTests({&FlattenMeshHierarchyTest::into2D, |
|
&FlattenMeshHierarchyTest::into3D}, |
|
Containers::arraySize(IntoData)); |
|
|
|
addTests({&FlattenMeshHierarchyTest::intoInvalidSize}); |
|
} |
|
|
|
const struct Scene { |
|
/* Using smaller types to verify we don't have unnecessarily hardcoded |
|
32-bit types */ |
|
struct Parent { |
|
UnsignedShort object; |
|
Byte parent; |
|
} parents[9]; |
|
|
|
struct Transformation { |
|
UnsignedShort object; |
|
Matrix3 transformation2D; |
|
Matrix4 transformation3D; |
|
} transforms[7]; |
|
|
|
struct Mesh { |
|
UnsignedShort object; |
|
UnsignedShort mesh; |
|
Short meshMaterial; |
|
} meshes[5]; |
|
} Data[]{{ |
|
/* |
|
Cases to test: |
|
|
|
- leaf paths with no attachments which don't contribute to the |
|
output in any way |
|
- nodes with transforms but no meshes |
|
- nodes with meshes but no transforms |
|
- nodes with multiple meshes |
|
- nodes with neither transforms nor meshes |
|
- object 4 has a mesh with identity transform (or, rather, no |
|
transformation entry at all) |
|
- objects 2 and 16 have the same mesh attached with the exact |
|
same transform -- this is a nonsense (they would overlap) and |
|
as such isn't deduplicated in any way |
|
- objects 0, 32 and 17 have transformations/meshes, but not part |
|
of the hierarchy; these are cut away from the views in the |
|
first test case to keep it simple |
|
|
|
1T 4M |
|
/ \ | 32M 0MM |
|
5T 2TM 11 |
|
/ \ \ | 32T 17T |
|
3MM 7T 6 16TM |
|
*/ |
|
{{3, 5}, |
|
{11, 4}, |
|
{5, 1}, |
|
{1, -1}, |
|
{7, 5}, |
|
{6, 2}, |
|
{2, 1}, |
|
{4, -1}, |
|
{16, 11}}, |
|
{{2, Matrix3::scaling({3.0f, 5.0f}), |
|
Matrix4::scaling({3.0f, 5.0f, 2.0f})}, |
|
{1, Matrix3::translation({1.0f, -1.5f}), |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})}, |
|
/* Same absolute transform as node 2 */ |
|
{16, Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::scaling({3.0f, 5.0f}), |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::scaling({3.0f, 5.0f, 2.0f})}, |
|
{7, Matrix3::scaling({2.0f, 1.0f}), |
|
Matrix4::scaling({2.0f, 1.0f, 0.5f})}, |
|
{5, Matrix3::rotation(35.0_degf), |
|
Matrix4::rotationZ(35.0_degf)}, |
|
/* These are not part of the hierarchy */ |
|
{32, Matrix3::translation({1.0f, 0.5f}), |
|
Matrix4::translation({1.0f, 0.5f, 2.0f})}, |
|
{17, Matrix3::translation({2.0f, 1.0f}), |
|
Matrix4::translation({2.0f, 1.0f, 4.0f})}, |
|
}, |
|
{{2, 113, 96}, |
|
{3, 266, 74}, |
|
{4, 525, 33}, |
|
{3, 422, -1}, |
|
{16, 113, 96}} |
|
}}; |
|
|
|
void FlattenMeshHierarchyTest::test2D() { |
|
auto&& data = TestData[testCaseInstanceId()]; |
|
setTestCaseDescription(data.name); |
|
|
|
Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 33, {}, Data, { |
|
/* To verify it doesn't just pick the first field ever */ |
|
Trade::SceneFieldData{Trade::SceneField::Camera, Trade::SceneMappingType::UnsignedShort, nullptr, Trade::SceneFieldType::UnsignedInt, nullptr}, |
|
Trade::SceneFieldData{Trade::SceneField::Parent, |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::object), |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::parent)}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::object) |
|
.exceptSuffix(data.transformationsToExclude), |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::transformation2D) |
|
.exceptSuffix(data.transformationsToExclude)}, |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::object) |
|
.exceptSuffix(data.meshesToExclude), |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::mesh) |
|
.exceptSuffix(data.meshesToExclude)}, |
|
Trade::SceneFieldData{Trade::SceneField::MeshMaterial, |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::object) |
|
.exceptSuffix(data.meshesToExclude), |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::meshMaterial) |
|
.exceptSuffix(data.meshesToExclude)}, |
|
}}; |
|
|
|
Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix3>> out; |
|
/* To test the parameter-less overload also */ |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
if(data.globalTransformation2D != Matrix3{}) |
|
out = flattenMeshHierarchy2D(scene, data.globalTransformation2D); |
|
else |
|
out = flattenMeshHierarchy2D(scene); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
|
|
CORRADE_COMPARE_AS(out, (Containers::arrayView<Containers::Triple<UnsignedInt, Int, Matrix3>>({ |
|
{113, 96, data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::scaling({3.0f, 5.0f})}, |
|
{266, 74, data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::rotation(35.0_degf)}, |
|
{525, 33, data.globalTransformation2D}, |
|
{422, -1, data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::rotation(35.0_degf)}, |
|
{113, 96, data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::scaling({3.0f, 5.0f})} |
|
})).prefix(data.expectedOutputSize), TestSuite::Compare::Container); |
|
} |
|
|
|
void FlattenMeshHierarchyTest::test3D() { |
|
auto&& data = TestData[testCaseInstanceId()]; |
|
setTestCaseDescription(data.name); |
|
|
|
Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 33, {}, Data, { |
|
/* To verify it doesn't just pick the first field ever */ |
|
Trade::SceneFieldData{Trade::SceneField::Camera, Trade::SceneMappingType::UnsignedShort, nullptr, Trade::SceneFieldType::UnsignedInt, nullptr}, |
|
Trade::SceneFieldData{Trade::SceneField::Parent, |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::object), |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::parent)}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::object) |
|
.exceptSuffix(data.transformationsToExclude), |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::transformation3D) |
|
.exceptSuffix(data.transformationsToExclude)}, |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::object) |
|
.exceptSuffix(data.meshesToExclude), |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::mesh) |
|
.exceptSuffix(data.meshesToExclude)}, |
|
Trade::SceneFieldData{Trade::SceneField::MeshMaterial, |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::object) |
|
.exceptSuffix(data.meshesToExclude), |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::meshMaterial) |
|
.exceptSuffix(data.meshesToExclude)}, |
|
}}; |
|
|
|
Containers::Array<Containers::Triple<UnsignedInt, Int, Matrix4>> out; |
|
/* To test the parameter-less overload also */ |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
if(data.globalTransformation3D != Matrix4{}) |
|
out = flattenMeshHierarchy3D(scene, data.globalTransformation3D); |
|
else |
|
out = flattenMeshHierarchy3D(scene); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
|
|
CORRADE_COMPARE_AS(out, (Containers::arrayView<Containers::Triple<UnsignedInt, Int, Matrix4>>({ |
|
{113, 96, data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::scaling({3.0f, 5.0f, 2.0f})}, |
|
{266, 74, data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::rotationZ(35.0_degf)}, |
|
{525, 33, data.globalTransformation3D}, |
|
{422, -1, data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::rotationZ(35.0_degf)}, |
|
{113, 96, data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::scaling({3.0f, 5.0f, 2.0f})} |
|
})).prefix(data.expectedOutputSize), TestSuite::Compare::Container); |
|
} |
|
|
|
void FlattenMeshHierarchyTest::not2DNot3D() { |
|
CORRADE_SKIP_IF_NO_ASSERT(); |
|
|
|
/* Used to assert even on an empty scene, now it does an early-out if the |
|
mesh field doesn't exist because flattenTransformationHierarchy() would |
|
assert instead. That behavioral change is fine for a deprecated API. */ |
|
Trade::SceneData scene{Trade::SceneMappingType::UnsignedInt, 0, nullptr, { |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::UnsignedInt, nullptr}, |
|
}}; |
|
|
|
std::ostringstream out; |
|
Error redirectError{&out}; |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
flattenMeshHierarchy2D(scene); |
|
flattenMeshHierarchy3D(scene); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
CORRADE_COMPARE(out.str(), |
|
"SceneTools::flattenTransformationHierarchy(): the scene is not 2D\n" |
|
"SceneTools::flattenTransformationHierarchy(): the scene is not 3D\n"); |
|
} |
|
|
|
void FlattenMeshHierarchyTest::noParentField() { |
|
CORRADE_SKIP_IF_NO_ASSERT(); |
|
|
|
/* Used to assert even on an empty scene, now it does an early-out if the |
|
mesh field doesn't exist because flattenTransformationHierarchy() would |
|
assert instead. That behavioral change is fine for a deprecated API. */ |
|
Trade::SceneData scene{Trade::SceneMappingType::UnsignedInt, 0, nullptr, { |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::UnsignedInt, nullptr}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix3x3, nullptr} |
|
}}; |
|
|
|
std::ostringstream out; |
|
Error redirectError{&out}; |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
flattenMeshHierarchy2D(scene); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
CORRADE_COMPARE(out.str(), |
|
"SceneTools::flattenTransformationHierarchy(): the scene has no hierarchy\n"); |
|
} |
|
|
|
void FlattenMeshHierarchyTest::noMeshField() { |
|
Trade::SceneData scene{Trade::SceneMappingType::UnsignedInt, 0, nullptr, { |
|
Trade::SceneFieldData{Trade::SceneField::Parent, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Int, nullptr}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix3x3, nullptr} |
|
}}; |
|
|
|
/* This should not blow up, just return nothing */ |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
CORRADE_COMPARE_AS(flattenMeshHierarchy2D(scene), |
|
(Containers::ArrayView<const Containers::Triple<UnsignedInt, Int, Matrix3>>{}), |
|
TestSuite::Compare::Container); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
} |
|
|
|
void FlattenMeshHierarchyTest::into2D() { |
|
auto&& data = IntoData[testCaseInstanceId()]; |
|
setTestCaseDescription(data.name); |
|
|
|
/* The *Into() variant is the actual base implementation, so just verify |
|
that the data get correctly propagated through. Everything else is |
|
tested above already. */ |
|
|
|
Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 33, {}, Data, { |
|
Trade::SceneFieldData{Trade::SceneField::Parent, |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::object), |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::parent)}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::object), |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::transformation2D)}, |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::object), |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::mesh)} |
|
}}; |
|
|
|
Containers::Array<Matrix3> out{NoInit, scene.fieldSize(Trade::SceneField::Mesh)}; |
|
/* To test the parameter-less overload also */ |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
if(data.globalTransformation2D != Matrix3{}) |
|
flattenMeshHierarchy2DInto(scene, out, data.globalTransformation2D); |
|
else |
|
flattenMeshHierarchy2DInto(scene, out); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
|
|
CORRADE_COMPARE_AS(out, Containers::arrayView<Matrix3>({ |
|
data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::scaling({3.0f, 5.0f}), |
|
data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::rotation(35.0_degf), |
|
data.globalTransformation2D, |
|
data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::rotation(35.0_degf), |
|
data.globalTransformation2D* |
|
Matrix3::translation({1.0f, -1.5f})* |
|
Matrix3::scaling({3.0f, 5.0f}) |
|
}), TestSuite::Compare::Container); |
|
} |
|
|
|
void FlattenMeshHierarchyTest::into3D() { |
|
auto&& data = IntoData[testCaseInstanceId()]; |
|
setTestCaseDescription(data.name); |
|
|
|
/* The *Into() variant is the actual base implementation, so just verify |
|
that the data get correctly propagated through. Everything else is |
|
tested above already. */ |
|
|
|
Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 33, {}, Data, { |
|
Trade::SceneFieldData{Trade::SceneField::Parent, |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::object), |
|
Containers::stridedArrayView(Data->parents) |
|
.slice(&Scene::Parent::parent)}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::object), |
|
Containers::stridedArrayView(Data->transforms) |
|
.slice(&Scene::Transformation::transformation3D)}, |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::object), |
|
Containers::stridedArrayView(Data->meshes) |
|
.slice(&Scene::Mesh::mesh)} |
|
}}; |
|
|
|
Containers::Array<Matrix4> out{NoInit, scene.fieldSize(Trade::SceneField::Mesh)}; |
|
/* To test the parameter-less overload also */ |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
if(data.globalTransformation3D != Matrix4{}) |
|
flattenMeshHierarchy3DInto(scene, out, data.globalTransformation3D); |
|
else |
|
flattenMeshHierarchy3DInto(scene, out); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
|
|
CORRADE_COMPARE_AS(out, Containers::arrayView<Matrix4>({ |
|
data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::scaling({3.0f, 5.0f, 2.0f}), |
|
data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::rotationZ(35.0_degf), |
|
data.globalTransformation3D, |
|
data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::rotationZ(35.0_degf), |
|
data.globalTransformation3D* |
|
Matrix4::translation({1.0f, -1.5f, 0.5f})* |
|
Matrix4::scaling({3.0f, 5.0f, 2.0f}) |
|
}), TestSuite::Compare::Container); |
|
} |
|
|
|
void FlattenMeshHierarchyTest::intoInvalidSize() { |
|
CORRADE_SKIP_IF_NO_ASSERT(); |
|
|
|
struct Data { |
|
UnsignedInt mapping; |
|
UnsignedInt mesh; |
|
} data[5]{}; |
|
|
|
Trade::SceneData scene2D{Trade::SceneMappingType::UnsignedInt, 1, {}, data, { |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, |
|
Containers::stridedArrayView(data).slice(&Data::mapping), |
|
Containers::stridedArrayView(data).slice(&Data::mesh)}, |
|
Trade::SceneFieldData{Trade::SceneField::Parent, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Int, nullptr}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix3x3, nullptr} |
|
}}; |
|
Trade::SceneData scene3D{Trade::SceneMappingType::UnsignedInt, 1, {}, data, { |
|
Trade::SceneFieldData{Trade::SceneField::Mesh, |
|
Containers::stridedArrayView(data).slice(&Data::mapping), |
|
Containers::stridedArrayView(data).slice(&Data::mesh)}, |
|
Trade::SceneFieldData{Trade::SceneField::Parent, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Int, nullptr}, |
|
Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix4x4, nullptr} |
|
}}; |
|
|
|
Matrix3 transformations2D[6]; |
|
Matrix4 transformations3D[4]; |
|
|
|
std::ostringstream out; |
|
Error redirectError{&out}; |
|
CORRADE_IGNORE_DEPRECATED_PUSH |
|
flattenMeshHierarchy2DInto(scene2D, transformations2D); |
|
flattenMeshHierarchy3DInto(scene3D, transformations3D); |
|
CORRADE_IGNORE_DEPRECATED_POP |
|
CORRADE_COMPARE(out.str(), |
|
"SceneTools::flattenTransformationHierarchyInto(): bad output size, expected 5 but got 6\n" |
|
"SceneTools::flattenTransformationHierarchyInto(): bad output size, expected 5 but got 4\n"); |
|
} |
|
|
|
}}}} |
|
|
|
CORRADE_TEST_MAIN(Magnum::SceneTools::Test::FlattenMeshHierarchyTest)
|
|
|