From 0062fbf78efca78ced4e9ea59d7d682c47e3c89b Mon Sep 17 00:00:00 2001 From: Squareys Date: Wed, 23 Nov 2016 22:31:00 +0100 Subject: [PATCH] Math: Add rudimentary Frustum class Signed-off-by: Squareys --- src/Magnum/Math/CMakeLists.txt | 1 + src/Magnum/Math/Frustum.h | 101 +++++++++++++++++++++++++++ src/Magnum/Math/Test/CMakeLists.txt | 1 + src/Magnum/Math/Test/FrustumTest.cpp | 89 +++++++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 src/Magnum/Math/Frustum.h create mode 100644 src/Magnum/Math/Test/FrustumTest.cpp diff --git a/src/Magnum/Math/CMakeLists.txt b/src/Magnum/Math/CMakeLists.txt index d6783821f..baeaa4dfb 100644 --- a/src/Magnum/Math/CMakeLists.txt +++ b/src/Magnum/Math/CMakeLists.txt @@ -33,6 +33,7 @@ set(MagnumMath_HEADERS Dual.h DualComplex.h DualQuaternion.h + Frustum.h Functions.h Math.h TypeTraits.h diff --git a/src/Magnum/Math/Frustum.h b/src/Magnum/Math/Frustum.h new file mode 100644 index 000000000..6396d51a0 --- /dev/null +++ b/src/Magnum/Math/Frustum.h @@ -0,0 +1,101 @@ +#ifndef Magnum_Math_Frustum_h +#define Magnum_Math_Frustum_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016 + Vladimír Vondruš + Copyright © 2016 Jonathan Hale + + 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. +*/ + +/** @file + * @brief Class @ref Magnum::Math::Frustum + */ + +#include +#include +#include + +#include "Magnum/Math/Matrix4.h" +#include "Magnum/Math/Vector4.h" + +namespace Magnum { namespace Math { + +/** +@brief Camera frustum + +*/ +template class Frustum { + public: + + /** + * @brief Create a frustum from projection matrix + */ + static Frustum fromMatrix(const Matrix4& m) { + return Frustum{ + m.row(3) + m.row(0), + m.row(3) - m.row(0), + m.row(3) + m.row(1), + m.row(3) - m.row(1), + m.row(3) + m.row(2), + m.row(3) - m.row(2) + }; + } + + /** + * @brief Construct frustum from frustum planes + */ + constexpr /*implicit*/ Frustum(const Vector4& left, const Vector4& right, const Vector4& bottom, const Vector4& top, const Vector4& near, const Vector4& far): _data{left, right, bottom, top, near, far} {} + + /** + * @brief Raw data + * @return One-dimensional array of length `24`. + */ + T* data() { return _data[0].data(); } + + /** @overload */ + constexpr const T* data() const { return _data[0].data(); } + + /** + * @brief The frustum planes + * + * In order left (index `0`), right (index `1`), bottom (index `1`), + * top (index `3`), near (index `4`), far (index `5`). + */ + constexpr Corrade::Containers::StaticArrayView<6, const Vector4> planes() const { + return Corrade::Containers::StaticArrayView<6, const Vector4>{_data}; + } + + /** + * @brief Plane at given index + * + * In order left (index `0`), right (index `1`), bottom (index `1`), + * top (index `3`), near (index `4`), far (index `5`). + */ + constexpr Vector4 operator[](std::size_t i) const { return _data[i]; } + + private: + Vector4 _data[6]; +}; + +}} + +#endif diff --git a/src/Magnum/Math/Test/CMakeLists.txt b/src/Magnum/Math/Test/CMakeLists.txt index 9f93ec1e1..7a89fe901 100644 --- a/src/Magnum/Math/Test/CMakeLists.txt +++ b/src/Magnum/Math/Test/CMakeLists.txt @@ -52,6 +52,7 @@ corrade_add_test(MathQuaternionTest QuaternionTest.cpp LIBRARIES MagnumMathTestL corrade_add_test(MathDualQuaternionTest DualQuaternionTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathBezierTest BezierTest.cpp LIBRARIES MagnumMathTestLib) +corrade_add_test(MathFrustumTest FrustumTest.cpp LIBRARIES MagnumMathTestLib) set_property(TARGET MathVectorTest diff --git a/src/Magnum/Math/Test/FrustumTest.cpp b/src/Magnum/Math/Test/FrustumTest.cpp new file mode 100644 index 000000000..be75700b5 --- /dev/null +++ b/src/Magnum/Math/Test/FrustumTest.cpp @@ -0,0 +1,89 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016 + Vladimír Vondruš + Copyright © 2016 Jonathan Hale + + 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 +#include +#include + +#include "Magnum/Math/Frustum.h" + +using namespace Corrade; + +namespace Magnum { namespace Math { namespace Test { + +struct FrustumTest: TestSuite::Tester { + explicit FrustumTest(); + + void construct(); + void constructFromMatrix(); +}; + +typedef Vector4 Vector4; +typedef Matrix4 Matrix4; +typedef Frustum Frustum; +typedef Deg Degf; + +FrustumTest::FrustumTest() { + addTests({&FrustumTest::construct, + &FrustumTest::constructFromMatrix}); +} + +void FrustumTest::construct() { + Vector4 planes[6]{ + {-1.0f, 0.0f, 0.0f, 1.0f}, + { 1.0f, 0.0f, 0.0f, 1.0f}, + { 0.0f,-1.0f, 0.0f, 1.0f}, + { 0.0f, 1.0f, 0.0f, 1.0f}, + { 0.0f, 0.0f,-1.0f, 1.0f}, + { 0.0f, 0.0f, 1.0f, 1.0f}}; + + Frustum frustum{ + planes[0], planes[1], + planes[2], planes[3], + planes[4], planes[5], + }; + + CORRADE_COMPARE_AS(frustum.planes(), Containers::ArrayView(planes), TestSuite::Compare::Container); +} + +void FrustumTest::constructFromMatrix() { + Vector4 planes[6]{ + { 1.0f, 0.0f,-1.0f, 0.0f}, + {-1.0f, 0.0f,-1.0f, 0.0f}, + { 0.0f, 1.0f,-1.0f, 0.0f}, + { 0.0f,-1.0f,-1.0f, 0.0f}, + { 0.0f, 0.0f,-2.22222f,-2.22222f}, + { 0.0f, 0.0f, 0.22222f, 2.22222f}}; + + const Frustum frustum = Frustum::fromMatrix( + Matrix4::perspectiveProjection(Degf(90.0f), 1.0f, 1.0f, 10.0f)); + + CORRADE_COMPARE_AS(frustum.planes(), Containers::ArrayView(planes), TestSuite::Compare::Container); +} + +}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::FrustumTest)