swift
traffic.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #ifndef SWIFT_SIM_XSWIFTBUS_TRAFFIC_H
5 #define SWIFT_SIM_XSWIFTBUS_TRAFFIC_H
6 
8 
9 #include <XPLM/XPLMCamera.h>
10 #include <XPLM/XPLMDisplay.h>
11 
12 #include <functional>
13 #include <utility>
14 
15 #include "XPMPMultiplayer.h"
16 #include "command.h"
17 #include "datarefs.h"
18 #include "dbusobject.h"
19 #include "drawable.h"
20 #include "menus.h"
21 #include "settings.h"
22 #include "terrainprobe.h"
23 
25 #define XSWIFTBUS_TRAFFIC_INTERFACENAME "org.swift_project.xswiftbus.traffic"
26 #define XSWIFTBUS_TRAFFIC_OBJECTPATH "/xswiftbus/traffic"
28 
29 namespace XSwiftBus
30 {
34  class CTraffic : public CDBusObject
35  {
36  public:
38  CTraffic(CSettingsProvider *settingsProvider);
39 
41  virtual ~CTraffic() override;
42 
44  static const std::string &InterfaceName()
45  {
46  static std::string s(XSWIFTBUS_TRAFFIC_INTERFACENAME);
47  return s;
48  }
49 
51  static const std::string &ObjectPath()
52  {
53  static std::string s(XSWIFTBUS_TRAFFIC_OBJECTPATH);
54  return s;
55  }
56 
58  void setPlaneViewMenu(const CMenu &planeViewSubMenu);
59 
61  bool initialize();
62 
65  bool acquireMultiplayerPlanes(std::string *owner = nullptr);
66 
68  void cleanup();
69 
71  std::string loadPlanesPackage(const std::string &path);
72 
74  void setDefaultIcao(const std::string &defaultIcao);
75 
77  void setDrawingLabels(bool drawing, int rgb = -1);
78 
80  bool isDrawingLabels() const;
81 
83  void setMaxPlanes(int planes);
84 
86  void setMaxDrawDistance(double nauticalMiles);
87 
89  void addPlane(const std::string &callsign, const std::string &modelName, const std::string &aircraftIcao,
90  const std::string &airlineIcao, const std::string &livery);
91 
93  void removePlane(const std::string &callsign);
94 
97 
99  void setPlanesPositions(const std::vector<std::string> &callsigns, std::vector<double> latitudesDeg,
100  std::vector<double> longitudesDeg, std::vector<double> altitudesFt,
101  std::vector<double> pitchesDeg, std::vector<double> rollsDeg,
102  std::vector<double> headingsDeg, const std::vector<bool> &onGrounds);
103 
105  void setPlanesSurfaces(const std::vector<std::string> &callsigns, const std::vector<double> &gears,
106  const std::vector<double> &flaps, const std::vector<double> &spoilers,
107  const std::vector<double> &speedBrakes, const std::vector<double> &slats,
108  const std::vector<double> &wingSweeps, const std::vector<double> &thrusts,
109  const std::vector<double> &elevators, const std::vector<double> &rudders,
110  const std::vector<double> &ailerons, const std::vector<bool> &landLights,
111  const std::vector<bool> &taxiLights, const std::vector<bool> &beaconLights,
112  const std::vector<bool> &strobeLights, const std::vector<bool> &navLights,
113  const std::vector<int> &lightPatterns);
114 
116  void setPlanesTransponders(const std::vector<std::string> &callsigns, const std::vector<int> &codes,
117  const std::vector<bool> &modeCs, const std::vector<bool> &idents);
118 
120  void getRemoteAircraftData(std::vector<std::string> &callsigns, std::vector<double> &latitudesDeg,
121  std::vector<double> &longitudesDeg, std::vector<double> &elevationsM,
122  std::vector<bool> &waterFlags, std::vector<double> &verticalOffsets) const;
123 
125  std::array<double, 3> getElevationAtPosition(const std::string &callsign, double latitudeDeg,
126  double longitudeDeg, double altitudeMeters, bool &o_isWater) const;
127 
129  void setFollowedAircraft(const std::string &callsign);
130 
132  int process();
133 
135  static const std::string &ownAircraftString()
136  {
137  static const std::string o = "ownAircraft";
138  return o;
139  }
140 
141  protected:
143  virtual void dbusDisconnectedHandler() override;
144 
146  DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) override;
147 
148  private:
150  struct DeltaCameraPosition
151  {
152  double dxMeters = 0.0;
153  double dyMeters = 0.0;
154  double dzMeters = 0.0;
155  double headingDeg = 0.0;
156  double pitchDeg = 0.0;
157  bool isInitialized = false;
158  };
159 
160  bool m_initialized = false;
161  bool m_enabledMultiplayer = false;
162  CTerrainProbe m_terrainProbe;
163 
164  void emitSimFrame();
165  void emitPlaneAdded(const std::string &callsign);
166  void emitPlaneAddingFailed(const std::string &callsign);
167  void switchToFollowPlaneView(const std::string &callsign);
168  void followNextPlane();
169  void followPreviousPlane();
170  bool containsCallsign(const std::string &callsign) const;
171 
172  static CTraffic *s_instance;
173  XPMPConfiguration_t m_configuration = {};
174  void updateConfiguration();
175 
176  static int orbitPlaneFunc(XPLMCameraPosition_t *cameraPosition, int isLosingControl, void *refcon);
177  static int followAircraftKeySniffer(char character, XPLMKeyFlags flags, char virtualKey, void *refcon);
178 
180  struct Plane
181  {
182  void *id = nullptr;
183  std::string callsign;
184  std::string aircraftIcao;
185  std::string airlineIcao;
186  std::string livery;
187  std::string modelName;
188  std::string nightTextureMode;
189  bool hasSurfaces = false;
190  bool isOnGround = false;
191  char label[32] {};
192  CTerrainProbe terrainProbe;
193  XPMPPlaneSurfaces_t surfaces;
194  float targetGearPosition = 0;
195  std::chrono::steady_clock::time_point prevSurfacesLerpTime;
196  std::chrono::steady_clock::time_point positionTimes[3];
197  XPMPPlanePosition_t positions[4]; // 1 as input for extrapolation, 1 as next input, 1 latest, 1 as output
198  XPMPPlaneSurveillance_t surveillance;
199  Plane(void *id_, const std::string &callsign_, const std::string &aircraftIcao_,
200  const std::string &airlineIcao_, const std::string &livery_, const std::string &modelName_);
201  };
202 
204  class Labels : public CDrawable
205  {
206  public:
207  Labels(CTraffic *traffic) : CDrawable(xplm_Phase_Window, false), m_traffic(traffic) {}
208  void setColor(int r, int g, int b)
209  {
210  m_color = { { static_cast<float>(r) / 255.f, static_cast<float>(g) / 255.f,
211  static_cast<float>(b) / 255.f } };
212  }
213 
214  protected:
215  virtual void draw() override;
216 
217  private:
218  static void matrixMultVec(double out[4], const float m[16], const double v[4]);
219  double distanceSquared(const double pos[3]) const;
220  CTraffic *m_traffic = nullptr;
221  std::array<float, 3> m_color { { 1.0f, 0.75f, 0.0f } };
222  ArrayDataRef<xplane::data::sim::graphics::view::world_matrix> m_worldMat;
223  ArrayDataRef<xplane::data::sim::graphics::view::projection_matrix_3d> m_projMat;
224  DataRef<xplane::data::sim::graphics::view::window_width> m_windowWidth;
225  DataRef<xplane::data::sim::graphics::view::window_height> m_windowHeight;
226  DataRef<xplane::data::sim::graphics::view::visibility_effective_m> m_visibilityM;
227  DataRef<xplane::data::sim::graphics::view::view_x> m_viewX;
228  DataRef<xplane::data::sim::graphics::view::view_y> m_viewY;
229  DataRef<xplane::data::sim::graphics::view::view_z> m_viewZ;
230  };
231  Labels m_labels { this };
232 
235  static bool isPlusMinus180(float v);
236  static bool isPlusMinus180(double v);
238 
241  static float normalizeToPlusMinus180Deg(float v);
242  static double normalizeToPlusMinus180Deg(double v);
243  static float normalizeToZero360Deg(float v);
244  static double normalizeToZero360Deg(double v);
246 
249  static bool isValidPosition(const XPMPPlanePosition_t &position);
250  static bool isValidPosition(const XPLMCameraPosition_t *camPos);
252 
255  static std::string pos2String(const XPMPPlanePosition_t &position);
256  static std::string pos2String(const XPLMCameraPosition_t *camPos);
258 
259  std::unordered_map<std::string, std::string> m_modelStrings; // mapping uppercase to mixedcase
260  std::unordered_map<std::string, Plane *> m_planesByCallsign;
261  std::unordered_map<void *, Plane *> m_planesById;
262  std::vector<std::string> m_followPlaneViewSequence;
263  // std::chrono::system_clock::time_point m_timestampLastSimFrame = std::chrono::system_clock::now();
264 
265  CMenu m_followPlaneViewSubMenu;
266  std::unordered_map<std::string, CMenuItem> m_followPlaneViewMenuItems;
267  std::string m_followPlaneViewCallsign;
268  CCommand m_followPlaneViewNextCommand;
269  CCommand m_followPlaneViewPreviousCommand;
270 
271  DataRef<xplane::data::sim::flightmodel::position::local_x> m_ownAircraftPositionX;
272  DataRef<xplane::data::sim::flightmodel::position::local_y> m_ownAircraftPositionY;
273  DataRef<xplane::data::sim::flightmodel::position::local_z> m_ownAircraftPositionZ;
274 
275  bool m_isSpacePressed = false;
276  int m_lastMouseX = -1;
277  int m_lastMouseY = -1;
278  double m_followAircraftDistanceMultiplier = 1.0;
279  DeltaCameraPosition m_deltaCameraPosition;
280 
281  bool m_emitSimFrame = true;
282  int m_countFrame = 0;
283 
284  std::vector<XPMPUpdate_t> m_updates;
285  void doPlaneUpdates();
286  void interpolatePosition(Plane *);
287  void interpolateGear(Plane *);
288  };
289 } // namespace XSwiftBus
290 
291 #endif // SWIFT_SIM_XSWIFTBUS_TRAFFIC_H
DBus base object.
Definition: dbusobject.h:20
CDrawable(XPLMDrawingPhase phase, bool before)
Constructor.
Definition: drawable.h:21
Class-based interface to X-Plane SDK menus.
Definition: menus.h:63
Something owning the settings.
Definition: settings.h:31
Class based interface to X-Plane SDK terrain probe.
Definition: terrainprobe.h:18
xswiftbus service object for traffic aircraft which is accessible through DBus
Definition: traffic.h:35
void removePlane(const std::string &callsign)
Remove a traffic aircraft.
void setDrawingLabels(bool drawing, int rgb=-1)
Set whether the plugin draws type and callsign labels above aircraft.
DBusHandlerResult dbusMessageHandler(const CDBusMessage &message)
Handler.
CTraffic(CSettingsProvider *settingsProvider)
Constructor.
bool isDrawingLabels() const
Get whether the plugin draws type and callsign labels above aircraft.
bool acquireMultiplayerPlanes(std::string *owner=nullptr)
Returns whether multiplayer planes have been acquired. If not, owner will be set to the plugin that a...
bool initialize()
Initialize the multiplayer planes rendering and return true if successful.
void setPlanesTransponders(const std::vector< std::string > &callsigns, const std::vector< int > &codes, const std::vector< bool > &modeCs, const std::vector< bool > &idents)
Set the transponder of multiple traffic aircraft.
void setDefaultIcao(const std::string &defaultIcao)
Set the ICAO code to use for aircraft without a model match.
virtual ~CTraffic()
Destructor.
int process()
Perform generic processing.
std::string loadPlanesPackage(const std::string &path)
Load a collection of planes from the given directory and return error message if unsuccessful.
void setPlaneViewMenu(const CMenu &planeViewSubMenu)
Set plane view submenu.
void cleanup()
Reverse the actions of initialize().
static const std::string & ownAircraftString()
Returns the own aircraft string to be used as callsign for setFollowedAircraft()
Definition: traffic.h:135
std::array< double, 3 > getElevationAtPosition(const std::string &callsign, double latitudeDeg, double longitudeDeg, double altitudeMeters, bool &o_isWater) const
Get the ground elevation at an arbitrary position.
static const std::string & ObjectPath()
DBus object path.
Definition: traffic.h:51
void setMaxDrawDistance(double nauticalMiles)
Set the maximum distance at which to draw aircraft (nautical miles).
virtual void dbusDisconnectedHandler()
Handler.
void removeAllPlanes()
Remove all traffic aircraft.
void getRemoteAircraftData(std::vector< std::string > &callsigns, std::vector< double > &latitudesDeg, std::vector< double > &longitudesDeg, std::vector< double > &elevationsM, std::vector< bool > &waterFlags, std::vector< double > &verticalOffsets) const
Get remote aircrafts data (lat, lon, elevation and CG)
void setMaxPlanes(int planes)
Set the maximum number of aircraft.
void setFollowedAircraft(const std::string &callsign)
Sets the aircraft with callsign to be followed in plane view.
void addPlane(const std::string &callsign, const std::string &modelName, const std::string &aircraftIcao, const std::string &airlineIcao, const std::string &livery)
Introduce a new traffic aircraft.
void setPlanesPositions(const std::vector< std::string > &callsigns, std::vector< double > latitudesDeg, std::vector< double > longitudesDeg, std::vector< double > altitudesFt, std::vector< double > pitchesDeg, std::vector< double > rollsDeg, std::vector< double > headingsDeg, const std::vector< bool > &onGrounds)
Set the position of multiple traffic aircrafts.
void setPlanesSurfaces(const std::vector< std::string > &callsigns, const std::vector< double > &gears, const std::vector< double > &flaps, const std::vector< double > &spoilers, const std::vector< double > &speedBrakes, const std::vector< double > &slats, const std::vector< double > &wingSweeps, const std::vector< double > &thrusts, const std::vector< double > &elevators, const std::vector< double > &rudders, const std::vector< double > &ailerons, const std::vector< bool > &landLights, const std::vector< bool > &taxiLights, const std::vector< bool > &beaconLights, const std::vector< bool > &strobeLights, const std::vector< bool > &navLights, const std::vector< int > &lightPatterns)
Set the flight control surfaces and lights of multiple traffic aircrafts.
static const std::string & InterfaceName()
DBus interface name.
Definition: traffic.h:44
Plugin loaded by X-Plane which publishes a DBus service.
Definition: command.h:14