#include #include #include "XPLMDisplay.h" #include "XPLMGraphics.h" #include "XPLMCamera.h" #include "XPLMPlanes.h" #include "XPLMUtilities.h" #include "XPLMDataAccess.h" #if LIN #include #else #if __GNUC__ #include #else #include #include <..\..\..\..\..\..\..\program files (x86)\microsoft sdks\windows\v7.0a\include\gl\gl.h> #endif #endif #include "AircraftUtils.h" #include using namespace System; using namespace System::Net; using namespace System::Net::Sockets; public ref class Globals abstract sealed { public: static IPEndPoint^ RemoteIpEndPoint = gcnew IPEndPoint( IPAddress::Any, 4900 ); static Socket^ XplanesSEND = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram, ProtocolType::Udp); }; XPLMDataRef gPlaneX = NULL; XPLMDataRef gPlaneY = NULL; XPLMDataRef gPlaneZ = NULL; XPLMDataRef gPlaneTheta = NULL; XPLMDataRef gPlanePhi = NULL; XPLMDataRef gPlanePsi = NULL; XPLMDataRef gOverRidePlanePosition = NULL; XPLMDataRef gAGL = NULL; XPLMDataRef gLatRef = NULL; XPLMDataRef gLongRef = NULL; float fTextColour[3]; char szString[100]; const double kMaxPlaneDistance = 5280.0 / 3.2 * 10.0; const double kFullPlaneDist = 5280.0 / 3.2 * 3.0; static inline float sqr(float a) { return a * a; } static inline float CalcDist3D(float x1, float y1, float z1, float x2, float y2, float z2) { return sqrt(sqr(x2-x1) + sqr(y2-y1) + sqr(z2-z1)); } const double kFtToMeters = 0.3048; static XPLMDataRef gFOVDataRef = NULL; int AircraftDrawCallback( XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon); PLUGIN_API int XPluginStart( char * outName, char * outSig, char * outDesc) { int planeCount; XPLMCountAircraft(&planeCount, 0, 0); fTextColour[0] = 1.0; fTextColour[1] = 1.0; fTextColour[2] = 1.0; strcpy(outName, "Quad Hil"); strcpy(outSig, "based on xplanesdk.examples.drawaircraft"); strcpy(outDesc, "A plugin that receives raw data to display"); /* Prefetch the sim variables we will use. */ gPlaneX = XPLMFindDataRef("sim/flightmodel/position/local_x"); gPlaneY = XPLMFindDataRef("sim/flightmodel/position/local_y"); gPlaneZ = XPLMFindDataRef("sim/flightmodel/position/local_z"); gPlaneTheta = XPLMFindDataRef("sim/flightmodel/position/theta"); gPlanePhi = XPLMFindDataRef("sim/flightmodel/position/phi"); gPlanePsi = XPLMFindDataRef("sim/flightmodel/position/psi"); gOverRidePlanePosition = XPLMFindDataRef("sim/operation/override/override_planepath"); gAGL = XPLMFindDataRef("sim/flightmodel/position/y_agl"); gLatRef = XPLMFindDataRef("sim/flightmodel/position/lat_ref"); gLongRef = XPLMFindDataRef("sim/flightmodel/position/lon_ref"); /* Next register the drawing callback. We want to be drawn * after X-Plane draws its 3-d objects. */ XPLMRegisterDrawCallback( AircraftDrawCallback, xplm_Phase_Window, /* Draw when sim is doing objects */ 0, /* After objects */ NULL); /* No refcon needed */ Globals::XplanesSEND->Bind(Globals::RemoteIpEndPoint); /* char FileName[256], AircraftPath[256]; for (long index = 0; index < planeCount; ++index) { XPLMGetNthAircraftModel(index, FileName, AircraftPath); pAircraft[index] = (char *)AircraftPath; if (XPLMAcquirePlanes((char **)&pAircraft, NULL, NULL)) XPLMSetAircraftModel(index, AircraftPath); } */ return 1; } PLUGIN_API void XPluginStop(void) { } PLUGIN_API void XPluginDisable(void) { int Enable[10]; Enable[0] = 0; XPLMSetDatavi(gOverRidePlanePosition,&Enable[0],0,1); // disable physics } PLUGIN_API int XPluginEnable(void) { int Enable[10]; Enable[0] = 1; XPLMSetDatavi(gOverRidePlanePosition,&Enable[0],0,1); // disable physics return 1; } PLUGIN_API void XPluginReceiveMessage( XPLMPluginID inFromWho, long inMessage, void * inParam) { } /* * AircraftDrawCallback * * This is the actual drawing callback that does the work; for us it will * be called after X-Plane has drawn its 3-d objects. The coordinate system * is 'normal' for 3-d drawing, meaning 0,0,0 is at the earth's surface at the * lat/lon reference point, with +Y = up, +Z = South, +X = East. (Note that * these relationships are only true at 0,0,0 due to the Earth's curvature!!) * * Drawing hooks that draw before X-Plane return 1 to let X-Plane draw or 0 * to inhibit drawing. For drawing hooks that run after X-Plane, this return * value is ignored but we will return 1 anyway. * */ public struct quad { double t1; double t2; double t3; double t4; double lat; double lng; double alt; double altagl; double roll; double pitch; double yaw; }; int AircraftDrawCallback( XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon) { if (Globals::XplanesSEND->Available > 0) { array^bytesReceived = gcnew array(256); int bytes = 0; bytes = Globals::XplanesSEND->Receive( bytesReceived, bytesReceived->Length, static_cast(0) ); int count = 0; double t1 = BitConverter::ToDouble(bytesReceived, count * 8); count++; double t2 = BitConverter::ToDouble(bytesReceived, count * 8); count++; double t3 = BitConverter::ToDouble(bytesReceived, count * 8); count++; double t4 = BitConverter::ToDouble(bytesReceived, count * 8); count++; double lat = BitConverter::ToDouble(bytesReceived, count * 8); count++; double lng = BitConverter::ToDouble(bytesReceived, count * 8); count++; double alt = BitConverter::ToDouble(bytesReceived, count * 8); count++; double altagl = BitConverter::ToDouble(bytesReceived, count * 8); count++; double roll = BitConverter::ToDouble(bytesReceived, count * 8); count++; double pitch = BitConverter::ToDouble(bytesReceived, count * 8); count++; double yaw = BitConverter::ToDouble(bytesReceived, count * 8); double X,Y,Z; XPLMSetDataf(gLatRef,(float)lat); XPLMSetDataf(gLongRef,(float)lng); XPLMWorldToLocal(lat,lng,alt * kFtToMeters,&X,&Y,&Z); XPLMSetDataf(gPlaneX, X); XPLMSetDataf(gPlaneY, Y); XPLMSetDataf(gPlaneZ, Z); XPLMSetDataf(gPlaneTheta, pitch); XPLMSetDataf(gPlanePhi, roll); XPLMSetDataf(gPlanePsi, yaw); sprintf(szString,"m1: %f, m2: %f, m3: %f, m4: %f\0", t1,t2,t3,t4); XPLMDrawString(fTextColour,700,700,szString,NULL,xplmFont_Basic); return 1; } else { return 1; } double x,y,z,theta,phi,psi; //double Lat = 34.09, Lon = -117.25, Alt = 1170; float Heading = 0, Pitch = 0, Roll = 0, Altitude; x = XPLMGetDataf(gPlaneX); y = XPLMGetDataf(gPlaneY); z = XPLMGetDataf(gPlaneZ); theta = XPLMGetDataf(gPlaneTheta); phi = XPLMGetDataf(gPlanePhi); psi = XPLMGetDataf(gPlanePsi); Altitude = XPLMGetDataf(gAGL); XPLMSetDataf(gPlaneX, x + 1); return 1; }