mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 12:55:33 +08:00
Add own aircraft to X-Plane plane view menu
ref T269
This commit is contained in:
committed by
Klaus Basan
parent
654cc1621e
commit
0b607f9e0b
@@ -13,6 +13,7 @@
|
||||
#include "weather.h"
|
||||
#include "utils.h"
|
||||
#include "XPLM/XPLMProcessing.h"
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
|
||||
@@ -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<CPlugin *>(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<double>(x) / static_cast<double>(w);
|
||||
double pitch = 20.0 * ((static_cast<double>(y) / static_cast<double>(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<float>(lx + dx);
|
||||
cameraPosition->y = static_cast<float>(ly + dy);
|
||||
cameraPosition->z = static_cast<float>(lz + dz);
|
||||
cameraPosition->pitch = static_cast<float>(pitch);
|
||||
cameraPosition->heading = static_cast<float>(heading);
|
||||
cameraPosition->roll = 0;
|
||||
}
|
||||
|
||||
// Return 1 to indicate we want to keep controlling the camera.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include "dbusconnection.h"
|
||||
#include "datarefs.h"
|
||||
#include "XPLM/XPLMCamera.h"
|
||||
#include "menus.h"
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
@@ -58,13 +61,20 @@ namespace XSwiftBus
|
||||
CMenuItem m_startServerMenuItem;
|
||||
CMenuItem m_toggleMessageWindowMenuItem;
|
||||
CMenu m_planeViewSubMenu;
|
||||
CMenuItem planeViewOwnAircraftMenuItem;
|
||||
|
||||
DataRef<xplane::data::sim::flightmodel::position::local_x> m_ownAircraftPositionX;
|
||||
DataRef<xplane::data::sim::flightmodel::position::local_y> m_ownAircraftPositionY;
|
||||
DataRef<xplane::data::sim::flightmodel::position::local_z> 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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user