From 13a6ba8a23d28c308aed655cc6f757b29f9fc374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 3 Sep 2018 23:24:49 +0200 Subject: [PATCH] Math: benchmark quaternion interpolation methods. --- src/Magnum/Math/Test/CMakeLists.txt | 2 + .../Math/Test/InterpolationBenchmark.cpp | 152 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 src/Magnum/Math/Test/InterpolationBenchmark.cpp diff --git a/src/Magnum/Math/Test/CMakeLists.txt b/src/Magnum/Math/Test/CMakeLists.txt index 4b5a7d4c4..14311a9a1 100644 --- a/src/Magnum/Math/Test/CMakeLists.txt +++ b/src/Magnum/Math/Test/CMakeLists.txt @@ -61,6 +61,8 @@ corrade_add_test(MathDistanceTest DistanceTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathIntersectionTest IntersectionTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathIntersectionBenchmark IntersectionBenchmark.cpp LIBRARIES MagnumMathTestLib) +corrade_add_test(MathInterpolationBenchmark InterpolationBenchmark.cpp LIBRARIES MagnumMathTestLib) + set_property(TARGET MathVectorTest MathMatrixTest diff --git a/src/Magnum/Math/Test/InterpolationBenchmark.cpp b/src/Magnum/Math/Test/InterpolationBenchmark.cpp new file mode 100644 index 000000000..c023b35ed --- /dev/null +++ b/src/Magnum/Math/Test/InterpolationBenchmark.cpp @@ -0,0 +1,152 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 + Vladimír Vondruš + + 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 + +#define CORRADE_NO_ASSERT +#include "Magnum/Math/DualQuaternion.h" + +namespace Magnum { namespace Math { namespace Test { + +struct InterpolationBenchmark: Corrade::TestSuite::Tester { + explicit InterpolationBenchmark(); + + void baseline(); + void quaternionLerp(); + void quaternionLerpShortestPath(); + void quaternionSlerp(); + void quaternionSlerpShortestPath(); + void dualQuaternionSclerp(); + void dualQuaternionSclerpShortestPath(); +}; + +using namespace Math::Literals; + +typedef Math::Quaternion Quaternion; +typedef Math::DualQuaternion DualQuaternion; +typedef Math::Vector3 Vector3; + +InterpolationBenchmark::InterpolationBenchmark() { + addBenchmarks({&InterpolationBenchmark::baseline, + &InterpolationBenchmark::quaternionLerp, + &InterpolationBenchmark::quaternionLerpShortestPath, + &InterpolationBenchmark::quaternionSlerp, + &InterpolationBenchmark::quaternionSlerpShortestPath, + &InterpolationBenchmark::dualQuaternionSclerp, + &InterpolationBenchmark::dualQuaternionSclerpShortestPath}, 100); +} + +void InterpolationBenchmark::baseline() { + Quaternion c; + Float t = 0.0f; + CORRADE_BENCHMARK(10000) { + c += Quaternion{}; + t += 0.0002f; + } + + CORRADE_VERIFY(!c.isNormalized()); +} + +void InterpolationBenchmark::quaternionLerp() { + auto a = Quaternion::rotation(225.0_degf, Vector3::zAxis()); + auto b = Quaternion::rotation(0.0_degf, Vector3::zAxis()); + Quaternion c; + Float t = 0.0f; + CORRADE_BENCHMARK(10000) { + c += lerp(a, b, t); + t += 0.0002f; + } + + CORRADE_VERIFY(!c.isNormalized()); +} + +void InterpolationBenchmark::quaternionLerpShortestPath() { + auto a = Quaternion::rotation(225.0_degf, Vector3::zAxis()); + auto b = Quaternion::rotation(0.0_degf, Vector3::zAxis()); + Quaternion c; + Float t = 0.0f; + CORRADE_BENCHMARK(10000) { + c += lerpShortestPath(a, b, t); + t += 0.0002f; + } + + CORRADE_VERIFY(!c.isNormalized()); +} + +void InterpolationBenchmark::quaternionSlerp() { + auto a = Quaternion::rotation(225.0_degf, Vector3::zAxis()); + auto b = Quaternion::rotation(0.0_degf, Vector3::zAxis()); + Quaternion c; + Float t = 0.0f; + CORRADE_BENCHMARK(10000) { + c += slerp(a, b, t); + t += 0.0002f; + } + + CORRADE_VERIFY(!c.isNormalized()); +} + +void InterpolationBenchmark::quaternionSlerpShortestPath() { + auto a = Quaternion::rotation(225.0_degf, Vector3::zAxis()); + auto b = Quaternion::rotation(0.0_degf, Vector3::zAxis()); + Quaternion c; + Float t = 0.0f; + CORRADE_BENCHMARK(10000) { + c += slerpShortestPath(a, b, t); + t += 0.0002f; + } + + CORRADE_VERIFY(!c.isNormalized()); +} + +void InterpolationBenchmark::dualQuaternionSclerp() { + auto a = DualQuaternion::rotation(225.0_degf, Vector3::zAxis()); + auto b = DualQuaternion::rotation(0.0_degf, Vector3::zAxis()); + DualQuaternion c; + Float t = 0.0f; + CORRADE_BENCHMARK(1000) { + c += sclerp(a, b, t); + t += 0.001f; + } + + CORRADE_VERIFY(!c.isNormalized()); +} + +void InterpolationBenchmark::dualQuaternionSclerpShortestPath() { + auto a = DualQuaternion::rotation(225.0_degf, Vector3::zAxis()); + auto b = DualQuaternion::rotation(0.0_degf, Vector3::zAxis()); + DualQuaternion c; + Float t = 0.0f; + CORRADE_BENCHMARK(1000) { + c += sclerpShortestPath(a, b, t); + t += 0.001f; + } + + CORRADE_VERIFY(!c.isNormalized()); +} + +}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::InterpolationBenchmark)