diff --git a/doc/changelog.dox b/doc/changelog.dox index 46984082a..5fa71864d 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -224,7 +224,8 @@ See also: @subsubsection changelog-latest-changes-math Math library - Added @ref Math::castInto() overloads for casting between @ref UnsignedByte - and @ref UnsignedShort or @ref Byte and @ref Short + and @ref UnsignedShort or @ref Byte and @ref Short, and for casting between + @ref Float and @ref Double @subsubsection changelog-latest-changes-meshtools MeshTools library diff --git a/src/Magnum/Math/PackingBatch.cpp b/src/Magnum/Math/PackingBatch.cpp index e30baeda6..268249fee 100644 --- a/src/Magnum/Math/PackingBatch.cpp +++ b/src/Magnum/Math/PackingBatch.cpp @@ -288,6 +288,14 @@ void castInto(const Corrade::Containers::StridedArrayView2D& src, c castIntoImplementation(src, dst); } +void castInto(const Corrade::Containers::StridedArrayView2D& src, const Corrade::Containers::StridedArrayView2D& dst) { + castIntoImplementation(src, dst); +} + +void castInto(const Corrade::Containers::StridedArrayView2D& src, const Corrade::Containers::StridedArrayView2D& dst) { + castIntoImplementation(src, dst); +} + static_assert(sizeof(HalfMantissaTable) + sizeof(HalfOffsetTable) + sizeof(HalfExponentTable) == 8576, "improper size of half->float conversion tables"); diff --git a/src/Magnum/Math/PackingBatch.h b/src/Magnum/Math/PackingBatch.h index 60d934178..e3359c85d 100644 --- a/src/Magnum/Math/PackingBatch.h +++ b/src/Magnum/Math/PackingBatch.h @@ -348,6 +348,43 @@ MAGNUM_EXPORT void castInto(const Corrade::Containers::StridedArrayView2D& src, const Corrade::Containers::StridedArrayView2D& dst); +/** +@brief Cast 32-bit floating-point values into a 64-bit floating-point representation +@param[in] src Source float values +@param[out] dst Destination double values +@m_since_latest + +This function performs an equivalent of @cpp Double(a) @ce over the range, so +e.g. @cpp 135.0f @ce becomes @cpp 135.0 @ce. Second dimension is meant to +contain vector/matrix components, or have a size of 1 for scalars. Expects that +@p src and @p dst have the same size and that the second dimension in both is +contiguous. + +@see @ref castInto(const Corrade::Containers::StridedArrayView2D&, const Corrade::Containers::StridedArrayView2D&), + @ref Corrade::Containers::StridedArrayView::isContiguous() +*/ +MAGNUM_EXPORT void castInto(const Corrade::Containers::StridedArrayView2D& src, const Corrade::Containers::StridedArrayView2D& dst); + +/** +@brief Cast 64-bit floating-point values into a 32-bit floating-point representation +@param[in] src Source double values +@param[out] dst Destination float values +@m_since_latest + +This function performs an equivalent of @cpp Float(a) @ce over the range, so +e.g. @cpp 135.0 @ce becomes @cpp 135.0f @ce. Second dimension is meant to +contain vector/matrix components, or have a size of 1 for scalars. Expects that +@p src and @p dst have the same size and that the second dimension in both is +contiguous. + +@attention Numbers with more than 23 bits of precision will not be represented + accurately when cast into a @ref Magnum::Float "Float". + +@see @ref castInto(const Corrade::Containers::StridedArrayView2D&, const Corrade::Containers::StridedArrayView2D&), + @ref Corrade::Containers::StridedArrayView::isContiguous() +*/ +MAGNUM_EXPORT void castInto(const Corrade::Containers::StridedArrayView2D& src, const Corrade::Containers::StridedArrayView2D& dst); + /* Since 1.8.17, the original short-hand group closing doesn't work anymore. FFS. */ /** diff --git a/src/Magnum/Math/Test/PackingBatchTest.cpp b/src/Magnum/Math/Test/PackingBatchTest.cpp index 42fb9792b..5ac84c475 100644 --- a/src/Magnum/Math/Test/PackingBatchTest.cpp +++ b/src/Magnum/Math/Test/PackingBatchTest.cpp @@ -57,6 +57,8 @@ struct PackingBatchTest: Corrade::TestSuite::Tester { template void castUnsignedInteger(); template void castSignedInteger(); + void castFloatDouble(); + template void assertionsPackUnpack(); void assertionsPackUnpackHalf(); template void assertionsCast(); @@ -89,6 +91,8 @@ PackingBatchTest::PackingBatchTest() { &PackingBatchTest::castSignedInteger, &PackingBatchTest::castSignedInteger, + &PackingBatchTest::castFloatDouble, + &PackingBatchTest::assertionsPackUnpack, &PackingBatchTest::assertionsPackUnpack, &PackingBatchTest::assertionsPackUnpack, @@ -105,7 +109,8 @@ PackingBatchTest::PackingBatchTest() { &PackingBatchTest::assertionsCast, &PackingBatchTest::assertionsCast, &PackingBatchTest::assertionsCast, - &PackingBatchTest::assertionsCast}); + &PackingBatchTest::assertionsCast, + &PackingBatchTest::assertionsCast}); } typedef Math::Constants Constants; @@ -573,6 +578,42 @@ template void PackingBatchTest::castSignedInteger() { Corrade::TestSuite::Compare::Container); } +void PackingBatchTest::castFloatDouble() { + struct Data { + Math::Vector2 src; + Math::Vector2 dst; + } data[]{ + {{0.25f, -89.5f}, {}}, + {{-119.0f, 22.75f}, {}}, + {{13.0f, 127.5f}, {}} + }; + + constexpr Math::Vector2 expectedTargetType[] { + {0.25, -89.5}, + {-119.0, 22.75}, + {13.0, 127.5} + }; + + constexpr Math::Vector2 expectedOriginalType[] { + {0.25f, -89.5f}, + {-119.0f, 22.75f}, + {13.0f, 127.5f} + }; + + Corrade::Containers::StridedArrayView1D> src{data, &data[0].src, 3, sizeof(Data)}; + Corrade::Containers::StridedArrayView1D> dst{data, &data[0].dst, 3, sizeof(Data)}; + castInto(Corrade::Containers::arrayCast<2, Float>(src), + Corrade::Containers::arrayCast<2, Double>(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, Double>(dst), + Corrade::Containers::arrayCast<2, Float>(src)); + CORRADE_COMPARE_AS(src, Corrade::Containers::stridedArrayView(expectedOriginalType), + Corrade::TestSuite::Compare::Container); +} + template void PackingBatchTest::assertionsPackUnpack() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");