From add649c321e984948bb8672476286730d0ab4d93 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 9 Aug 2019 23:41:01 +0200 Subject: [PATCH] Ref T709, improved normalization and space pressed handling, unit test --- src/blackmisc/simulation/xplane/qtfreeutils.h | 10 ++++ src/xswiftbus/traffic.cpp | 52 ++++++++++++++----- src/xswiftbus/traffic.h | 6 ++- .../simulation/testxplane/testxplane.cpp | 35 +++++++++++++ 4 files changed, 88 insertions(+), 15 deletions(-) diff --git a/src/blackmisc/simulation/xplane/qtfreeutils.h b/src/blackmisc/simulation/xplane/qtfreeutils.h index 3a69bb911..791603c72 100644 --- a/src/blackmisc/simulation/xplane/qtfreeutils.h +++ b/src/blackmisc/simulation/xplane/qtfreeutils.h @@ -92,6 +92,16 @@ namespace BlackMisc return tokens; } + //! Normalize value to range start -> end (like for +-180degrees) + inline double normalizeValue(const double value, const double start, const double end) + { + // https://stackoverflow.com/questions/1628386/normalise-orientation-between-0-and-360 + if (value >= start && value <= end) { return value; } + const double width = end - start ; + const double offsetValue = value - start; // value relative to 0 + return (offsetValue - (floor(offsetValue / width) * width)) + start ; + } + //! ACF properties struct AcfProperties { diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index 9e62ebe01..54a5d4017 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -21,6 +21,7 @@ #include #include #include +#include "blackmisc/simulation/xplane/qtfreeutils.h" #include #include #include @@ -30,6 +31,8 @@ // clazy:excludeall=reserve-candidates +using namespace BlackMisc::Simulation::XPlane::QtFreeUtils; + namespace XSwiftBus { CTraffic::Plane::Plane(void *id_, const std::string &callsign_, const std::string &aircraftIcao_, const std::string &airlineIcao_, const std::string &livery_, const std::string &modelName_) @@ -918,7 +921,7 @@ namespace XSwiftBus // Ideally we would like to test against right mouse button, but X-Plane SDK does not // allow that. - if (!traffic->m_deltaCameraPosition.isInitialized || traffic->m_isSpacePressed) + if (!traffic->m_deltaCameraPosition.isInitialized) { int w = 0, h = 0, x = 0, y = 0; // First get the screen size and mouse location. We will use this to decide @@ -936,11 +939,17 @@ namespace XSwiftBus return 0; } - traffic->m_deltaCameraPosition.headingDeg = 360.0 * static_cast(x) / static_cast(w); - double usedCameraPitchDeg = 20.0 * ((static_cast(y) / static_cast(h)) * 2.0 - 1.0); + if (x < 1 || y < 1 || x >= w || y >= h) + { + WARNING_LOG("Screen w/h, and x/y" + std::to_string(w) + "/" + std::to_string(h) + " | " + std::to_string(x) + "/" + std::to_string(y)); + return 0; + } - // make sure we can use it with tan in range +-90 degrees - // we limit to +-85deg + traffic->m_deltaCameraPosition.headingDeg = normalizeToZero360DegD(360.0 * static_cast(x) / static_cast(w)); // range 0-360 + double usedCameraPitchDeg = 60.0 - (60.0 * 2.0 * static_cast(y) / static_cast(h)); // range +- + + // make sure we can use it with tan in range +-90 degrees and the result of tan not getting too high + // we limit to +-85deg, tan 45deg: 1 | tan 60deg: 1.73 | tan 85deg: 11.4 if (usedCameraPitchDeg >= 85.0) { usedCameraPitchDeg = 85.0; } else if (usedCameraPitchDeg <= -85.0) { usedCameraPitchDeg = -85.0; } traffic->m_deltaCameraPosition.pitchDeg = usedCameraPitchDeg; @@ -1071,8 +1080,10 @@ namespace XSwiftBus // We are only interested in Space key if (virtualKey == XPLM_VK_SPACE) { - if (flags & xplm_DownFlag) { traffic->m_isSpacePressed = true; } - if (flags & xplm_UpFlag) { traffic->m_isSpacePressed = false; } + // if XPlane looses focus it can happen that key down is NOT reset + // for the camera we use the init flag instead, so it is only run once + if (flags & xplm_DownFlag) { traffic->m_isSpacePressed = true; traffic->m_deltaCameraPosition.isInitialized = false; } + if (flags & xplm_UpFlag) { traffic->m_isSpacePressed = false; } } /* Return 1 to pass the keystroke to plugin windows and X-Plane. @@ -1111,17 +1122,32 @@ namespace XSwiftBus float CTraffic::normalizeToPlusMinus180DegF(float v) { if (std::isnan(v)) { return 0.0f; } - if (v > 180.0f) { return v - 360.0f;} - if (v <= -180.0f) { return v + 360.0f;} - return v; + return static_cast(normalizeToPlusMinus180DegD(static_cast(v))); } double CTraffic::normalizeToPlusMinus180DegD(double v) { if (std::isnan(v)) { return 0.0; } - if (v > 180.0) { return v - 360.0;} - if (v <= -180.0) { return v + 360.0;} - return v; + const double n = normalizeValue(v, -180.0, 180.0); + if (n <= -180.0) { return 180.0; } + if (n > 180.0) { return 180.0; } + return n; + } + + float CTraffic::normalizeToZero360DegF(float v) + { + if (std::isnan(v)) { return 0.0f; } + return static_cast(normalizeToZero360DegD(static_cast(v))); + + } + + double CTraffic::normalizeToZero360DegD(double v) + { + if (std::isnan(v)) { return 0.0; } + const double n = normalizeValue(v, 0, 360.0); + if (n >= 360.0) { return 0.0;} + if (n < 0.0) { return 0.0;} + return n; } bool CTraffic::isValidPosition(const XPMPPlanePosition_t &position) diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index e11ccf9c4..5404b9652 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -196,9 +196,11 @@ namespace XSwiftBus static bool isZeroTo360(double v); //! @} - //! Normalize to (-180, 180] degress @{ - static float normalizeToPlusMinus180DegF(float v); + //! Normalize to (-180, 180] or [0, 360) degrees @{ + static float normalizeToPlusMinus180DegF(float v); static double normalizeToPlusMinus180DegD(double v); + static float normalizeToZero360DegF(float v); + static double normalizeToZero360DegD(double v); //! @} //! Check the position if values are valid @{ diff --git a/tests/blackmisc/simulation/testxplane/testxplane.cpp b/tests/blackmisc/simulation/testxplane/testxplane.cpp index 1e732e8c1..a61c0a34d 100644 --- a/tests/blackmisc/simulation/testxplane/testxplane.cpp +++ b/tests/blackmisc/simulation/testxplane/testxplane.cpp @@ -35,6 +35,7 @@ namespace BlackMiscTest void splitTest(); void acfPropertiesTest(); void xSwiftBusSettingsTest(); + void qtFreeUtils(); }; void CTestXPlane::getFileNameTest() @@ -141,6 +142,40 @@ namespace BlackMiscTest QCOMPARE(s.getDBusServerAddressQt(), s2.getDBusServerAddressQt()); QVERIFY2(s2.getNightTextureModeQt() == "foo", "Expect lower case foo"); } + + void CTestXPlane::qtFreeUtils() + { + double vOut; + vOut = normalizeValue(77.0, 0.0, 360.0); + QVERIFY2(qFuzzyCompare(77.0, vOut), "Wrong normalize 0-360"); + + vOut = normalizeValue(361.0, 0.0, 360.0); + QVERIFY2(qFuzzyCompare(1.0, vOut), "Wrong normalize 0-360"); + + vOut = normalizeValue(-10.0, 0.0, 360.0); + QVERIFY2(qFuzzyCompare(350.0, vOut), "Wrong normalize 0-360"); + + vOut = normalizeValue(-370.0, 0.0, 360.0); + QVERIFY2(qFuzzyCompare(350.0, vOut), "Wrong normalize 0-360"); + + vOut = normalizeValue(-180.0, 0.0, 360.0); + QVERIFY2(qFuzzyCompare(180.0, vOut), "Wrong normalize 0-360"); + + vOut = normalizeValue(-10.0, -180.0, 180.0); + QVERIFY2(qFuzzyCompare(-10.0, vOut), "Wrong normalize +-180"); + + vOut = normalizeValue(100.0, -180.0, 180.0); + QVERIFY2(qFuzzyCompare(100.0, vOut), "Wrong normalize +-180"); + + vOut = normalizeValue(190.0, -180.0, 180.0); + QVERIFY2(qFuzzyCompare(-170.0, vOut), "Wrong normalize +-180"); + + vOut = normalizeValue(360.0, -180.0, 180.0); + QVERIFY2(qFuzzyCompare(0, vOut), "Wrong normalize +-180"); + + vOut = normalizeValue(-190, -180.0, 180.0); + QVERIFY2(qFuzzyCompare(170, vOut), "Wrong normalize +-180"); + } } //! main