mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-07 11:05:33 +08:00
Resolved differences between XSB xivap and Martin's subversion repository
This commit is contained in:
@@ -137,9 +137,9 @@ typedef struct {
|
|||||||
float slatRatio;
|
float slatRatio;
|
||||||
float wingSweep;
|
float wingSweep;
|
||||||
float thrust;
|
float thrust;
|
||||||
float yolkPitch;
|
float yokePitch;
|
||||||
float yolkHeading;
|
float yokeHeading;
|
||||||
float yolkRoll;
|
float yokeRoll;
|
||||||
xpmp_LightStatus lights;
|
xpmp_LightStatus lights;
|
||||||
} XPMPPlaneSurfaces_t;
|
} XPMPPlaneSurfaces_t;
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ typedef int XPMPPlaneDataType;
|
|||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
xpmpData_Unavailable = 0, /* The information has never been specified. */
|
xpmpData_Unavailable = 0, /* The information has never been specified. */
|
||||||
xpmpData_Unchanged = 1, /* The information from the last time the plug-in was aksed. */
|
xpmpData_Unchanged = 1, /* The information from the last time the plug-in was asked. */
|
||||||
xpmpData_NewData = 2 /* The information has changed this sim cycle. */
|
xpmpData_NewData = 2 /* The information has changed this sim cycle. */
|
||||||
};
|
};
|
||||||
typedef int XPMPPlaneCallbackResult;
|
typedef int XPMPPlaneCallbackResult;
|
||||||
@@ -463,6 +463,19 @@ typedef void (* XPMPRenderPlanes_f)(
|
|||||||
*/
|
*/
|
||||||
void XPMPDumpOneCycle(void);
|
void XPMPDumpOneCycle(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPMPEnableAircraftLabels
|
||||||
|
* XPMPDisableAircraftLabels
|
||||||
|
*
|
||||||
|
* These functions enable and disable the drawing of aircraft labels above the aircraft
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void XPMPEnableAircraftLabels(void);
|
||||||
|
|
||||||
|
void XPMPDisableAircraftLabels(void);
|
||||||
|
|
||||||
|
bool XPMPDrawingAircraftLabels(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#include "ptypes.h"
|
#include "ptypes.h"
|
||||||
#include "pasync.h"
|
#include "pasync.h"
|
||||||
|
|
||||||
#include "XPLMMultiplayerCSL.h"
|
#include "XPMPMultiplayerCSL.h"
|
||||||
#include "XPLMMultiplayerObj.h"
|
#include "XPMPMultiplayerObj.h"
|
||||||
|
|
||||||
USING_PTYPES
|
USING_PTYPES
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "ptypes.h"
|
#include "ptypes.h"
|
||||||
#include "pasync.h"
|
#include "pasync.h"
|
||||||
|
|
||||||
#include "XPLMMultiplayerCSL.h"
|
#include "XPMPMultiplayerCSL.h"
|
||||||
|
|
||||||
const int MSG_LOADJOB_OBJ = 1;
|
const int MSG_LOADJOB_OBJ = 1;
|
||||||
const int MSG_LOADJOB_TEX = 2;
|
const int MSG_LOADJOB_TEX = 2;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "PlatformUtils.h"
|
#include "PlatformUtils.h"
|
||||||
|
|
||||||
//#define _STDINT_H_
|
//#define _STDINT_H_
|
||||||
#include <Endian.h>
|
//#include <Endian.h>
|
||||||
//#include <Dialogs.h>
|
//#include <Dialogs.h>
|
||||||
//#include <Navigation.h>
|
//#include <Navigation.h>
|
||||||
//#include <string.h>
|
//#include <string.h>
|
||||||
@@ -39,16 +39,12 @@ static OSErr FSSpecToPathName(const FSSpec * inFileSpec, char * outPathname);
|
|||||||
|
|
||||||
void EndianFlipShort(short * ioShort)
|
void EndianFlipShort(short * ioShort)
|
||||||
{
|
{
|
||||||
#if defined(__POWERPC__)
|
|
||||||
*ioShort = Endian16_Swap(*ioShort);
|
*ioShort = Endian16_Swap(*ioShort);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndianFlipLong(long * ioLong)
|
void EndianFlipLong(long * ioLong)
|
||||||
{
|
{
|
||||||
#if defined(__POWERPC__)
|
|
||||||
*ioLong = Endian32_Swap(*ioLong);
|
*ioLong = Endian32_Swap(*ioLong);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get FilePathFromUser puts up a nav services dialog box and converts the results
|
/* Get FilePathFromUser puts up a nav services dialog box and converts the results
|
||||||
@@ -68,6 +64,8 @@ struct CFSmartPtr {
|
|||||||
|
|
||||||
int HFS2PosixPath(const char *path, char *result, int resultLen)
|
int HFS2PosixPath(const char *path, char *result, int resultLen)
|
||||||
{
|
{
|
||||||
|
bool is_dir = (path[strlen(path)-1] == ':');
|
||||||
|
|
||||||
CFSmartPtr<CFStringRef> inStr(CFStringCreateWithCString(kCFAllocatorDefault, path ,kCFStringEncodingMacRoman));
|
CFSmartPtr<CFStringRef> inStr(CFStringCreateWithCString(kCFAllocatorDefault, path ,kCFStringEncodingMacRoman));
|
||||||
if (inStr == NULL) return -1;
|
if (inStr == NULL) return -1;
|
||||||
|
|
||||||
@@ -80,6 +78,8 @@ int HFS2PosixPath(const char *path, char *result, int resultLen)
|
|||||||
if (!CFStringGetCString(outStr, result, resultLen, kCFStringEncodingMacRoman))
|
if (!CFStringGetCString(outStr, result, resultLen, kCFStringEncodingMacRoman))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if(is_dir) strcat(result, "/");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,12 +60,9 @@ OSStatus aglInitEntryPoints (void)
|
|||||||
fileRefParam.ioNamePtr = frameworkName;
|
fileRefParam.ioNamePtr = frameworkName;
|
||||||
fileRefParam.newRef = &fileRef;
|
fileRefParam.newRef = &fileRef;
|
||||||
|
|
||||||
// For some reason an explicit cast satisfies gcc TDG
|
|
||||||
SInt32 fileRefParamIO_DirID = static_cast<SInt32>(fileRefParam.ioDirID);
|
|
||||||
|
|
||||||
// Frameworks directory/folder
|
// Frameworks directory/folder
|
||||||
err = FindFolder (kSystemDomain, kFrameworksFolderType, false,
|
err = FindFolder (kSystemDomain, kFrameworksFolderType, false,
|
||||||
&fileRefParam.ioVRefNum, &fileRefParamIO_DirID);
|
&fileRefParam.ioVRefNum, (SInt32 *) &fileRefParam.ioDirID);
|
||||||
if (noErr != err) {
|
if (noErr != err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
#include <gl/glext.h>
|
#include <GL/glext.h>
|
||||||
#elif LIN
|
#elif LIN
|
||||||
#define GLX_GLXEXT_PROTOTYPES
|
#define GLX_GLXEXT_PROTOTYPES
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
|||||||
@@ -480,11 +480,7 @@ int XPMPRenderMultiplayerPlanes(
|
|||||||
gRenderer(gRendererRef);
|
gRenderer(gRendererRef);
|
||||||
else
|
else
|
||||||
XPMPDefaultPlaneRenderer();
|
XPMPDefaultPlaneRenderer();
|
||||||
#if XTWR // We don't want to see our own plane!
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XPMPIsICAOValid(
|
bool XPMPIsICAOValid(
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "PlatformUtils.h"
|
#include "PlatformUtils.h"
|
||||||
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
using std::max;
|
using std::max;
|
||||||
@@ -220,9 +220,16 @@ bool LoadOnePackage(const string& inPath, int pass)
|
|||||||
int sim, xplm;
|
int sim, xplm;
|
||||||
XPLMHostApplicationID host;
|
XPLMHostApplicationID host;
|
||||||
|
|
||||||
|
#ifdef DEBUG_CSL_LOADING
|
||||||
|
XPLMDump() << "LoadOnePackage was passed inPath of: " << inPath << ".\n";
|
||||||
|
#endif
|
||||||
// First locate and attempt to load the xsb_aircraft.txt file from th is package.
|
// First locate and attempt to load the xsb_aircraft.txt file from th is package.
|
||||||
string path(inPath);
|
string path(inPath);
|
||||||
path += (DIR_STR "xsb_aircraft.txt");
|
path += (DIR_STR "xsb_aircraft.txt");
|
||||||
|
#ifdef DEBUG_CSL_LOADING
|
||||||
|
XPLMDump() << "LoadOnePackage attempting to open: " << path << ".\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
FILE * fi = fopen(path.c_str(), "r");
|
FILE * fi = fopen(path.c_str(), "r");
|
||||||
|
|
||||||
XPLMGetVersions(&sim, &xplm, &host);
|
XPLMGetVersions(&sim, &xplm, &host);
|
||||||
@@ -524,7 +531,7 @@ bool LoadOnePackage(const string& inPath, int pass)
|
|||||||
}
|
}
|
||||||
fclose(fi);
|
fclose(fi);
|
||||||
} else {
|
} else {
|
||||||
XPLMDump() << "XSB WARNING: package '" << inPath << "' could not be opened.\n";
|
XPLMDump() << "XSB WARNING: package '" << inPath << "' could not be opened. Error was: " << strerror(errno) << ".\n";
|
||||||
}
|
}
|
||||||
return parse_err;
|
return parse_err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,39 +58,110 @@
|
|||||||
// Maximum altitude difference in feet for TCAS blips
|
// Maximum altitude difference in feet for TCAS blips
|
||||||
#define MAX_TCAS_ALTDIFF 5000
|
#define MAX_TCAS_ALTDIFF 5000
|
||||||
|
|
||||||
|
// Even in good weather we don't want labels on things
|
||||||
|
// that we can barely see. Cut labels at 5 km.
|
||||||
|
#define MAX_LABEL_DIST 5000.0
|
||||||
|
|
||||||
|
|
||||||
std::vector<XPLMDataRef> gMultiRef_X;
|
std::vector<XPLMDataRef> gMultiRef_X;
|
||||||
std::vector<XPLMDataRef> gMultiRef_Y;
|
std::vector<XPLMDataRef> gMultiRef_Y;
|
||||||
std::vector<XPLMDataRef> gMultiRef_Z;
|
std::vector<XPLMDataRef> gMultiRef_Z;
|
||||||
|
|
||||||
/* UTILITY FUNCTIONS */
|
bool gDrawLabels = true;
|
||||||
|
|
||||||
static inline double sqr(double a) { return a * a; }
|
struct cull_info_t { // This struct has everything we need to cull fast!
|
||||||
static inline double CalcDist3D(double x1, double y1, double z1, double x2, double y2, double z2)
|
float model_view[16]; // The model view matrix, to get from local OpenGL to eye coordinates.
|
||||||
|
float proj[16]; // Proj matrix - this is just a hack to use for gluProject.
|
||||||
|
float nea_clip[4]; // Four clip planes in the form of Ax + By + Cz + D = 0 (ABCD are in the array.)
|
||||||
|
float far_clip[4]; // They are oriented so the positive side of the clip plane is INSIDE the view volume.
|
||||||
|
float lft_clip[4];
|
||||||
|
float rgt_clip[4];
|
||||||
|
float bot_clip[4];
|
||||||
|
float top_clip[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void setup_cull_info(cull_info_t * i)
|
||||||
{
|
{
|
||||||
return sqrt(sqr(x2-x1) + sqr(y2-y1) + sqr(z2-z1));
|
// First, just read out the current OpenGL matrices...do this once at setup because it's not the fastest thing to do.
|
||||||
|
glGetFloatv(GL_MODELVIEW_MATRIX ,i->model_view);
|
||||||
|
glGetFloatv(GL_PROJECTION_MATRIX,i->proj);
|
||||||
|
|
||||||
|
// Now...what the heck is this? Here's the deal: the clip planes have values in "clip" coordinates of: Left = (1,0,0,1)
|
||||||
|
// Right = (-1,0,0,1), Bottom = (0,1,0,1), etc. (Clip coordinates are coordinates from -1 to 1 in XYZ that the driver
|
||||||
|
// uses. The projection matrix converts from eye to clip coordinates.)
|
||||||
|
//
|
||||||
|
// How do we convert a plane backward from clip to eye coordinates? Well, we need the transpose of the inverse of the
|
||||||
|
// inverse of the projection matrix. (Transpose of the inverse is needed to transform a plane, and the inverse of the
|
||||||
|
// projection is the matrix that goes clip -> eye.) Well, that cancels out to the transpose of the projection matrix,
|
||||||
|
// which is nice because it means we don't need a matrix inversion in this bit of sample code.
|
||||||
|
|
||||||
|
// So this nightmare down here is simply:
|
||||||
|
// clip plane * transpose (proj_matrix)
|
||||||
|
// worked out for all six clip planes. If you squint you can see the patterns:
|
||||||
|
// L: 1 0 0 1
|
||||||
|
// R: -1 0 0 1
|
||||||
|
// B: 0 1 0 1
|
||||||
|
// T: 0 -1 0 1
|
||||||
|
// etc.
|
||||||
|
|
||||||
|
i->lft_clip[0] = i->proj[0]+i->proj[3]; i->lft_clip[1] = i->proj[4]+i->proj[7]; i->lft_clip[2] = i->proj[8]+i->proj[11]; i->lft_clip[3] = i->proj[12]+i->proj[15];
|
||||||
|
i->rgt_clip[0] =-i->proj[0]+i->proj[3]; i->rgt_clip[1] =-i->proj[4]+i->proj[7]; i->rgt_clip[2] =-i->proj[8]+i->proj[11]; i->rgt_clip[3] =-i->proj[12]+i->proj[15];
|
||||||
|
|
||||||
|
i->bot_clip[0] = i->proj[1]+i->proj[3]; i->bot_clip[1] = i->proj[5]+i->proj[7]; i->bot_clip[2] = i->proj[9]+i->proj[11]; i->bot_clip[3] = i->proj[13]+i->proj[15];
|
||||||
|
i->top_clip[0] =-i->proj[1]+i->proj[3]; i->top_clip[1] =-i->proj[5]+i->proj[7]; i->top_clip[2] =-i->proj[9]+i->proj[11]; i->top_clip[3] =-i->proj[13]+i->proj[15];
|
||||||
|
|
||||||
|
i->nea_clip[0] = i->proj[2]+i->proj[3]; i->nea_clip[1] = i->proj[6]+i->proj[7]; i->nea_clip[2] = i->proj[10]+i->proj[11]; i->nea_clip[3] = i->proj[14]+i->proj[15];
|
||||||
|
i->far_clip[0] =-i->proj[2]+i->proj[3]; i->far_clip[1] =-i->proj[6]+i->proj[7]; i->far_clip[2] =-i->proj[10]+i->proj[11]; i->far_clip[3] =-i->proj[14]+i->proj[15];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sphere_is_visible(const cull_info_t * i, float x, float y, float z, float r)
|
||||||
static inline double CalcAngle(double dy, double dx)
|
|
||||||
{
|
{
|
||||||
double angle;
|
// First: we transform our coordinate into eye coordinates from model-view.
|
||||||
if (dx == 0.0)
|
float xp = x * i->model_view[0] + y * i->model_view[4] + z * i->model_view[ 8] + i->model_view[12];
|
||||||
angle = (dy > 0.0) ? 0.0 : 180.0;
|
float yp = x * i->model_view[1] + y * i->model_view[5] + z * i->model_view[ 9] + i->model_view[13];
|
||||||
else
|
float zp = x * i->model_view[2] + y * i->model_view[6] + z * i->model_view[10] + i->model_view[14];
|
||||||
angle = 90.0 - (atan(dy/dx) * 180.0 / 3.14159265);
|
|
||||||
if (dx < 0.0)
|
// Now - we apply the "plane equation" of each clip plane to see how far from the clip plane our point is.
|
||||||
angle += 180.0;
|
// The clip planes are directed: positive number distances mean we are INSIDE our viewing area by some distance;
|
||||||
return angle;
|
// negative means outside. So ... if we are outside by less than -r, the ENTIRE sphere is out of bounds.
|
||||||
|
// We are not visible! We do the near clip plane, then sides, then far, in an attempt to try the planes
|
||||||
|
// that will eliminate the most geometry first...half the world is behind the near clip plane, but not much is
|
||||||
|
// behind the far clip plane on sunny day.
|
||||||
|
if ((xp * i->nea_clip[0] + yp * i->nea_clip[1] + zp * i->nea_clip[2] + i->nea_clip[3] + r) < 0) return false;
|
||||||
|
if ((xp * i->bot_clip[0] + yp * i->bot_clip[1] + zp * i->bot_clip[2] + i->bot_clip[3] + r) < 0) return false;
|
||||||
|
if ((xp * i->top_clip[0] + yp * i->top_clip[1] + zp * i->top_clip[2] + i->top_clip[3] + r) < 0) return false;
|
||||||
|
if ((xp * i->lft_clip[0] + yp * i->lft_clip[1] + zp * i->lft_clip[2] + i->lft_clip[3] + r) < 0) return false;
|
||||||
|
if ((xp * i->rgt_clip[0] + yp * i->rgt_clip[1] + zp * i->rgt_clip[2] + i->rgt_clip[3] + r) < 0) return false;
|
||||||
|
if ((xp * i->far_clip[0] + yp * i->far_clip[1] + zp * i->far_clip[2] + i->far_clip[3] + r) < 0) return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double DiffAngle(double a1, double a2)
|
static float sphere_distance_sqr(const cull_info_t * i, float x, float y, float z)
|
||||||
{
|
{
|
||||||
double diff = (a2 - a1);
|
float xp = x * i->model_view[0] + y * i->model_view[4] + z * i->model_view[ 8] + i->model_view[12];
|
||||||
if (diff >= 180.0)
|
float yp = x * i->model_view[1] + y * i->model_view[5] + z * i->model_view[ 9] + i->model_view[13];
|
||||||
diff -= 360.0;
|
float zp = x * i->model_view[2] + y * i->model_view[6] + z * i->model_view[10] + i->model_view[14];
|
||||||
if (diff <= -180.0)
|
return xp*xp+yp*yp+zp*zp;
|
||||||
diff += 360.0;
|
}
|
||||||
return fabs(diff);
|
|
||||||
|
static void convert_to_2d(const cull_info_t * i, const float * vp, float x, float y, float z, float w, float * out_x, float * out_y)
|
||||||
|
{
|
||||||
|
float xe = x * i->model_view[0] + y * i->model_view[4] + z * i->model_view[ 8] + w * i->model_view[12];
|
||||||
|
float ye = x * i->model_view[1] + y * i->model_view[5] + z * i->model_view[ 9] + w * i->model_view[13];
|
||||||
|
float ze = x * i->model_view[2] + y * i->model_view[6] + z * i->model_view[10] + w * i->model_view[14];
|
||||||
|
float we = x * i->model_view[3] + y * i->model_view[7] + z * i->model_view[11] + w * i->model_view[15];
|
||||||
|
|
||||||
|
float xc = xe * i->proj[0] + ye * i->proj[4] + ze * i->proj[ 8] + we * i->proj[12];
|
||||||
|
float yc = xe * i->proj[1] + ye * i->proj[5] + ze * i->proj[ 9] + we * i->proj[13];
|
||||||
|
// float zc = xe * i->proj[2] + ye * i->proj[6] + ze * i->proj[10] + we * i->proj[14];
|
||||||
|
float wc = xe * i->proj[3] + ye * i->proj[7] + ze * i->proj[11] + we * i->proj[15];
|
||||||
|
|
||||||
|
xc /= wc;
|
||||||
|
yc /= wc;
|
||||||
|
// zc /= wc;
|
||||||
|
|
||||||
|
*out_x = vp[0] + (1.0f + xc) * vp[2] / 2.0f;
|
||||||
|
*out_y = vp[1] + (1.0f + yc) * vp[3] / 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,24 +178,15 @@ static int gTotPlanes = 0; // Counters
|
|||||||
static int gACFPlanes = 0; // Number of Austin's planes we drew in full
|
static int gACFPlanes = 0; // Number of Austin's planes we drew in full
|
||||||
static int gNavPlanes = 0; // Number of Austin's planes we drew with lights only
|
static int gNavPlanes = 0; // Number of Austin's planes we drew with lights only
|
||||||
static int gOBJPlanes = 0; // Number of our OBJ planes we drew in full
|
static int gOBJPlanes = 0; // Number of our OBJ planes we drew in full
|
||||||
static int gHackFOVLast = 0;
|
|
||||||
|
|
||||||
static XPLMDataRef gFOVDataRef = NULL; // Current FOV for culling.
|
|
||||||
static XPLMDataRef gVisDataRef = NULL; // Current air visiblity for culling.
|
static XPLMDataRef gVisDataRef = NULL; // Current air visiblity for culling.
|
||||||
static XPLMDataRef gAltitudeRef = NULL; // Current aircraft altitude (for TCAS)
|
static XPLMDataRef gAltitudeRef = NULL; // Current aircraft altitude (for TCAS)
|
||||||
static float gOverRes = 1.0; // Wide-screen support. (May be messed up.)
|
|
||||||
|
|
||||||
|
|
||||||
void XPMPInitDefaultPlaneRenderer(void)
|
void XPMPInitDefaultPlaneRenderer(void)
|
||||||
{
|
{
|
||||||
// SETUP - mostly just fetch datarefs.
|
// SETUP - mostly just fetch datarefs.
|
||||||
int width;
|
|
||||||
XPLMGetScreenSize(&width, NULL);
|
|
||||||
gOverRes = ((double) width) / 1024.0;
|
|
||||||
|
|
||||||
gFOVDataRef = XPLMFindDataRef("sim/graphics/view/field_of_view_deg");
|
|
||||||
if (gFOVDataRef == NULL)
|
|
||||||
XPLMDebugString("WARNING: Default renderer could not find FOV data in the sim.\n");
|
|
||||||
gVisDataRef = XPLMFindDataRef("sim/graphics/view/visibility_effective_m");
|
gVisDataRef = XPLMFindDataRef("sim/graphics/view/visibility_effective_m");
|
||||||
if (gVisDataRef == NULL) gVisDataRef = XPLMFindDataRef("sim/weather/visibility_effective_m");
|
if (gVisDataRef == NULL) gVisDataRef = XPLMFindDataRef("sim/weather/visibility_effective_m");
|
||||||
if (gVisDataRef == NULL)
|
if (gVisDataRef == NULL)
|
||||||
@@ -145,9 +207,6 @@ void XPMPInitDefaultPlaneRenderer(void)
|
|||||||
XPLMRegisterDataAccessor("hack/renderer/acfs", xplmType_Int, 0, GetRendererStat, NULL,
|
XPLMRegisterDataAccessor("hack/renderer/acfs", xplmType_Int, 0, GetRendererStat, NULL,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
&gACFPlanes, NULL);
|
&gACFPlanes, NULL);
|
||||||
XPLMRegisterDataAccessor("hack/renderer/fov", xplmType_Int, 0, GetRendererStat, NULL,
|
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
&gHackFOVLast, NULL);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We don't know how many multiplayer planes there are - fetch as many as we can.
|
// We don't know how many multiplayer planes there are - fetch as many as we can.
|
||||||
@@ -191,6 +250,8 @@ struct PlaneToRender_t {
|
|||||||
XPLMPlaneDrawState_t state; // Flaps, gear, etc.
|
XPLMPlaneDrawState_t state; // Flaps, gear, etc.
|
||||||
float dist;
|
float dist;
|
||||||
xpmp_LightStatus lights; // lights status
|
xpmp_LightStatus lights; // lights status
|
||||||
|
string label;
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef std::map<float, PlaneToRender_t> RenderMap;
|
typedef std::map<float, PlaneToRender_t> RenderMap;
|
||||||
|
|
||||||
@@ -213,30 +274,18 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gFOVDataRef == NULL) // No FOV - we're probably totally screwed up.
|
cull_info_t gl_camera;
|
||||||
return;
|
setup_cull_info(&gl_camera);
|
||||||
|
XPLMCameraPosition_t x_camera;
|
||||||
|
|
||||||
|
XPLMReadCameraPosition(&x_camera); // only for zoom!
|
||||||
|
|
||||||
// Culling - read the camera pos«and figure out what's visible.
|
// Culling - read the camera pos«and figure out what's visible.
|
||||||
|
|
||||||
XPLMCameraPosition_t cameraPos;
|
double maxDist = XPLMGetDataf(gVisDataRef);
|
||||||
double fov;
|
double labelDist = min(maxDist, MAX_LABEL_DIST) * x_camera.zoom; // Labels get easier to see when users zooms.
|
||||||
|
double fullPlaneDist = x_camera.zoom * (5280.0 / 3.2) * (gFloatPrefsFunc ? gFloatPrefsFunc("planes","full_distance", 3.0) : 3.0); // Only draw planes fully within 3 miles.
|
||||||
XPLMReadCameraPosition(&cameraPos);
|
int maxFullPlanes = gIntPrefsFunc ? gIntPrefsFunc("planes","max_full_count", 100) : 100; // Draw no more than 100 full planes!
|
||||||
fov = XPLMGetDataf(gFOVDataRef);
|
|
||||||
double maxDist = XPLMGetDataf(gVisDataRef);
|
|
||||||
|
|
||||||
double kFullPlaneDist = gOverRes * (5280.0 / 3.2) * (gFloatPrefsFunc ? gFloatPrefsFunc("planes","full_distance", 3.0) : 3.0); // Only draw planes fully within 3 miles.
|
|
||||||
int kMaxFullPlanes = gIntPrefsFunc ? gIntPrefsFunc("planes","max_full_count", 100) : 100; // Draw no more than 100 full planes!
|
|
||||||
|
|
||||||
// Field of view modification. We don't yet handle camera roll because I'm too stupid
|
|
||||||
// to do the math. (I took linear algebra but came out of the course knowing less than
|
|
||||||
// when I went in. So instead we...assume that our field of view is vertical, apply
|
|
||||||
// a 5:3 aspect ratio to widen it and a 10% fudge factor to account for airplanes
|
|
||||||
// not being point objects. The 5:3 is based on allowing for the worst case, that
|
|
||||||
// we're rolled to make a perfect diagonal making our monitor as wide as possible.d
|
|
||||||
// We divide by camera zoom so that when we're zoomed in we're not taking people
|
|
||||||
// that have been zoomed out of our peripheral vision.
|
|
||||||
fov = fov * 5.0 / 4.0 / cameraPos.zoom;
|
|
||||||
|
|
||||||
gTotPlanes = planeCount;
|
gTotPlanes = planeCount;
|
||||||
gNavPlanes = gACFPlanes = gOBJPlanes = 0;
|
gNavPlanes = gACFPlanes = gOBJPlanes = 0;
|
||||||
@@ -245,7 +294,7 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
XPLMCountAircraft(&modelCount, &active, &plugin);
|
XPLMCountAircraft(&modelCount, &active, &plugin);
|
||||||
tcas = modelCount - 1; // This is how many tcas blips we can have!
|
tcas = modelCount - 1; // This is how many tcas blips we can have!
|
||||||
|
|
||||||
RenderMap myPlanes;
|
RenderMap myPlanes; // Planes - sorted by distance so we can do the closest N and bail
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* CULLING AND STATE CALCULATION LOOP
|
* CULLING AND STATE CALCULATION LOOP
|
||||||
@@ -274,6 +323,7 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
|
|
||||||
XPMPPlanePosition_t pos;
|
XPMPPlanePosition_t pos;
|
||||||
pos.size = sizeof(pos);
|
pos.size = sizeof(pos);
|
||||||
|
pos.label[0] = 0;
|
||||||
|
|
||||||
if (XPMPGetPlaneData(id, xpmpDataType_Position, &pos) != xpmpData_Unavailable)
|
if (XPMPGetPlaneData(id, xpmpDataType_Position, &pos) != xpmpData_Unavailable)
|
||||||
{
|
{
|
||||||
@@ -282,9 +332,7 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
double x,y,z;
|
double x,y,z;
|
||||||
XPLMWorldToLocal(pos.lat, pos.lon, pos.elevation * kFtToMeters, &x, &y, &z);
|
XPLMWorldToLocal(pos.lat, pos.lon, pos.elevation * kFtToMeters, &x, &y, &z);
|
||||||
|
|
||||||
double distMeters = CalcDist3D(x,y,z,cameraPos.x, cameraPos.y, cameraPos.z);
|
float distMeters = sqrt(sphere_distance_sqr(&gl_camera,x,y,z));
|
||||||
if (cameraPos.zoom != 0.0)
|
|
||||||
distMeters /= cameraPos.zoom; // If we're 2x zoomed, pretend the AC is half as far away.
|
|
||||||
|
|
||||||
// If the plane is farther than our TCAS range, it's just not visible. Drop it!
|
// If the plane is farther than our TCAS range, it's just not visible. Drop it!
|
||||||
if (distMeters > kMaxDistTCAS)
|
if (distMeters > kMaxDistTCAS)
|
||||||
@@ -310,36 +358,11 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
// Calculate the angles between the camera angles and the real angles.
|
// Calculate the angles between the camera angles and the real angles.
|
||||||
// Cull if we exceed half the FOV.
|
// Cull if we exceed half the FOV.
|
||||||
|
|
||||||
double headingToTarget = CalcAngle(cameraPos.z - z, x - cameraPos.x);
|
if(!cull && !sphere_is_visible(&gl_camera, x, y, z, 50.0))
|
||||||
double pitchToTarget = CalcAngle(sqrt(sqr(x - cameraPos.x) + sqr(cameraPos.z - z)), y - cameraPos.y);
|
|
||||||
|
|
||||||
double headOff = DiffAngle(headingToTarget, cameraPos.heading);
|
|
||||||
double pitchOff = DiffAngle(pitchToTarget,cameraPos.pitch);
|
|
||||||
|
|
||||||
#if DEBUG_RENDERER
|
|
||||||
char cullBuf[1024];
|
|
||||||
sprintf(cullBuf, "Target Pos = %f,%f,%f, Camera Pos = %f,%f,%f.\n",
|
|
||||||
x,y,z,cameraPos.x,cameraPos.y,cameraPos.z);
|
|
||||||
XPLMDebugString(cullBuf);
|
|
||||||
sprintf(cullBuf, "Camera p=%f,h=%f, object p=%f,h=%f,diff p=%f,h=%f.\n",
|
|
||||||
cameraPos.pitch, cameraPos.heading, pitchToTarget, headingToTarget, pitchOff, headOff);
|
|
||||||
XPLMDebugString(cullBuf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
float fov_fudged = fov + atan(200.0 / distMeters) * 180.0 / 3.141592565;
|
|
||||||
#if RENDERER_STATS
|
|
||||||
gHackFOVLast = fov_fudged;
|
|
||||||
#endif
|
|
||||||
// View frustum check - if we're off screen, we don't draw. But remember us - we may be visible on TCAS.
|
|
||||||
if ((headOff > (fov_fudged / 2.0)) ||
|
|
||||||
(pitchOff > (fov_fudged / 2.0)))
|
|
||||||
{
|
|
||||||
cull = true;
|
cull = true;
|
||||||
}
|
|
||||||
|
|
||||||
// Full plane or lites based on distance.
|
// Full plane or lites based on distance.
|
||||||
bool drawFullPlane = (distMeters < kFullPlaneDist);
|
bool drawFullPlane = (distMeters < fullPlaneDist);
|
||||||
|
|
||||||
#if DEBUG_RENDERER
|
#if DEBUG_RENDERER
|
||||||
|
|
||||||
@@ -378,9 +401,9 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
renderRecord.state.slatRatio = surfaces.slatRatio ;
|
renderRecord.state.slatRatio = surfaces.slatRatio ;
|
||||||
renderRecord.state.wingSweep = surfaces.wingSweep ;
|
renderRecord.state.wingSweep = surfaces.wingSweep ;
|
||||||
renderRecord.state.thrust = surfaces.thrust ;
|
renderRecord.state.thrust = surfaces.thrust ;
|
||||||
renderRecord.state.yolkPitch = surfaces.yolkPitch ;
|
renderRecord.state.yokePitch = surfaces.yokePitch ;
|
||||||
renderRecord.state.yolkHeading = surfaces.yolkHeading ;
|
renderRecord.state.yokeHeading = surfaces.yokeHeading ;
|
||||||
renderRecord.state.yolkRoll = surfaces.yolkRoll ;
|
renderRecord.state.yokeRoll = surfaces.yokeRoll ;
|
||||||
|
|
||||||
renderRecord.lights.lightFlags = surfaces.lights.lightFlags;
|
renderRecord.lights.lightFlags = surfaces.lights.lightFlags;
|
||||||
|
|
||||||
@@ -390,9 +413,9 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
renderRecord.state.flapRatio = (pos.elevation < 70) ? 1.0 : 0.0;
|
renderRecord.state.flapRatio = (pos.elevation < 70) ? 1.0 : 0.0;
|
||||||
renderRecord.state.spoilerRatio = renderRecord.state.speedBrakeRatio = renderRecord.state.slatRatio = renderRecord.state.wingSweep = 0.0;
|
renderRecord.state.spoilerRatio = renderRecord.state.speedBrakeRatio = renderRecord.state.slatRatio = renderRecord.state.wingSweep = 0.0;
|
||||||
renderRecord.state.thrust = (pos.pitch > 30) ? 1.0 : 0.6;
|
renderRecord.state.thrust = (pos.pitch > 30) ? 1.0 : 0.6;
|
||||||
renderRecord.state.yolkPitch = pos.pitch / 90.0;
|
renderRecord.state.yokePitch = pos.pitch / 90.0;
|
||||||
renderRecord.state.yolkHeading = pos.heading / 180.0;
|
renderRecord.state.yokeHeading = pos.heading / 180.0;
|
||||||
renderRecord.state.yolkRoll = pos.roll / 90.0;
|
renderRecord.state.yokeRoll = pos.roll / 90.0;
|
||||||
|
|
||||||
// use some smart defaults
|
// use some smart defaults
|
||||||
renderRecord.lights.bcnLights = 1;
|
renderRecord.lights.bcnLights = 1;
|
||||||
@@ -403,6 +426,7 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
renderRecord.state.gearPosition = 1.0;
|
renderRecord.state.gearPosition = 1.0;
|
||||||
renderRecord.full = drawFullPlane;
|
renderRecord.full = drawFullPlane;
|
||||||
renderRecord.dist = distMeters;
|
renderRecord.dist = distMeters;
|
||||||
|
renderRecord.label = pos.label;
|
||||||
|
|
||||||
myPlanes.insert(RenderMap::value_type(distMeters, renderRecord));
|
myPlanes.insert(RenderMap::value_type(distMeters, renderRecord));
|
||||||
|
|
||||||
@@ -444,7 +468,7 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
{
|
{
|
||||||
// Max plane enforcement - once we run out of the max number of full planes the
|
// Max plane enforcement - once we run out of the max number of full planes the
|
||||||
// user allows, force only lites for framerate
|
// user allows, force only lites for framerate
|
||||||
if (gACFPlanes >= kMaxFullPlanes)
|
if (gACFPlanes >= maxFullPlanes)
|
||||||
iter->second.full = false;
|
iter->second.full = false;
|
||||||
|
|
||||||
#if DEBUG_RENDERER
|
#if DEBUG_RENDERER
|
||||||
@@ -567,6 +591,46 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PASS 4 - Labels
|
||||||
|
if ( gDrawLabels )
|
||||||
|
{
|
||||||
|
GLfloat vp[4];
|
||||||
|
glGetFloatv(GL_VIEWPORT,vp);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0, vp[2], 0, vp[3], -1, 1);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
float c[4] = { 1, 1, 0, 1 };
|
||||||
|
|
||||||
|
|
||||||
|
for (RenderMap::iterator iter = myPlanes.begin(); iter != myPlanes.end(); ++iter)
|
||||||
|
if(iter->first < labelDist)
|
||||||
|
if(!iter->second.cull) // IMPORTANT - airplane BEHIND us still maps XY onto screen...so we get 180 degree reflections. But behind us acf are culled, so that's good.
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
convert_to_2d(&gl_camera, vp, iter->second.x, iter->second.y, iter->second.z, 1.0, &x, &y);
|
||||||
|
|
||||||
|
float rat = 1.0 - (iter->first / labelDist);
|
||||||
|
c[0] = c[1] = 0.5 + 0.5 * rat;
|
||||||
|
c[2] = 0.5 - 0.5 * rat; // gray -> yellow - no alpha in the SDK - foo!
|
||||||
|
|
||||||
|
XPLMDrawString(c, x, y+10, (char *) iter->second.label.c_str(), NULL, xplmFont_Basic);
|
||||||
|
}
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPopMatrix();
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Final hack - leave a note to ourselves for how many of Austin's planes we relocated to do TCAS.
|
// Final hack - leave a note to ourselves for how many of Austin's planes we relocated to do TCAS.
|
||||||
if (tcas > renderedCounter)
|
if (tcas > renderedCounter)
|
||||||
tcas = renderedCounter;
|
tcas = renderedCounter;
|
||||||
@@ -574,3 +638,19 @@ void XPMPDefaultPlaneRenderer(void)
|
|||||||
|
|
||||||
gDumpOneRenderCycle = 0;
|
gDumpOneRenderCycle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XPMPEnableAircraftLabels()
|
||||||
|
{
|
||||||
|
gDrawLabels = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XPMPDisableAircraftLabels()
|
||||||
|
{
|
||||||
|
gDrawLabels = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XPMPDrawingAircraftLabels()
|
||||||
|
{
|
||||||
|
return gDrawLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "XObjDefs.h"
|
#include "XObjDefs.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -30,6 +29,7 @@
|
|||||||
//#include <time.h>
|
//#include <time.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#if !defined(XUTILS_EXCLUDE_MAC_CRAP) && defined(__MACH__)
|
#if !defined(XUTILS_EXCLUDE_MAC_CRAP) && defined(__MACH__)
|
||||||
#define XUTILS_EXCLUDE_MAC_CRAP 1
|
#define XUTILS_EXCLUDE_MAC_CRAP 1
|
||||||
|
|||||||
Reference in New Issue
Block a user