From 0b607f9e0bbe7b6316f42f06f6a7f14db47fa52c Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Wed, 16 May 2018 17:13:12 +0200 Subject: [PATCH] Add own aircraft to X-Plane plane view menu ref T269 --- src/xswiftbus/plugin.cpp | 58 +++++++++++++++++++++++++++++++++++++++ src/xswiftbus/plugin.h | 10 +++++++ src/xswiftbus/traffic.cpp | 11 ++++++-- src/xswiftbus/traffic.h | 4 +-- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/xswiftbus/plugin.cpp b/src/xswiftbus/plugin.cpp index 93e2ccc14..908ff04fa 100644 --- a/src/xswiftbus/plugin.cpp +++ b/src/xswiftbus/plugin.cpp @@ -13,6 +13,7 @@ #include "weather.h" #include "utils.h" #include "XPLM/XPLMProcessing.h" +#include #include #include @@ -33,6 +34,7 @@ namespace XSwiftBus // m_startServerMenuItems.push_back(m_menu.item("Start server on system bus", [this]{ startServer(BlackMisc::CDBusServer::systemBusAddress()); })); // m_startServerMenuItems.push_back(m_menu.item("Start server on localhost P2P", [this]{ startServer(BlackMisc::CDBusServer::p2pAddress("localhost")); })); m_planeViewSubMenu = m_menu.subMenu("Plane View"); + planeViewOwnAircraftMenuItem = m_planeViewSubMenu.item("Own Aircraft", [this] { switchToOwnAircraftView(); }); m_dbusThread = std::thread([this]() { @@ -77,6 +79,18 @@ namespace XSwiftBus INFO_LOG("XSwiftBus started."); } + void CPlugin::switchToOwnAircraftView() + { + /* This is the hotkey callback. First we simulate a joystick press and + * release to put us in 'free view 1'. This guarantees that no panels + * are showing and we are an external view. */ + XPLMCommandButtonPress(xplm_joy_v_fr1); + XPLMCommandButtonRelease(xplm_joy_v_fr1); + + /* Now we control the camera until the view changes. */ + XPLMControlCamera(xplm_ControlCameraUntilViewChanges, orbitOwnAircraftFunc, this); + } + void CPlugin::onAircraftModelChanged() { if (m_service) @@ -101,4 +115,48 @@ namespace XSwiftBus if (plugin->m_traffic) { plugin->m_traffic->processDBus(); } return -1; } + + int CPlugin::orbitOwnAircraftFunc(XPLMCameraPosition_t *cameraPosition, int isLosingControl, void *refcon) + { + auto *plugin = static_cast(refcon); + + if (isLosingControl == 1) { return 0; } + + if (cameraPosition) + { + int w, h, x, y; + // First get the screen size and mouse location. We will use this to decide + // what part of the orbit we are in. The mouse will move us up-down and around. + // fixme: In a future update, change the orbit only while right mouse button is pressed. + XPLMGetScreenSize(&w, &h); + XPLMGetMouseLocation(&x, &y); + double heading = 360.0 * static_cast(x) / static_cast(w); + double pitch = 20.0 * ((static_cast(y) / static_cast(h)) * 2.0 - 1.0); + + // Now calculate where the camera should be positioned to be 200 + // meters from the plane and pointing at the plane at the pitch and + // heading we wanted above. + static const double PI = std::acos(-1); + double dx = -50.0 * sin(heading * PI / 180.0); + double dz = 50.0 * cos(heading * PI / 180.0); + double dy = -50.0 * tan(pitch * PI / 180.0); + + double lx, ly, lz; + + lx = plugin->m_ownAircraftPositionX.get(); + ly = plugin->m_ownAircraftPositionY.get(); + lz = plugin->m_ownAircraftPositionZ.get(); + + // Fill out the camera position info. + cameraPosition->x = static_cast(lx + dx); + cameraPosition->y = static_cast(ly + dy); + cameraPosition->z = static_cast(lz + dz); + cameraPosition->pitch = static_cast(pitch); + cameraPosition->heading = static_cast(heading); + cameraPosition->roll = 0; + } + + // Return 1 to indicate we want to keep controlling the camera. + return 1; + } } diff --git a/src/xswiftbus/plugin.h b/src/xswiftbus/plugin.h index 83bb86cd0..8a9a93ddc 100644 --- a/src/xswiftbus/plugin.h +++ b/src/xswiftbus/plugin.h @@ -20,7 +20,10 @@ #ifndef NOMINMAX #define NOMINMAX #endif + #include "dbusconnection.h" +#include "datarefs.h" +#include "XPLM/XPLMCamera.h" #include "menus.h" #include #include @@ -58,13 +61,20 @@ namespace XSwiftBus CMenuItem m_startServerMenuItem; CMenuItem m_toggleMessageWindowMenuItem; CMenu m_planeViewSubMenu; + CMenuItem planeViewOwnAircraftMenuItem; + + DataRef m_ownAircraftPositionX; + DataRef m_ownAircraftPositionY; + DataRef m_ownAircraftPositionZ; std::thread m_dbusThread; bool m_shouldStop = false; void startServer(CDBusConnection::BusType bus); + void switchToOwnAircraftView(); static float flightLoopCallback(float, float, int, void *refcon); + static int orbitOwnAircraftFunc(XPLMCameraPosition_t *cameraPosition, int isLosingControl, void *refcon); }; } diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index a9dfb6122..127193f9c 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -58,6 +58,11 @@ namespace XSwiftBus bool s_legacyDataOK = true; + void CTraffic::setPlaneViewMenu(const CMenu &planeViewSubMenu) + { + m_planeViewSubMenu = planeViewSubMenu; + } + void CTraffic::initLegacyData() { initXPlanePath(); @@ -127,7 +132,7 @@ namespace XSwiftBus sendDBusMessage(signalPlaneAddingFailed); } - void CTraffic::orbitRemotePlane(const std::string &callsign) + void CTraffic::switchToPlaneView(const std::string &callsign) { m_planeViewCallsign = callsign; @@ -232,7 +237,7 @@ namespace XSwiftBus m_planesById[id] = plane; // Create view menu item - CMenuItem planeViewMenuItem = m_planeViewSubMenu.item(callsign, [this, callsign] { orbitRemotePlane(callsign); }); + CMenuItem planeViewMenuItem = m_planeViewSubMenu.item(callsign, [this, callsign] { switchToPlaneView(callsign); }); m_planeViewMenuItems[callsign] = planeViewMenuItem; } } @@ -399,7 +404,7 @@ namespace XSwiftBus auto planeIt = m_planesByCallsign.find(callsign); if (planeIt == m_planesByCallsign.end()) { return; } - orbitRemotePlane(callsign); + switchToPlaneView(callsign); } const char *introspection_traffic = diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index 1e61cf80c..c04618d97 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -56,7 +56,7 @@ namespace XSwiftBus } //! Set plane view submenu - void setPlaneViewMenu(const CMenu &planeViewSubMenu) { m_planeViewSubMenu = planeViewSubMenu; } + void setPlaneViewMenu(const CMenu &planeViewSubMenu); //! Called by XPluginStart static void initLegacyData(); @@ -131,7 +131,7 @@ namespace XSwiftBus void emitSimFrame(); void emitPlaneAdded(const std::string &callsign); void emitPlaneAddingFailed(const std::string &callsign); - void orbitRemotePlane(const std::string &callsign); + void switchToPlaneView(const std::string &callsign); static int preferences(const char *section, const char *name, int def); static float preferences(const char *section, const char *name, float def);