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.
786 lines
32 KiB
786 lines
32 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/StridedArrayView.h> |
|
#include <Corrade/TestSuite/Tester.h> |
|
#include <Corrade/TestSuite/Compare/Container.h> |
|
#include <Corrade/Utility/DebugStl.h> |
|
|
|
#include "Magnum/Math/Color.h" |
|
#include "Magnum/Math/Packing.h" |
|
#include "Magnum/Math/PackingBatch.h" |
|
#include "Magnum/Math/Vector4.h" |
|
|
|
namespace Magnum { namespace Math { namespace Test { namespace { |
|
|
|
struct PackingBatchTest: Corrade::TestSuite::Tester { |
|
explicit PackingBatchTest(); |
|
|
|
void unpackUnsignedByte(); |
|
void unpackUnsignedShort(); |
|
void unpackSignedByte(); |
|
void unpackSignedShort(); |
|
void packUnsignedByte(); |
|
void packUnsignedShort(); |
|
void packSignedByte(); |
|
void packSignedShort(); |
|
|
|
void unpackHalf(); |
|
void packHalf(); |
|
|
|
template<class FloatingPoint, class Integral> void castUnsignedFloatingPoint(); |
|
template<class FloatingPoint, class Integral> void castSignedFloatingPoint(); |
|
|
|
template<class T, class U> void castUnsignedInteger(); |
|
template<class T, class U> void castSignedInteger(); |
|
template<class T, class U> void castFloatDouble(); |
|
|
|
template<class T> void assertionsPackUnpack(); |
|
void assertionsPackUnpackHalf(); |
|
template<class U, class T> void assertionsCast(); |
|
}; |
|
|
|
PackingBatchTest::PackingBatchTest() { |
|
addTests({&PackingBatchTest::unpackUnsignedByte, |
|
&PackingBatchTest::unpackUnsignedShort, |
|
&PackingBatchTest::unpackSignedByte, |
|
&PackingBatchTest::unpackSignedShort, |
|
&PackingBatchTest::packUnsignedByte, |
|
&PackingBatchTest::packUnsignedShort, |
|
&PackingBatchTest::packSignedByte, |
|
&PackingBatchTest::packSignedShort, |
|
|
|
&PackingBatchTest::unpackHalf, |
|
&PackingBatchTest::packHalf, |
|
|
|
&PackingBatchTest::castUnsignedFloatingPoint<Float, UnsignedByte>, |
|
&PackingBatchTest::castUnsignedFloatingPoint<Float, UnsignedShort>, |
|
&PackingBatchTest::castUnsignedFloatingPoint<Float, UnsignedInt>, |
|
&PackingBatchTest::castUnsignedFloatingPoint<Double, UnsignedByte>, |
|
&PackingBatchTest::castUnsignedFloatingPoint<Double, UnsignedShort>, |
|
&PackingBatchTest::castUnsignedFloatingPoint<Double, UnsignedInt>, |
|
&PackingBatchTest::castSignedFloatingPoint<Float, Byte>, |
|
&PackingBatchTest::castSignedFloatingPoint<Float, Short>, |
|
&PackingBatchTest::castSignedFloatingPoint<Float, Int>, |
|
&PackingBatchTest::castSignedFloatingPoint<Double, Byte>, |
|
&PackingBatchTest::castSignedFloatingPoint<Double, Short>, |
|
&PackingBatchTest::castSignedFloatingPoint<Double, Int>, |
|
|
|
&PackingBatchTest::castUnsignedInteger<UnsignedByte, UnsignedByte>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedByte, UnsignedShort>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedByte, UnsignedInt>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedShort, UnsignedShort>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedShort, UnsignedInt>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedInt, UnsignedInt>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedByte, UnsignedLong>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedShort, UnsignedLong>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedInt, UnsignedLong>, |
|
&PackingBatchTest::castUnsignedInteger<UnsignedLong, UnsignedLong>, |
|
&PackingBatchTest::castSignedInteger<Byte, Byte>, |
|
&PackingBatchTest::castSignedInteger<Byte, Short>, |
|
&PackingBatchTest::castSignedInteger<Byte, Int>, |
|
&PackingBatchTest::castSignedInteger<Short, Short>, |
|
&PackingBatchTest::castSignedInteger<Short, Int>, |
|
&PackingBatchTest::castSignedInteger<Int, Int>, |
|
&PackingBatchTest::castSignedInteger<Byte, Long>, |
|
&PackingBatchTest::castSignedInteger<Short, Long>, |
|
&PackingBatchTest::castSignedInteger<Int, Long>, |
|
&PackingBatchTest::castSignedInteger<Long, Long>, |
|
&PackingBatchTest::castFloatDouble<Float, Double>, |
|
&PackingBatchTest::castFloatDouble<Float, Float>, |
|
&PackingBatchTest::castFloatDouble<Double, Double>, |
|
|
|
&PackingBatchTest::assertionsPackUnpack<UnsignedByte>, |
|
&PackingBatchTest::assertionsPackUnpack<Byte>, |
|
&PackingBatchTest::assertionsPackUnpack<UnsignedShort>, |
|
&PackingBatchTest::assertionsPackUnpack<Short>, |
|
&PackingBatchTest::assertionsPackUnpackHalf, |
|
&PackingBatchTest::assertionsCast<Float, UnsignedByte>, |
|
&PackingBatchTest::assertionsCast<Float, Byte>, |
|
&PackingBatchTest::assertionsCast<Float, UnsignedShort>, |
|
&PackingBatchTest::assertionsCast<Float, Short>, |
|
&PackingBatchTest::assertionsCast<Float, UnsignedInt>, |
|
&PackingBatchTest::assertionsCast<Float, Int>, |
|
&PackingBatchTest::assertionsCast<Double, UnsignedByte>, |
|
&PackingBatchTest::assertionsCast<Double, Byte>, |
|
&PackingBatchTest::assertionsCast<Double, UnsignedShort>, |
|
&PackingBatchTest::assertionsCast<Double, Short>, |
|
&PackingBatchTest::assertionsCast<Double, UnsignedInt>, |
|
&PackingBatchTest::assertionsCast<Double, Int>, |
|
&PackingBatchTest::assertionsCast<UnsignedByte, UnsignedByte>, |
|
&PackingBatchTest::assertionsCast<UnsignedShort, UnsignedByte>, |
|
&PackingBatchTest::assertionsCast<UnsignedShort, UnsignedShort>, |
|
&PackingBatchTest::assertionsCast<UnsignedInt, UnsignedByte>, |
|
&PackingBatchTest::assertionsCast<UnsignedInt, UnsignedShort>, |
|
&PackingBatchTest::assertionsCast<UnsignedInt, UnsignedInt>, |
|
&PackingBatchTest::assertionsCast<UnsignedLong, UnsignedByte>, |
|
&PackingBatchTest::assertionsCast<UnsignedLong, UnsignedShort>, |
|
&PackingBatchTest::assertionsCast<UnsignedLong, UnsignedInt>, |
|
&PackingBatchTest::assertionsCast<UnsignedLong, UnsignedLong>, |
|
&PackingBatchTest::assertionsCast<Byte, Byte>, |
|
&PackingBatchTest::assertionsCast<Short, Byte>, |
|
&PackingBatchTest::assertionsCast<Short, Short>, |
|
&PackingBatchTest::assertionsCast<Int, Byte>, |
|
&PackingBatchTest::assertionsCast<Int, Short>, |
|
&PackingBatchTest::assertionsCast<Int, Int>, |
|
&PackingBatchTest::assertionsCast<Long, Byte>, |
|
&PackingBatchTest::assertionsCast<Long, Short>, |
|
&PackingBatchTest::assertionsCast<Long, Int>, |
|
&PackingBatchTest::assertionsCast<Long, Long>, |
|
&PackingBatchTest::assertionsCast<Float, Float>, |
|
&PackingBatchTest::assertionsCast<Double, Float>, |
|
&PackingBatchTest::assertionsCast<Double, Double>}); |
|
} |
|
|
|
typedef Math::Constants<Float> Constants; |
|
typedef Math::Vector2<UnsignedByte> Vector2ub; |
|
typedef Math::Vector2<UnsignedShort> Vector2us; |
|
typedef Math::Vector2<Byte> Vector2b; |
|
typedef Math::Vector2<Short> Vector2s; |
|
typedef Math::Vector2<Float> Vector2; |
|
typedef Math::Vector2<UnsignedInt> Vector2ui; |
|
typedef Math::Vector2<Int> Vector2i; |
|
typedef Math::Vector3<Float> Vector3; |
|
typedef Math::Vector4<UnsignedShort> Vector4us; |
|
typedef Math::Vector4<Float> Vector4; |
|
|
|
void PackingBatchTest::unpackUnsignedByte() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2ub src; |
|
Vector2 dst; |
|
} data[]{ |
|
{{0, 89}, {}}, |
|
{{149, 255}, {}}, |
|
{{0, 255}, {}} |
|
}; |
|
|
|
constexpr Vector2 expected[] { |
|
{0.0f, 0.34902f}, |
|
{0.584314f, 1.0f}, |
|
{0.0f, 1.0f} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2ub> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
unpackInto(Corrade::Containers::arrayCast<2, UnsignedByte>(src), |
|
Corrade::Containers::arrayCast<2, Float>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::unpack<Vector2>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::unpackUnsignedShort() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2us src; |
|
Vector2 dst; |
|
} data[]{ |
|
{{0, 8192}, {}}, |
|
{{49152, 65535}, {}}, |
|
{{0, 65535}, {}} |
|
}; |
|
|
|
constexpr Vector2 expected[] { |
|
{0.0f, 0.125002f}, |
|
{0.750011f, 1.0f}, |
|
{0.0f, 1.0f} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2us> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
unpackInto(Corrade::Containers::arrayCast<2, UnsignedShort>(src), |
|
Corrade::Containers::arrayCast<2, Float>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::unpack<Vector2>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::unpackSignedByte() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2b src; |
|
Vector2 dst; |
|
} data[]{ |
|
{{0, 127}, {}}, |
|
{{37, -72}, {}}, |
|
{{-127, -128}, {}} |
|
}; |
|
|
|
constexpr Vector2 expected[] { |
|
{0.0f, 1.0f}, |
|
{0.291339f, -0.566929f}, |
|
{-1.0f, -1.0f} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2b> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
unpackInto(Corrade::Containers::arrayCast<2, Byte>(src), |
|
Corrade::Containers::arrayCast<2, Float>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::unpack<Vector2>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::unpackSignedShort() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2s src; |
|
Vector2 dst; |
|
} data[]{ |
|
{{0, 16384}, {}}, |
|
{{-16384, 32767}, {}}, |
|
{{-32767, -32768}, {}} |
|
}; |
|
|
|
constexpr Vector2 expected[] { |
|
{0.0f, 0.500015f}, |
|
{-0.500015f, 1.0f}, |
|
{-1.0f, -1.0f} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2s> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
unpackInto(Corrade::Containers::arrayCast<2, Short>(src), |
|
Corrade::Containers::arrayCast<2, Float>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::unpack<Vector2>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::packUnsignedByte() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2 src; |
|
Vector2ub dst; |
|
} data[]{ |
|
{{0.0f, 0.0000001f}, {}}, |
|
{{0.4357f, 0.5f}, {}}, |
|
{{1.0f, 0.9999999f}, {}} |
|
}; |
|
|
|
constexpr Vector2ub expected[] { |
|
{0, 0}, |
|
{111, 128}, |
|
{255, 255} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2ub> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
packInto(Corrade::Containers::arrayCast<2, Float>(src), |
|
Corrade::Containers::arrayCast<2, UnsignedByte>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::pack<Vector2ub>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::packUnsignedShort() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2 src; |
|
Vector2us dst; |
|
} data[]{ |
|
{{0.0f, 0.0000001f}, {}}, |
|
{{0.4357f, 0.5f}, {}}, |
|
{{1.0f, 0.9999999f}, {}} |
|
}; |
|
|
|
constexpr Vector2us expected[] { |
|
{0, 0}, |
|
{28554, 32768}, |
|
{65535, 65535} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2us> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
packInto(Corrade::Containers::arrayCast<2, Float>(src), |
|
Corrade::Containers::arrayCast<2, UnsignedShort>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::pack<Vector2us>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::packSignedByte() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2 src; |
|
Vector2b dst; |
|
} data[]{ |
|
{{-1.0f, -0.732f}, {}}, |
|
{{0.0f, 0.1357f}, {}}, |
|
{{1.0f, 0.9999999f}, {}} |
|
}; |
|
|
|
constexpr Vector2b expected[] { |
|
{-127, -93}, |
|
{0, 17}, |
|
{127, 127} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2b> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
packInto(Corrade::Containers::arrayCast<2, Float>(src), |
|
Corrade::Containers::arrayCast<2, Byte>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::pack<Vector2b>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::packSignedShort() { |
|
/* Test data adapted from PackingTest */ |
|
struct Data { |
|
Vector2 src; |
|
Vector2s dst; |
|
} data[]{ |
|
{{-1.0f, -0.33f}, {}}, |
|
{{0.0f, 0.66f}, {}}, |
|
{{1.0f, 0.9999999f}, {}} |
|
}; |
|
|
|
constexpr Vector2s expected[] { |
|
{-32767, -10813}, |
|
{0, 21626}, |
|
{32767, 32767} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2s> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
packInto(Corrade::Containers::arrayCast<2, Float>(src), |
|
Corrade::Containers::arrayCast<2, Short>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::pack<Vector2s>(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::unpackHalf() { |
|
/* Test data adapted from HalfTest */ |
|
struct Data { |
|
Vector2us src; |
|
Vector2 dst; |
|
} data[]{ |
|
{{0, 0x3c00}, {}}, |
|
{{0x4000, 0x4200}, {}}, |
|
{{0x8dc2, 0x57bc}, {}}, |
|
{{0xfc00, 0x7c00}, {}} |
|
}; |
|
|
|
constexpr Vector2 expected[] { |
|
{0.0f, 1.0f}, |
|
{2.0f, 3.0f}, |
|
{-0.000351f, 123.75f}, |
|
{-Constants::inf(), +Constants::inf()} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2us> src{data, &data[0].src, |
|
Corrade::Containers::arraySize(data), sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2> dst{data, &data[0].dst, |
|
Corrade::Containers::arraySize(data), sizeof(Data)}; |
|
unpackHalfInto(Corrade::Containers::arrayCast<2, UnsignedShort>(src), |
|
Corrade::Containers::arrayCast<2, Float>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::unpackHalf(data[i].src), data[i].dst); |
|
} |
|
|
|
void PackingBatchTest::packHalf() { |
|
/* Test data adapted from HalfTest */ |
|
struct Data { |
|
Vector2 src; |
|
Vector2us dst; |
|
} data[]{ |
|
{{0.0f, 1.0f}, {}}, |
|
{{2.0f, 3.0f}, {}}, |
|
{{-0.000351512f, 123.75f}, {}}, |
|
{{-Constants::inf(), +Constants::inf()}, {}} |
|
}; |
|
|
|
constexpr Vector2us expected[] { |
|
{0, 0x3c00}, |
|
{0x4000, 0x4200}, |
|
{0x8dc2, 0x57bc}, |
|
{0xfc00, 0x7c00} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Vector2> src{data, &data[0].src, |
|
Corrade::Containers::arraySize(data), sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Vector2us> dst{data, &data[0].dst, |
|
Corrade::Containers::arraySize(data), sizeof(Data)}; |
|
packHalfInto(Corrade::Containers::arrayCast<2, Float>(src), |
|
Corrade::Containers::arrayCast<2, UnsignedShort>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expected), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Ensure the results are consistent with non-batch APIs */ |
|
for(std::size_t i = 0; i != Corrade::Containers::arraySize(data); ++i) |
|
CORRADE_COMPARE(Math::packHalf(data[i].src), data[i].dst); |
|
} |
|
|
|
template<class FloatingPoint, class Integral> void PackingBatchTest::castUnsignedFloatingPoint() { |
|
setTestCaseTemplateName({TypeTraits<FloatingPoint>::name(), TypeTraits<Integral>::name()}); |
|
|
|
struct Data { |
|
Math::Vector2<Integral> src; |
|
Math::Vector2<FloatingPoint> dst; |
|
} data[]{ |
|
{{0, 89}, {}}, |
|
{{149, 22}, {}}, |
|
{{13, 255}, {}} |
|
}; |
|
|
|
/* GCC 4.8 doesn't like constexpr here (cannot initialize aggregate of type |
|
‘const Vector2 [3]’ with a compound literal), wtf */ |
|
const Math::Vector2<FloatingPoint> expectedFloatingPoint[] { |
|
{FloatingPoint(0.0), FloatingPoint(89.0)}, |
|
{FloatingPoint(149.0), FloatingPoint(22.0)}, |
|
{FloatingPoint(13.0), FloatingPoint(255.0)} |
|
}; |
|
|
|
constexpr Math::Vector2<Integral> expectedIntegral[] { |
|
{0, 89}, |
|
{149, 22}, |
|
{13, 255} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<Integral>> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<FloatingPoint>> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
castInto(Corrade::Containers::arrayCast<2, Integral>(src), |
|
Corrade::Containers::arrayCast<2, FloatingPoint>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expectedFloatingPoint), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Test the other way around as well */ |
|
castInto(Corrade::Containers::arrayCast<2, FloatingPoint>(dst), |
|
Corrade::Containers::arrayCast<2, Integral>(src)); |
|
CORRADE_COMPARE_AS(src, Corrade::Containers::stridedArrayView(expectedIntegral), |
|
Corrade::TestSuite::Compare::Container); |
|
} |
|
|
|
template<class FloatingPoint, class Integral> void PackingBatchTest::castSignedFloatingPoint() { |
|
setTestCaseTemplateName({TypeTraits<FloatingPoint>::name(), TypeTraits<Integral>::name()}); |
|
|
|
struct Data { |
|
Math::Vector2<Integral> src; |
|
Math::Vector2<FloatingPoint> dst; |
|
} data[]{ |
|
{{0, -89}, {}}, |
|
{{-119, 22}, {}}, |
|
{{13, 127}, {}} |
|
}; |
|
|
|
/* GCC 4.8 doesn't like constexpr here (cannot initialize aggregate of type |
|
‘const Vector2 [3]’ with a compound literal), wtf */ |
|
const Math::Vector2<FloatingPoint> expectedFloatingPoint[] { |
|
{FloatingPoint(0.0), FloatingPoint(-89.0)}, |
|
{FloatingPoint(-119.0), FloatingPoint(22.0)}, |
|
{FloatingPoint(13.0), FloatingPoint(127.0)} |
|
}; |
|
|
|
constexpr Math::Vector2<Integral> expectedIntegral[] { |
|
{0, -89}, |
|
{-119, 22}, |
|
{13, 127} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<Integral>> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<FloatingPoint>> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
castInto(Corrade::Containers::arrayCast<2, Integral>(src), |
|
Corrade::Containers::arrayCast<2, FloatingPoint>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expectedFloatingPoint), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Test the other way around as well */ |
|
castInto(Corrade::Containers::arrayCast<2, FloatingPoint>(dst), |
|
Corrade::Containers::arrayCast<2, Integral>(src)); |
|
CORRADE_COMPARE_AS(src, Corrade::Containers::stridedArrayView(expectedIntegral), |
|
Corrade::TestSuite::Compare::Container); |
|
} |
|
|
|
template<class T, class U> void PackingBatchTest::castUnsignedInteger() { |
|
setTestCaseTemplateName({TypeTraits<T>::name(), TypeTraits<U>::name()}); |
|
|
|
struct Data { |
|
Math::Vector2<T> src; |
|
Math::Vector2<U> dst; |
|
} data[]{ |
|
{{0, 89}, {}}, |
|
{{149, 22}, {}}, |
|
{{13, 255}, {}} |
|
}; |
|
|
|
constexpr Math::Vector2<U> expectedTargetType[] { |
|
{0, 89}, |
|
{149, 22}, |
|
{13, 255} |
|
}; |
|
|
|
constexpr Math::Vector2<T> expectedOriginalType[] { |
|
{0, 89}, |
|
{149, 22}, |
|
{13, 255} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<T>> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<U>> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
castInto(Corrade::Containers::arrayCast<2, T>(src), |
|
Corrade::Containers::arrayCast<2, U>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expectedTargetType), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Test the other way around as well */ |
|
castInto(Corrade::Containers::arrayCast<2, U>(dst), |
|
Corrade::Containers::arrayCast<2, T>(src)); |
|
CORRADE_COMPARE_AS(src, Corrade::Containers::stridedArrayView(expectedOriginalType), |
|
Corrade::TestSuite::Compare::Container); |
|
} |
|
|
|
template<class T, class U> void PackingBatchTest::castSignedInteger() { |
|
setTestCaseTemplateName({TypeTraits<T>::name(), TypeTraits<U>::name()}); |
|
|
|
struct Data { |
|
Math::Vector2<T> src; |
|
Math::Vector2<U> dst; |
|
} data[]{ |
|
{{0, -89}, {}}, |
|
{{-119, 22}, {}}, |
|
{{13, 127}, {}} |
|
}; |
|
|
|
constexpr Math::Vector2<U> expectedTargetType[] { |
|
{0, -89}, |
|
{-119, 22}, |
|
{13, 127} |
|
}; |
|
|
|
constexpr Math::Vector2<T> expectedOriginalType[] { |
|
{0, -89}, |
|
{-119, 22}, |
|
{13, 127} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<T>> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<U>> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
castInto(Corrade::Containers::arrayCast<2, T>(src), |
|
Corrade::Containers::arrayCast<2, U>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expectedTargetType), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Test the other way around as well */ |
|
castInto(Corrade::Containers::arrayCast<2, U>(dst), |
|
Corrade::Containers::arrayCast<2, T>(src)); |
|
CORRADE_COMPARE_AS(src, Corrade::Containers::stridedArrayView(expectedOriginalType), |
|
Corrade::TestSuite::Compare::Container); |
|
} |
|
|
|
template<class T, class U> void PackingBatchTest::castFloatDouble() { |
|
struct Data { |
|
Math::Vector2<T> src; |
|
Math::Vector2<U> dst; |
|
} data[]{ |
|
{{T(0.25), T(-89.5)}, {}}, |
|
{{T(-119.0), T(22.75)}, {}}, |
|
{{T(13.0), T(127.5)}, {}} |
|
}; |
|
|
|
constexpr Math::Vector2<U> expectedTargetType[] { |
|
{U(0.25), U(-89.5)}, |
|
{U(-119.0), U(22.75)}, |
|
{U(13.0), U(127.5)} |
|
}; |
|
|
|
constexpr Math::Vector2<T> expectedOriginalType[] { |
|
{T(0.25), T(-89.5)}, |
|
{T(-119.0), T(22.75)}, |
|
{T(13.0), T(127.5)} |
|
}; |
|
|
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<T>> src{data, &data[0].src, 3, sizeof(Data)}; |
|
Corrade::Containers::StridedArrayView1D<Math::Vector2<U>> dst{data, &data[0].dst, 3, sizeof(Data)}; |
|
castInto(Corrade::Containers::arrayCast<2, T>(src), |
|
Corrade::Containers::arrayCast<2, U>(dst)); |
|
CORRADE_COMPARE_AS(dst, Corrade::Containers::stridedArrayView(expectedTargetType), |
|
Corrade::TestSuite::Compare::Container); |
|
|
|
/* Test the other way around as well */ |
|
castInto(Corrade::Containers::arrayCast<2, U>(dst), |
|
Corrade::Containers::arrayCast<2, T>(src)); |
|
CORRADE_COMPARE_AS(src, Corrade::Containers::stridedArrayView(expectedOriginalType), |
|
Corrade::TestSuite::Compare::Container); |
|
} |
|
|
|
template<class T> void PackingBatchTest::assertionsPackUnpack() { |
|
CORRADE_SKIP_IF_NO_ASSERT(); |
|
|
|
Math::Vector2<T> data[2]{}; |
|
Math::Vector4<T> dataNonContiguous[2]{}; |
|
Vector2 resultWrongCount[1]{}; |
|
Vector2 result[2]{}; |
|
Vector3 resultWrongVectorSize[2]{}; |
|
Vector4 resultNonContiguous[2]{}; |
|
|
|
auto src = Corrade::Containers::arrayCast<2, T>( |
|
Corrade::Containers::arrayView(data)); |
|
auto srcNonContiguous = Corrade::Containers::arrayCast<2, T>( |
|
Corrade::Containers::arrayView(dataNonContiguous)).every({1, 2}); |
|
auto dst = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(result)); |
|
auto dstWrongCount = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(resultWrongCount)); |
|
auto dstWrongVectorSize = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(resultWrongVectorSize)); |
|
auto dstNotContiguous = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(resultNonContiguous)).every({1, 2}); |
|
|
|
std::ostringstream out; |
|
Error redirectError{&out}; |
|
unpackInto(src, dstWrongCount); |
|
unpackInto(src, dstWrongVectorSize); |
|
unpackInto(src, dstNotContiguous); |
|
unpackInto(srcNonContiguous, dst); |
|
packInto(dstWrongCount, src); |
|
packInto(dstWrongVectorSize, src); |
|
packInto(dstNotContiguous, src); |
|
packInto(dst, srcNonContiguous); |
|
CORRADE_COMPARE(out.str(), |
|
"Math::unpackInto(): wrong destination size, got {1, 2} but expected {2, 2}\n" |
|
"Math::unpackInto(): wrong destination size, got {2, 3} but expected {2, 2}\n" |
|
"Math::unpackInto(): second destination view dimension is not contiguous\n" |
|
"Math::unpackInto(): second source view dimension is not contiguous\n" |
|
"Math::packInto(): wrong destination size, got {2, 2} but expected {1, 2}\n" |
|
"Math::packInto(): wrong destination size, got {2, 2} but expected {2, 3}\n" |
|
"Math::packInto(): second source view dimension is not contiguous\n" |
|
"Math::packInto(): second destination view dimension is not contiguous\n"); |
|
} |
|
|
|
void PackingBatchTest::assertionsPackUnpackHalf() { |
|
CORRADE_SKIP_IF_NO_ASSERT(); |
|
|
|
Vector2us data[2]{}; |
|
Vector4us dataNonContiguous[2]{}; |
|
Vector2 result[2]{}; |
|
Vector2 resultWrongCount[1]{}; |
|
Vector3 resultWrongVectorSize[2]{}; |
|
Vector4 resultNonContiguous[2]{}; |
|
|
|
auto src = Corrade::Containers::arrayCast<2, UnsignedShort>( |
|
Corrade::Containers::arrayView(data)); |
|
auto srcNonContiguous = Corrade::Containers::arrayCast<2, UnsignedShort>( |
|
Corrade::Containers::arrayView(dataNonContiguous)).every({1, 2}); |
|
auto dst = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(result)); |
|
auto dstWrongCount = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(resultWrongCount)); |
|
auto dstWrongVectorSize = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(resultWrongVectorSize)); |
|
auto dstNotContiguous = Corrade::Containers::arrayCast<2, Float>( |
|
Corrade::Containers::arrayView(resultNonContiguous)).every({1, 2}); |
|
|
|
std::ostringstream out; |
|
Error redirectError{&out}; |
|
unpackHalfInto(src, dstWrongCount); |
|
unpackHalfInto(src, dstWrongVectorSize); |
|
unpackHalfInto(src, dstNotContiguous); |
|
unpackHalfInto(srcNonContiguous, dst); |
|
packHalfInto(dstWrongCount, src); |
|
packHalfInto(dstWrongVectorSize, src); |
|
packHalfInto(dstNotContiguous, src); |
|
packHalfInto(dst, srcNonContiguous); |
|
CORRADE_COMPARE(out.str(), |
|
"Math::unpackHalfInto(): wrong destination size, got {1, 2} but expected {2, 2}\n" |
|
"Math::unpackHalfInto(): wrong destination size, got {2, 3} but expected {2, 2}\n" |
|
"Math::unpackHalfInto(): second destination view dimension is not contiguous\n" |
|
"Math::unpackHalfInto(): second source view dimension is not contiguous\n" |
|
"Math::packHalfInto(): wrong destination size, got {2, 2} but expected {1, 2}\n" |
|
"Math::packHalfInto(): wrong destination size, got {2, 2} but expected {2, 3}\n" |
|
"Math::packHalfInto(): second source view dimension is not contiguous\n" |
|
"Math::packHalfInto(): second destination view dimension is not contiguous\n"); |
|
} |
|
|
|
template<class U, class T> void PackingBatchTest::assertionsCast() { |
|
CORRADE_SKIP_IF_NO_ASSERT(); |
|
|
|
setTestCaseTemplateName({TypeTraits<U>::name(), TypeTraits<T>::name()}); |
|
|
|
Math::Vector2<T> data[2]{}; |
|
Math::Vector2<U> resultWrongCount[1]{}; |
|
Math::Vector3<U> resultWrongVectorSize[2]{}; |
|
Math::Vector4<U> resultNonContiguous[2]{}; |
|
|
|
auto src = Corrade::Containers::arrayCast<2, T>( |
|
Corrade::Containers::arrayView(data)); |
|
auto dstWrongCount = Corrade::Containers::arrayCast<2, U>( |
|
Corrade::Containers::arrayView(resultWrongCount)); |
|
auto dstWrongVectorSize = Corrade::Containers::arrayCast<2, U>( |
|
Corrade::Containers::arrayView(resultWrongVectorSize)); |
|
auto dstNotContiguous = Corrade::Containers::arrayCast<2, U>( |
|
Corrade::Containers::arrayView(resultNonContiguous)).every({1, 2}); |
|
|
|
std::ostringstream out; |
|
Error redirectError{&out}; |
|
castInto(src, dstWrongCount); |
|
castInto(src, dstWrongVectorSize); |
|
castInto(src, dstNotContiguous); |
|
castInto(dstWrongCount, src); |
|
castInto(dstWrongVectorSize, src); |
|
castInto(dstNotContiguous, src); |
|
CORRADE_COMPARE(out.str(), |
|
"Math::castInto(): wrong destination size, got {1, 2} but expected {2, 2}\n" |
|
"Math::castInto(): wrong destination size, got {2, 3} but expected {2, 2}\n" |
|
"Math::castInto(): second destination view dimension is not contiguous\n" |
|
"Math::castInto(): wrong destination size, got {2, 2} but expected {1, 2}\n" |
|
"Math::castInto(): wrong destination size, got {2, 2} but expected {2, 3}\n" |
|
"Math::castInto(): second source view dimension is not contiguous\n"); |
|
} |
|
|
|
}}}} |
|
|
|
CORRADE_TEST_MAIN(Magnum::Math::Test::PackingBatchTest)
|
|
|