Runway camera location control (#144)

* update ignore

* basics working

* set cam pos remotely

* log cam position

* keep default behaviour, if short view message is received

Compatibility with existing software

* all to tabs

* rename variable

* option to use camera direction fields
This commit is contained in:
Kai Lehmkuehler
2018-11-14 16:56:29 +01:00
committed by Jason Watkins
parent 136e0d5f2b
commit f9bfd6e3b9
3 changed files with 114 additions and 8 deletions

2
.gitignore vendored
View File

@@ -19,6 +19,7 @@
# OS generated files # # OS generated files #
###################### ######################
.DS_Store? .DS_Store?
.DS_Store
ehthumbs.db ehthumbs.db
Icon? Icon?
Thumbs.db Thumbs.db
@@ -69,6 +70,7 @@ build/
xcuserdata xcuserdata
*.moved-aside *.moved-aside
*.xccheckout *.xccheckout
xcshareddata
# IntelliJ Files # # IntelliJ Files #
################## ##################

View File

@@ -20,10 +20,13 @@
#include "Log.h" #include "Log.h"
#include "XPLMUtilities.h" #include "XPLMUtilities.h"
#include "XPLMGraphics.h"
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
namespace XPC namespace XPC
{ {
std::map<std::string, MessageHandlers::ConnectionInfo> MessageHandlers::connections; std::map<std::string, MessageHandlers::ConnectionInfo> MessageHandlers::connections;
@@ -597,7 +600,7 @@ namespace XPC
// Update log // Update log
Log::FormatLine(LOG_TRACE, "SIMU", "Message Received (Conn %i)", connection.id); Log::FormatLine(LOG_TRACE, "SIMU", "Message Received (Conn %i)", connection.id);
char v = msg.GetBuffer()[5]; unsigned char v = msg.GetBuffer()[5];
if (v < 0 || (v > 2 && v < 100) || (v > 119 && v < 200) || v > 219) if (v < 0 || (v > 2 && v < 100) || (v > 119 && v < 200) || v > 219)
{ {
Log::FormatLine(LOG_ERROR, "SIMU", "ERROR: Invalid argument: %i", v); Log::FormatLine(LOG_ERROR, "SIMU", "ERROR: Invalid argument: %i", v);
@@ -686,21 +689,111 @@ namespace XPC
Log::WriteLine(LOG_INFO, "TEXT", "[TEXT] Text set"); Log::WriteLine(LOG_INFO, "TEXT", "[TEXT] Text set");
} }
} }
void MessageHandlers::HandleView(const Message& msg) void MessageHandlers::HandleView(const Message& msg)
{ {
// Update Log // Update Log
Log::FormatLine(LOG_TRACE, "VIEW", "Message Received(Conn %i)", connection.id); Log::FormatLine(LOG_TRACE, "VIEW", "Message Received(Conn %i)", connection.id);
int enable_camera_location = 0;
const std::size_t size = msg.GetSize(); const std::size_t size = msg.GetSize();
if (size != 9) if (size == 9)
{ {
Log::FormatLine(LOG_ERROR, "VIEW", "Error: Unexpected length. Message was %d bytes, expected 9.", size); // default view switcher as before
}
else if (size == 37)
{
// Allow camera location control
enable_camera_location = 1;
}
else
{
Log::FormatLine(LOG_ERROR, "VIEW", "Error: Unexpected length. Message was %d bytes, expected 9 or 37.", size);
return; return;
} }
const unsigned char* buffer = msg.GetBuffer(); const unsigned char* buffer = msg.GetBuffer();
int type = *((int*)(buffer + 5)); int type = *((int*)(buffer + 5));
XPLMCommandKeyStroke(type); XPLMCommandKeyStroke(type);
if(type == 79 && enable_camera_location == 1) // runway camera view
{
static struct CameraProperties campos;
campos.loc[0] = *(double*)(buffer+9);
campos.loc[1] = *(double*)(buffer+17);
campos.loc[2] = *(double*)(buffer+25);
campos.direction[0] = -998;
campos.direction[1] = -998;
campos.direction[2] = -998;
campos.zoom = *(float*)(buffer+33);
Log::FormatLine(LOG_TRACE, "VIEW", "Cam pos %f %f %f zoom %f", campos.loc[0], campos.loc[1], campos.loc[2],campos.zoom);
XPLMControlCamera(xplm_ControlCameraUntilViewChanges, CamFunc, &campos);
}
}
int MessageHandlers::CamFunc( XPLMCameraPosition_t * outCameraPosition, int inIsLosingControl, void *inRefcon)
{
if (outCameraPosition && !inIsLosingControl)
{
struct CameraProperties* campos = (struct CameraProperties*)inRefcon;
// camera position
double clat = campos->loc[0];
double clon = campos->loc[1];
double calt = campos->loc[2];
double cX, cY, cZ;
XPLMWorldToLocal(clat, clon, calt, &cX, &cY, &cZ);
outCameraPosition->x = cX;
outCameraPosition->y = cY;
outCameraPosition->z = cZ;
// Log::FormatLine(LOG_TRACE, "CAM", "Cam pos %f %f %f", clat, clon, calt);
if(campos->direction[0] == -998) // calculate camera direction
{
// aircraft position
double x = XPC::DataManager::GetDouble(XPC::DREF_LocalX, 0);
double y = XPC::DataManager::GetDouble(XPC::DREF_LocalY, 0);
double z = XPC::DataManager::GetDouble(XPC::DREF_LocalZ, 0);
// relative position vector cam to plane
double dx = x - cX;
double dy = y - cY;
double dz = z - cZ;
// Log::FormatLine(LOG_TRACE, "CAM", "Cam vect %f %f %f", dx, dy, dz);
double pi = 3.141592653589793;
// horizontal distance
double dist = sqrt(dx*dx + dz*dz);
outCameraPosition->pitch = atan2(dy, dist) * 180.0/pi;
double angle = atan2(dz, dx) * 180.0/pi; // rel to pos right (pos X)
outCameraPosition->heading = 90 + angle; // rel to north
// Log::FormatLine(LOG_TRACE, "CAM", "Cam p %f hdg %f ", outCameraPosition->pitch, outCameraPosition->heading);
outCameraPosition->roll = 0;
}
else
{
outCameraPosition->roll = campos->direction[0];
outCameraPosition->pitch = campos->direction[1];
outCameraPosition->heading = campos->direction[2];
}
outCameraPosition->zoom = campos->zoom;
}
return 1;
} }
void MessageHandlers::HandleWypt(const Message& msg) void MessageHandlers::HandleWypt(const Message& msg)

View File

@@ -7,6 +7,9 @@
#include <string> #include <string>
#include <map> #include <map>
#include "XPLMCamera.h"
namespace XPC namespace XPC
{ {
/// A function that handles a message. /// A function that handles a message.
@@ -26,10 +29,10 @@ namespace XPC
/// socket. /// socket.
/// ///
/// \details After a message is read, HandleMessage analyzes the sender's network address /// \details After a message is read, HandleMessage analyzes the sender's network address
/// to determine whether the sender is a new client. It then either loads /// to determine whether the sender is a new client. It then either loads
/// connection details for an existing client, or creates a new connection record /// connection details for an existing client, or creates a new connection record
/// for new clients. Finally, the message handler checks the message type and /// for new clients. Finally, the message handler checks the message type and
/// dispatches the message to the appropriate handler. /// dispatches the message to the appropriate handler.
/// \param msg The message to be processed. /// \param msg The message to be processed.
static void HandleMessage(Message& msg); static void HandleMessage(Message& msg);
@@ -54,6 +57,14 @@ namespace XPC
static void HandleXPlaneData(const Message& msg); static void HandleXPlaneData(const Message& msg);
static void HandleUnknown(const Message& msg); static void HandleUnknown(const Message& msg);
static int CamFunc( XPLMCameraPosition_t * outCameraPosition, int inIsLosingControl, void *inRefcon);
struct CameraProperties{
double loc[3];
float direction[3];
float zoom;
};
typedef struct typedef struct
{ {