From 53c1549e69af552d28d5da8fc4dcdd0e9a1cad60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 24 Mar 2019 17:27:03 +0100 Subject: [PATCH] Math: deprecate Frustum::planes() in favor of begin()/end(). This allows us to get rid of the StaticArrayView, which is the last roadblock on the way to a single-header math. The planes() are now deprecated, along with the include, and will get removed in a future release. --- doc/changelog.dox | 8 +++++ doc/snippets/MagnumMath.cpp | 11 +++++++ src/Magnum/Math/Frustum.h | 33 +++++++++++++++++-- src/Magnum/Math/Intersection.h | 8 ++--- src/Magnum/Math/Test/FrustumTest.cpp | 30 +++++++++++++++-- .../Math/Test/IntersectionBenchmark.cpp | 2 +- 6 files changed, 81 insertions(+), 11 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 36a62e766..b01e01594 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -107,6 +107,11 @@ See also: @ref GL::Context::DetectedDriver::SwiftShader and @ref GL::Context::DetectedDriver::ArmMali +@subsubsection changelog-latest-new-math Math library + +- @ref Math::Frustum::begin() / @ref Math::Frustum::end() accessors for + easy range-for access to @ref Math::Frustum planes + @subsubsection changelog-latest-new-platform Platform libraries - @ref Platform::Sdl2Application and @ref Platform::GlfwApplication are now @@ -298,6 +303,9 @@ See also: are deprecated in favor of tuple-less @ref Math::ColorHsv, working correctly with the usual @ref Math::NoInit / @ref Math::ZeroInit tags while being faster to compile +- @cpp Math::Frustum::planes() @ce are deprecated due to redundancy, use + either @ref Math::Frustum::operator[](), @ref Math::Frustum::data() or + range access using @ref Math::Frustum::begin() / @ref Math::Frustum::end() - @cpp Trade::ImporterFileCallbackPolicy @ce is deprecated as it was moved to @ref InputFileCallbackPolicy in the root namespace to be shared with APIs outside of the @ref Trade namespace diff --git a/doc/snippets/MagnumMath.cpp b/doc/snippets/MagnumMath.cpp index 83d10e7ab..a789b136a 100644 --- a/doc/snippets/MagnumMath.cpp +++ b/doc/snippets/MagnumMath.cpp @@ -31,8 +31,10 @@ #include "Magnum/Math/FunctionsBatch.h" #include "Magnum/Math/Bezier.h" #include "Magnum/Math/CubicHermite.h" +#include "Magnum/Math/Distance.h" #include "Magnum/Math/DualComplex.h" #include "Magnum/Math/DualQuaternion.h" +#include "Magnum/Math/Frustum.h" #include "Magnum/Math/Half.h" #include "Magnum/Math/Range.h" #include "Magnum/Math/Algorithms/GramSchmidt.h" @@ -858,6 +860,15 @@ Math::Dual integral{floatingPoint}; // {1, 2} /* [Dual-conversion] */ } +[](const Vector3& point){ +Frustum frustum; +/* [Frustum-range] */ +for(Vector4 plane: frustum) + if(Math::Distance::pointPlaneScaled(point, plane) < 0.0f) return false; +return true; +/* [Frustum-range] */ +}({}); + { /* [div] */ Int quotient, remainder; diff --git a/src/Magnum/Math/Frustum.h b/src/Magnum/Math/Frustum.h index 9ac7c020c..7692aa355 100644 --- a/src/Magnum/Math/Frustum.h +++ b/src/Magnum/Math/Frustum.h @@ -31,7 +31,6 @@ */ #include -#include #ifndef CORRADE_NO_DEBUG #include #endif @@ -39,6 +38,10 @@ #include "Magnum/Math/Matrix4.h" #include "Magnum/Math/Vector4.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include /** @todo remove when planes() is gone */ +#endif + namespace Magnum { namespace Math { namespace Implementation { @@ -116,11 +119,17 @@ template class Frustum { T* data() { return _data[0].data(); } constexpr const T* data() const { return _data[0].data(); } /**< @overload */ - /** @brief Frustum planes */ - constexpr Corrade::Containers::StaticArrayView<6, const Vector4> planes() const { + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Frustum planes + * @deprecated Use @ref operator[](std::size_t) const, @ref data() or + * @ref begin() / @ref end() instead. + */ + constexpr CORRADE_DEPRECATED("use operator[](), data() or begin() / end() instead") Corrade::Containers::StaticArrayView<6, const Vector4> planes() const { /* GCC 4.8 needs explicit construction */ return Corrade::Containers::StaticArrayView<6, const Vector4>{_data}; } + #endif /** * @brief Plane at given index @@ -132,6 +141,24 @@ template class Frustum { return CORRADE_CONSTEXPR_ASSERT(i < 6, "Math::Frustum::operator[](): index" << i << "out of range"), _data[i]; } + /** + * @brief First plane + * + * Together with @ref end() useful for range access, for example here + * to check for a point/frustum intersection, similarly to + * @ref Intersection::pointFrustum(): + * + * @snippet MagnumMath.cpp Frustum-range + */ + Vector4* begin() { return _data; } + constexpr const Vector4* begin() const { return _data; } /**< @overload */ + constexpr const Vector4* cbegin() const { return _data; } /**< @overload */ + + /** @brief (One after) last plane */ + Vector4* end() { return _data + 6; } + constexpr const Vector4* end() const { return _data + 6; } /**< @overload */ + constexpr const Vector4* cend() const { return _data + 6; } /**< @overload */ + /** @brief Left plane */ constexpr Vector4 left() const { return _data[0]; } diff --git a/src/Magnum/Math/Intersection.h b/src/Magnum/Math/Intersection.h index a8ca655b8..e9c83fdd8 100644 --- a/src/Magnum/Math/Intersection.h +++ b/src/Magnum/Math/Intersection.h @@ -418,7 +418,7 @@ The @p tanAngleSqPlusOne parameter can be precomputed like this: template bool rangeCone(const Range3D& range, const Vector3& coneOrigin, const Vector3& coneNormal, const T tanAngleSqPlusOne); template bool pointFrustum(const Vector3& point, const Frustum& frustum) { - for(const Vector4& plane: frustum.planes()) { + for(const Vector4& plane: frustum) { /* The point is in front of one of the frustum planes (normals point outwards) */ if(Distance::pointPlaneScaled(point, plane) < T(0)) @@ -434,7 +434,7 @@ template bool rangeFrustum(const Range3D& range, const Frustum& f const Vector3 center = range.min() + range.max(); const Vector3 extent = range.max() - range.min(); - for(const Vector4& plane: frustum.planes()) { + for(const Vector4& plane: frustum) { const Vector3 absPlaneNormal = Math::abs(plane.xyz()); const Float d = Math::dot(center, plane.xyz()); @@ -446,7 +446,7 @@ template bool rangeFrustum(const Range3D& range, const Frustum& f } template bool aabbFrustum(const Vector3& aabbCenter, const Vector3& aabbExtents, const Frustum& frustum) { - for(const Vector4& plane: frustum.planes()) { + for(const Vector4& plane: frustum) { const Vector3 absPlaneNormal = Math::abs(plane.xyz()); const Float d = Math::dot(aabbCenter, plane.xyz()); @@ -460,7 +460,7 @@ template bool aabbFrustum(const Vector3& aabbCenter, const Vector3 bool sphereFrustum(const Vector3& sphereCenter, const T sphereRadius, const Frustum& frustum) { const T radiusSq = sphereRadius*sphereRadius; - for(const Vector4& plane: frustum.planes()) { + for(const Vector4& plane: frustum) { /* The sphere is in front of one of the frustum planes (normals point outwards) */ if(Distance::pointPlaneScaled(sphereCenter, plane) < -radiusSq) diff --git a/src/Magnum/Math/Test/FrustumTest.cpp b/src/Magnum/Math/Test/FrustumTest.cpp index 0bfde3772..8a276a9cd 100644 --- a/src/Magnum/Math/Test/FrustumTest.cpp +++ b/src/Magnum/Math/Test/FrustumTest.cpp @@ -75,6 +75,7 @@ struct FrustumTest: Corrade::TestSuite::Tester { void convert(); void data(); + void rangeFor(); void compare(); @@ -98,6 +99,7 @@ FrustumTest::FrustumTest() { &FrustumTest::convert, &FrustumTest::data, + &FrustumTest::rangeFor, &FrustumTest::compare, @@ -120,8 +122,12 @@ void FrustumTest::construct() { planes[2], planes[3], planes[4], planes[5]}; - CORRADE_COMPARE_AS(frustum.planes(), Corrade::Containers::arrayView(planes), - Corrade::TestSuite::Compare::Container); + CORRADE_COMPARE(frustum[0], planes[0]); + CORRADE_COMPARE(frustum[1], planes[1]); + CORRADE_COMPARE(frustum[2], planes[2]); + CORRADE_COMPARE(frustum[3], planes[3]); + CORRADE_COMPARE(frustum[4], planes[4]); + CORRADE_COMPARE(frustum[5], planes[5]); CORRADE_VERIFY((std::is_nothrow_constructible::value)); } @@ -269,7 +275,7 @@ void FrustumTest::data() { #if !defined(__GNUC__) || __GNUC__*100 + __GNUC_MINOR__ >= 500 constexpr #endif - Vector4 right = a.planes()[1]; + Vector4 right = a.cbegin()[1]; CORRADE_COMPARE(right, (Vector4{-1.0f, 0.0f, 0.0f, 1.0f})); constexpr Vector4 bottom = a[2]; @@ -278,6 +284,12 @@ void FrustumTest::data() { constexpr Vector4 near = a.near(); CORRADE_COMPARE(near, (Vector4{0.0f, 0.0f, 1.0f, 1.0f})); + #if !defined(CORRADE_MSVC2015_COMPATIBILITY) && (!defined(__GNUC__) || __GNUC__*100 + __GNUC_MINOR__ >= 500) + constexpr + #endif + Vector4 far = *(a.cend() - 1); + CORRADE_COMPARE(far, (Vector4{0.0f, 0.0f, -1.0f, 1.0f})); + #ifndef CORRADE_MSVC2015_COMPATIBILITY /* Apparently dereferencing pointer is verboten */ constexpr #endif @@ -290,6 +302,18 @@ void FrustumTest::data() { CORRADE_COMPARE(out.str(), "Math::Frustum::operator[](): index 6 out of range\n"); } +void FrustumTest::rangeFor() { + Frustum a; + Vector4 sum{3.0f}; + Int i = 0; + for(const Vector4& plane: a) { + ++i; + sum *= plane; + } + CORRADE_COMPARE(i, 6); + CORRADE_COMPARE(sum, (Vector4{0.0f, 0.0f, 0.0f, 3.0f})); +} + void FrustumTest::compare() { Frustum a{ {-1.0f, 2.0f, -3.0f, 0.1f}, diff --git a/src/Magnum/Math/Test/IntersectionBenchmark.cpp b/src/Magnum/Math/Test/IntersectionBenchmark.cpp index 6c9843315..7628c0a5c 100644 --- a/src/Magnum/Math/Test/IntersectionBenchmark.cpp +++ b/src/Magnum/Math/Test/IntersectionBenchmark.cpp @@ -34,7 +34,7 @@ namespace Magnum { namespace Math { namespace Test { namespace { template bool rangeFrustumNaive(const Math::Range3D& box, const Math::Frustum& frustum) { - for(const Math::Vector4& plane: frustum.planes()) { + for(const Math::Vector4& plane: frustum) { bool cornerHit = 0; for(UnsignedByte c = 0; c != 8; ++c) {