Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b129b289c | ||
|
|
a89ceb96b9 | ||
|
|
9af5f9f094 | ||
|
|
6776c2e536 | ||
|
|
4c3b4219fe | ||
|
|
a09806bb98 | ||
|
|
e175c8cc4d | ||
|
|
a53faf4565 | ||
|
|
dc653ac46c | ||
|
|
c544777d37 | ||
|
|
93a37df90a | ||
|
|
1da02cca4c | ||
|
|
4b1d777ad4 | ||
|
|
fb0916be0f | ||
|
|
806083cb25 | ||
|
|
5ba74e30b8 | ||
|
|
c39e08cb2a | ||
|
|
e4653be9a1 | ||
|
|
cd5765be1e | ||
|
|
c481b06451 | ||
|
|
91ba4618e7 | ||
|
|
fdc5521389 | ||
|
|
e88c915206 | ||
|
|
1e60698053 | ||
|
|
5702bd7ee8 | ||
|
|
8eef3eb582 | ||
|
|
31db353173 | ||
|
|
2c4a0dd998 | ||
|
|
7d7e41dacc | ||
|
|
453a53b372 | ||
|
|
ef68d18f64 | ||
|
|
ded1d2343f | ||
|
|
e6241a2f73 | ||
|
|
467254ec66 | ||
|
|
135e137921 | ||
|
|
e13a5b57d4 | ||
|
|
f1c00cdd18 | ||
|
|
8c3de351b0 |
@@ -1,3 +1,24 @@
|
||||
New in 0.0.14
|
||||
* Added a module to manage waypoints and routes, calculate bearing and
|
||||
distance to next waypoint, lateral distance off route, etc.
|
||||
* Moved some of the basic time management code over from flightgear.
|
||||
* Bucket dimensions can be returned in meters
|
||||
* Added SOCK_STREAM (TCP) socket support to the networking code.
|
||||
* Updated random number generator interface so application can provide
|
||||
it's own seed value as well as use the default time seed.
|
||||
* Added a routine to calculate the distance between a point and a line segment.
|
||||
* Updates to the property manager and the property list loader/saver.
|
||||
* Added an explanation of the rational behind our terrain texture coordinate
|
||||
generation code.
|
||||
* Fixed sky dome so that the color at the horizon will always match
|
||||
the specified fog color.
|
||||
* Did a fair amount of fg -> sg name space updating (lots left to do.)
|
||||
* December 14, 2000
|
||||
* Added support for KAI C++ on linux.
|
||||
* MSVC tweaks.
|
||||
* MacOS tweaks.
|
||||
* FreeBSD tweaks.
|
||||
|
||||
New in 0.0.13
|
||||
* September 14, 2000
|
||||
* Added support for reading and writing xml files (easyxml)
|
||||
|
||||
@@ -392,3 +392,24 @@ if test "$have_timezone" = no; then
|
||||
AC_MSG_RESULT(no))
|
||||
fi
|
||||
])dnl
|
||||
|
||||
## AC_BZ_SET_COMPILER: Addition by Theodore Papadopoulo
|
||||
## Patch by Jim McKelvey: change sed -e 's/ /@/g' to sed -e 's/ /@/'
|
||||
AC_DEFUN(AC_SG_SET_COMPILER,
|
||||
[cxxwith=`echo $1 | sed -e 's/ /@/'`
|
||||
case "$cxxwith" in
|
||||
*:*@*) # Full initialization syntax
|
||||
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)@.*/\1/p'`
|
||||
CXXFLAGS=`echo "$cxxwith" | sed -n -e 's/.*:.*@\(.*\)/\1/p'`
|
||||
;;
|
||||
*:*) # Simple initialization syntax
|
||||
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)/\1/p'`
|
||||
CXXFLAGS=$3
|
||||
;;
|
||||
*) # Default values
|
||||
CXX=$2
|
||||
CXXFLAGS=$3
|
||||
CC="$2 --c"
|
||||
## CFLAGS=
|
||||
;;
|
||||
esac])
|
||||
|
||||
+20
-1
@@ -6,7 +6,24 @@ dnl $Id$
|
||||
AC_INIT(simgear/bucket/newbucket.cxx)
|
||||
|
||||
dnl Initialize the automake stuff
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.0.13)
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.0.14)
|
||||
|
||||
dnl Specify KAI C++ compiler and flags.
|
||||
dnl Borrowed with slight modification from blitz distribution.
|
||||
AC_ARG_WITH(cxx,
|
||||
[ --with-cxx=COMPILER[:name-flags] set options for COMPILER (KCC)],
|
||||
[case "$withval" in
|
||||
KCC*) # KAI C++ http://www.kai.com/
|
||||
echo "Configuring for KAI C++"
|
||||
AC_SG_SET_COMPILER($withval,"KCC","--restrict --strict_warnings")
|
||||
CXX_OPTIMIZE_FLAGS=="+K3 -O3"
|
||||
CXX_DEBUG_FLAGS="-g +K0"
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
echo CXX = $CXX
|
||||
echo CC = $CC
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_MAKE_SET
|
||||
@@ -251,12 +268,14 @@ AC_OUTPUT( \
|
||||
simgear/Makefile \
|
||||
simgear/version.h \
|
||||
simgear/bucket/Makefile \
|
||||
simgear/camera/Makefile \
|
||||
simgear/debug/Makefile \
|
||||
simgear/ephemeris/Makefile \
|
||||
simgear/io/Makefile \
|
||||
simgear/magvar/Makefile \
|
||||
simgear/math/Makefile \
|
||||
simgear/misc/Makefile \
|
||||
simgear/route/Makefile \
|
||||
simgear/screen/Makefile \
|
||||
simgear/serial/Makefile \
|
||||
simgear/sky/Makefile \
|
||||
|
||||
@@ -33,6 +33,7 @@ SUBDIRS = \
|
||||
math \
|
||||
$(METAR_DIRS) \
|
||||
misc \
|
||||
route \
|
||||
screen \
|
||||
$(SERIAL_DIRS) \
|
||||
sky \
|
||||
|
||||
@@ -14,4 +14,4 @@ libsgbucket_a_SOURCES = newbucket.cxx
|
||||
# $(top_builddir)/bucket/libsgbucket.a \
|
||||
# $(top_builddir)/misc/libsgmisc.a
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
+152
-12
@@ -36,8 +36,109 @@
|
||||
#include "newbucket.hxx"
|
||||
|
||||
|
||||
// default constructor
|
||||
SGBucket::SGBucket() {
|
||||
}
|
||||
|
||||
|
||||
// constructor for specified location
|
||||
SGBucket::SGBucket(const double dlon, const double dlat) {
|
||||
set_bucket(dlon, dlat);
|
||||
}
|
||||
|
||||
|
||||
// create an impossible bucket if false
|
||||
SGBucket::SGBucket(const bool is_good) {
|
||||
set_bucket(0.0, 0.0);
|
||||
if ( !is_good ) {
|
||||
lon = -1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse a unique scenery tile index and find the lon, lat, x, and y
|
||||
SGBucket::SGBucket(const long int bindex) {
|
||||
long int index = bindex;
|
||||
|
||||
lon = index >> 14;
|
||||
index -= lon << 14;
|
||||
lon -= 180;
|
||||
|
||||
lat = index >> 6;
|
||||
index -= lat << 6;
|
||||
lat -= 90;
|
||||
|
||||
y = index >> 3;
|
||||
index -= y << 3;
|
||||
|
||||
x = index;
|
||||
}
|
||||
|
||||
|
||||
// default destructor
|
||||
SGBucket::~SGBucket() {
|
||||
}
|
||||
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
void SGBucket::set_bucket( double *lonlat ) {
|
||||
set_bucket( lonlat[0], lonlat[1] );
|
||||
}
|
||||
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
void SGBucket::set_bucket( double dlon, double dlat ) {
|
||||
//
|
||||
// latitude first
|
||||
//
|
||||
double span = sg_bucket_span( dlat );
|
||||
double diff = dlon - (double)(int)dlon;
|
||||
|
||||
// cout << "diff = " << diff << " span = " << span << endl;
|
||||
|
||||
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lon = (int)dlon;
|
||||
} else {
|
||||
lon = (int)dlon - 1;
|
||||
}
|
||||
|
||||
// find subdivision or super lon if needed
|
||||
if ( span < FG_EPSILON ) {
|
||||
// polar cap
|
||||
lon = 0;
|
||||
x = 0;
|
||||
} else if ( span <= 1.0 ) {
|
||||
x = (int)((dlon - lon) / span);
|
||||
} else {
|
||||
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lon = (int)( (int)(lon / span) * span);
|
||||
} else {
|
||||
// cout << " lon = " << lon
|
||||
// << " tmp = " << (int)((lon-1) / span) << endl;
|
||||
lon = (int)( (int)((lon + 1) / span) * span - span);
|
||||
if ( lon < -180 ) {
|
||||
lon = -180;
|
||||
}
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// then latitude
|
||||
//
|
||||
diff = dlat - (double)(int)dlat;
|
||||
|
||||
if ( (dlat >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lat = (int)dlat;
|
||||
} else {
|
||||
lat = (int)dlat - 1;
|
||||
}
|
||||
y = (int)((dlat - lat) * 8);
|
||||
}
|
||||
|
||||
|
||||
// Build the path name for this bucket
|
||||
string FGBucket::gen_base_path() const {
|
||||
string SGBucket::gen_base_path() const {
|
||||
// long int index;
|
||||
int top_lon, top_lat, main_lon, main_lat;
|
||||
char hem, pole;
|
||||
@@ -85,19 +186,58 @@ string FGBucket::gen_base_path() const {
|
||||
}
|
||||
|
||||
|
||||
// return width of the tile in degrees
|
||||
double SGBucket::get_width() const {
|
||||
return sg_bucket_span( get_center_lat() );
|
||||
}
|
||||
|
||||
|
||||
// return height of the tile in degrees
|
||||
double SGBucket::get_height() const {
|
||||
return SG_BUCKET_SPAN;
|
||||
}
|
||||
|
||||
|
||||
// return width of the tile in meters
|
||||
double SGBucket::get_width_m() const {
|
||||
double clat = (int)get_center_lat();
|
||||
if ( clat > 0 ) {
|
||||
clat = (int)clat + 0.5;
|
||||
} else {
|
||||
clat = (int)clat - 0.5;
|
||||
}
|
||||
double clat_rad = clat * DEG_TO_RAD;
|
||||
double cos_lat = cos( clat_rad );
|
||||
double local_radius = cos_lat * EQUATORIAL_RADIUS_M;
|
||||
double local_perimeter = 2.0 * local_radius * FG_PI;
|
||||
double degree_width = local_perimeter / 360.0;
|
||||
|
||||
return sg_bucket_span( get_center_lat() ) * degree_width;
|
||||
}
|
||||
|
||||
|
||||
// return height of the tile in meters
|
||||
double SGBucket::get_height_m() const {
|
||||
double perimeter = 2.0 * EQUATORIAL_RADIUS_M * FG_PI;
|
||||
double degree_height = perimeter / 360.0;
|
||||
|
||||
return SG_BUCKET_SPAN * degree_height;
|
||||
}
|
||||
|
||||
|
||||
// find the bucket which is offset by the specified tile units in the
|
||||
// X & Y direction. We need the current lon and lat to resolve
|
||||
// ambiguities when going from a wider tile to a narrower one above or
|
||||
// below. This assumes that we are feeding in
|
||||
FGBucket fgBucketOffset( double dlon, double dlat, int dx, int dy ) {
|
||||
FGBucket result( dlon, dlat );
|
||||
double clat = result.get_center_lat() + dy * FG_BUCKET_SPAN;
|
||||
SGBucket sgBucketOffset( double dlon, double dlat, int dx, int dy ) {
|
||||
SGBucket result( dlon, dlat );
|
||||
double clat = result.get_center_lat() + dy * SG_BUCKET_SPAN;
|
||||
|
||||
// walk dy units in the lat direction
|
||||
result.set_bucket( dlon, clat );
|
||||
|
||||
// find the lon span for the new latitude
|
||||
double span = bucket_span( clat );
|
||||
double span = sg_bucket_span( clat );
|
||||
|
||||
// walk dx units in the lon direction
|
||||
double tmp = dlon + dx * span;
|
||||
@@ -114,7 +254,7 @@ FGBucket fgBucketOffset( double dlon, double dlat, int dx, int dy ) {
|
||||
|
||||
|
||||
// calculate the offset between two buckets
|
||||
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
|
||||
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ) {
|
||||
|
||||
// Latitude difference
|
||||
double c1_lat = b1.get_center_lat();
|
||||
@@ -122,12 +262,12 @@ void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
|
||||
double diff_lat = c2_lat - c1_lat;
|
||||
|
||||
#ifdef HAVE_RINT
|
||||
*dy = (int)rint( diff_lat / FG_BUCKET_SPAN );
|
||||
*dy = (int)rint( diff_lat / SG_BUCKET_SPAN );
|
||||
#else
|
||||
if ( diff_lat > 0 ) {
|
||||
*dy = (int)( diff_lat / FG_BUCKET_SPAN + 0.5 );
|
||||
*dy = (int)( diff_lat / SG_BUCKET_SPAN + 0.5 );
|
||||
} else {
|
||||
*dy = (int)( diff_lat / FG_BUCKET_SPAN - 0.5 );
|
||||
*dy = (int)( diff_lat / SG_BUCKET_SPAN - 0.5 );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -136,10 +276,10 @@ void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
|
||||
double c2_lon = b2.get_center_lon();
|
||||
double diff_lon = c2_lon - c1_lon;
|
||||
double span;
|
||||
if ( bucket_span(c1_lat) <= bucket_span(c2_lat) ) {
|
||||
span = bucket_span(c1_lat);
|
||||
if ( sg_bucket_span(c1_lat) <= sg_bucket_span(c2_lat) ) {
|
||||
span = sg_bucket_span(c1_lat);
|
||||
} else {
|
||||
span = bucket_span(c2_lat);
|
||||
span = sg_bucket_span(c2_lat);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RINT
|
||||
|
||||
+99
-215
@@ -44,7 +44,8 @@
|
||||
// already depending on how you defined FG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
#ifdef __MWERKS__
|
||||
# include <math.h> // needed fabs()
|
||||
FG_USING_STD(sprintf);
|
||||
FG_USING_STD(fabs);
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
@@ -57,79 +58,16 @@ FG_USING_STD(ostream);
|
||||
|
||||
|
||||
|
||||
#define FG_BUCKET_SPAN 0.125 // 1/8 of a degree
|
||||
#define FG_HALF_BUCKET_SPAN 0.0625 // 1/2 of 1/8 of a degree = 1/16 = 0.0625
|
||||
#define SG_BUCKET_SPAN 0.125 // 1/8 of a degree
|
||||
#define SG_HALF_BUCKET_SPAN 0.0625 // 1/2 of 1/8 of a degree = 1/16 = 0.0625
|
||||
|
||||
class FGBucket;
|
||||
ostream& operator<< ( ostream&, const FGBucket& );
|
||||
bool operator== ( const FGBucket&, const FGBucket& );
|
||||
|
||||
class FGBucket {
|
||||
|
||||
private:
|
||||
double cx, cy; // centerpoint (lon, lat) in degrees of bucket
|
||||
int lon; // longitude index (-180 to 179)
|
||||
int lat; // latitude index (-90 to 89)
|
||||
int x; // x subdivision (0 to 7)
|
||||
int y; // y subdivision (0 to 7)
|
||||
|
||||
public:
|
||||
|
||||
// default constructor
|
||||
FGBucket();
|
||||
|
||||
// create a bucket which would contain the specified lon/lat
|
||||
FGBucket(const double lon, const double lat);
|
||||
|
||||
// create a bucket based on "long int" index
|
||||
FGBucket(const long int bindex);
|
||||
|
||||
// create an impossible bucket if false
|
||||
FGBucket(const bool is_good);
|
||||
|
||||
~FGBucket();
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
void set_bucket( double dlon, double dlat );
|
||||
void set_bucket( double *lonlat ) {
|
||||
set_bucket( lonlat[0], lonlat[1] );
|
||||
}
|
||||
|
||||
void make_bad ( void );
|
||||
|
||||
// Generate the unique scenery tile index for this bucket
|
||||
long int gen_index();
|
||||
string gen_index_str() const;
|
||||
|
||||
// Build the path name for this bucket
|
||||
string gen_base_path() const;
|
||||
|
||||
// return the center lon of a tile
|
||||
double get_center_lon() const;
|
||||
|
||||
// return width of the tile
|
||||
double get_width() const;
|
||||
|
||||
// return the center lat of a tile
|
||||
double get_center_lat() const;
|
||||
|
||||
// return height of the tile
|
||||
double get_height() const;
|
||||
|
||||
// Informational methods
|
||||
inline int get_lon() const { return lon; }
|
||||
inline int get_lat() const { return lat; }
|
||||
inline int get_x() const { return x; }
|
||||
inline int get_y() const { return y; }
|
||||
|
||||
// friends
|
||||
friend ostream& operator<< ( ostream&, const FGBucket& );
|
||||
friend bool operator== ( const FGBucket&, const FGBucket& );
|
||||
};
|
||||
class SGBucket;
|
||||
ostream& operator<< ( ostream&, const SGBucket& );
|
||||
bool operator== ( const SGBucket&, const SGBucket& );
|
||||
|
||||
|
||||
// return the horizontal tile span factor based on latitude
|
||||
inline double bucket_span( double l ) {
|
||||
inline double sg_bucket_span( double l ) {
|
||||
if ( l >= 89.0 ) {
|
||||
return 360.0;
|
||||
} else if ( l >= 88.0 ) {
|
||||
@@ -164,179 +102,125 @@ inline double bucket_span( double l ) {
|
||||
}
|
||||
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
inline void FGBucket::set_bucket( double dlon, double dlat ) {
|
||||
//
|
||||
// latitude first
|
||||
//
|
||||
double span = bucket_span( dlat );
|
||||
double diff = dlon - (double)(int)dlon;
|
||||
class SGBucket {
|
||||
|
||||
// cout << "diff = " << diff << " span = " << span << endl;
|
||||
private:
|
||||
double cx, cy; // centerpoint (lon, lat) in degrees of bucket
|
||||
int lon; // longitude index (-180 to 179)
|
||||
int lat; // latitude index (-90 to 89)
|
||||
int x; // x subdivision (0 to 7)
|
||||
int y; // y subdivision (0 to 7)
|
||||
|
||||
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lon = (int)dlon;
|
||||
} else {
|
||||
lon = (int)dlon - 1;
|
||||
}
|
||||
public:
|
||||
|
||||
// find subdivision or super lon if needed
|
||||
if ( span < FG_EPSILON ) {
|
||||
// polar cap
|
||||
lon = 0;
|
||||
x = 0;
|
||||
} else if ( span <= 1.0 ) {
|
||||
x = (int)((dlon - lon) / span);
|
||||
} else {
|
||||
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lon = (int)( (int)(lon / span) * span);
|
||||
} else {
|
||||
// cout << " lon = " << lon
|
||||
// << " tmp = " << (int)((lon-1) / span) << endl;
|
||||
lon = (int)( (int)((lon + 1) / span) * span - span);
|
||||
if ( lon < -180 ) {
|
||||
lon = -180;
|
||||
}
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
// default constructor
|
||||
SGBucket();
|
||||
|
||||
//
|
||||
// then latitude
|
||||
//
|
||||
diff = dlat - (double)(int)dlat;
|
||||
// constructor for specified location
|
||||
SGBucket(const double dlon, const double dlat);
|
||||
|
||||
if ( (dlat >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lat = (int)dlat;
|
||||
} else {
|
||||
lat = (int)dlat - 1;
|
||||
}
|
||||
y = (int)((dlat - lat) * 8);
|
||||
}
|
||||
// create an impossible bucket if false
|
||||
SGBucket(const bool is_good);
|
||||
|
||||
// Parse a unique scenery tile index and find the lon, lat, x, and y
|
||||
SGBucket(const long int bindex);
|
||||
|
||||
// default constructor
|
||||
inline FGBucket::FGBucket() {}
|
||||
// default destructor
|
||||
~SGBucket();
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
void set_bucket( double dlon, double dlat );
|
||||
void set_bucket( double *lonlat );
|
||||
|
||||
// constructor for specified location
|
||||
inline FGBucket::FGBucket(const double dlon, const double dlat) {
|
||||
set_bucket(dlon, dlat);
|
||||
}
|
||||
|
||||
|
||||
// create an impossible bucket if false
|
||||
inline FGBucket::FGBucket(const bool is_good) {
|
||||
set_bucket(0.0, 0.0);
|
||||
if ( !is_good ) {
|
||||
// create an impossible bucket
|
||||
inline void make_bad( void ) {
|
||||
set_bucket(0.0, 0.0);
|
||||
lon = -1000;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the unique scenery tile index for this bucket
|
||||
//
|
||||
// The index is constructed as follows:
|
||||
//
|
||||
// 9 bits - to represent 360 degrees of longitude (-180 to 179)
|
||||
// 8 bits - to represent 180 degrees of latitude (-90 to 89)
|
||||
//
|
||||
// Each 1 degree by 1 degree tile is further broken down into an 8x8
|
||||
// grid. So we also need:
|
||||
//
|
||||
// 3 bits - to represent x (0 to 7)
|
||||
// 3 bits - to represent y (0 to 7)
|
||||
|
||||
// Parse a unique scenery tile index and find the lon, lat, x, and y
|
||||
inline FGBucket::FGBucket(const long int bindex) {
|
||||
long int index = bindex;
|
||||
|
||||
lon = index >> 14;
|
||||
index -= lon << 14;
|
||||
lon -= 180;
|
||||
|
||||
lat = index >> 6;
|
||||
index -= lat << 6;
|
||||
lat -= 90;
|
||||
|
||||
y = index >> 3;
|
||||
index -= y << 3;
|
||||
|
||||
x = index;
|
||||
}
|
||||
|
||||
|
||||
// default destructor
|
||||
inline FGBucket::~FGBucket() {}
|
||||
|
||||
|
||||
// Generate the unique scenery tile index for this bucket
|
||||
//
|
||||
// The index is constructed as follows:
|
||||
//
|
||||
// 9 bits - to represent 360 degrees of longitude (-180 to 179)
|
||||
// 8 bits - to represent 180 degrees of latitude (-90 to 89)
|
||||
//
|
||||
// Each 1 degree by 1 degree tile is further broken down into an 8x8
|
||||
// grid. So we also need:
|
||||
//
|
||||
// 3 bits - to represent x (0 to 7)
|
||||
// 3 bits - to represent y (0 to 7)
|
||||
|
||||
inline long int FGBucket::gen_index() {
|
||||
return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x;
|
||||
}
|
||||
|
||||
inline string FGBucket::gen_index_str() const {
|
||||
char tmp[20];
|
||||
sprintf(tmp, "%ld",
|
||||
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
|
||||
return (string)tmp;
|
||||
}
|
||||
|
||||
|
||||
// return the center lon of a tile
|
||||
inline double FGBucket::get_center_lon() const {
|
||||
double span = bucket_span( lat + y / 8.0 + FG_HALF_BUCKET_SPAN );
|
||||
|
||||
if ( span >= 1.0 ) {
|
||||
return lon + span / 2.0;
|
||||
} else {
|
||||
return lon + x * span + span / 2.0;
|
||||
inline long int gen_index() const {
|
||||
return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x;
|
||||
}
|
||||
}
|
||||
|
||||
inline string gen_index_str() const {
|
||||
char tmp[20];
|
||||
sprintf(tmp, "%ld",
|
||||
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
|
||||
return (string)tmp;
|
||||
}
|
||||
|
||||
// Build the path name for this bucket
|
||||
string gen_base_path() const;
|
||||
|
||||
// return the center lon of a tile
|
||||
inline double get_center_lon() const {
|
||||
double span = sg_bucket_span( lat + y / 8.0 + SG_HALF_BUCKET_SPAN );
|
||||
|
||||
if ( span >= 1.0 ) {
|
||||
return lon + span / 2.0;
|
||||
} else {
|
||||
return lon + x * span + span / 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
// return the center lat of a tile
|
||||
inline double get_center_lat() const {
|
||||
return lat + y / 8.0 + SG_HALF_BUCKET_SPAN;
|
||||
}
|
||||
|
||||
// return width of the tile in degrees
|
||||
double get_width() const;
|
||||
// return height of the tile in degrees
|
||||
double get_height() const;
|
||||
|
||||
// return width of the tile in meters
|
||||
double get_width_m() const;
|
||||
// return height of the tile in meters
|
||||
double get_height_m() const;
|
||||
|
||||
// Informational methods
|
||||
inline int get_lon() const { return lon; }
|
||||
inline int get_lat() const { return lat; }
|
||||
inline int get_x() const { return x; }
|
||||
inline int get_y() const { return y; }
|
||||
|
||||
// friends
|
||||
friend ostream& operator<< ( ostream&, const SGBucket& );
|
||||
friend bool operator== ( const SGBucket&, const SGBucket& );
|
||||
};
|
||||
|
||||
|
||||
// return the center lat of a tile
|
||||
inline double FGBucket::get_center_lat() const {
|
||||
return lat + y / 8.0 + FG_HALF_BUCKET_SPAN;
|
||||
}
|
||||
|
||||
|
||||
// return width of the tile
|
||||
inline double FGBucket::get_width() const {
|
||||
return bucket_span( get_center_lat() );
|
||||
}
|
||||
|
||||
|
||||
// return height of the tile
|
||||
inline double FGBucket::get_height() const {
|
||||
return FG_BUCKET_SPAN;
|
||||
}
|
||||
|
||||
|
||||
// create an impossible bucket
|
||||
inline void FGBucket::make_bad( void ) {
|
||||
set_bucket(0.0, 0.0);
|
||||
lon = -1000;
|
||||
}
|
||||
|
||||
|
||||
// offset a bucket struct by the specified tile units in the X & Y
|
||||
// direction
|
||||
FGBucket fgBucketOffset( double dlon, double dlat, int x, int y );
|
||||
// offset a bucket specified by dlon, dlat by the specified tile units
|
||||
// in the X & Y direction
|
||||
SGBucket sgBucketOffset( double dlon, double dlat, int x, int y );
|
||||
|
||||
|
||||
// calculate the offset between two buckets
|
||||
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy );
|
||||
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
|
||||
|
||||
|
||||
inline ostream&
|
||||
operator<< ( ostream& out, const FGBucket& b )
|
||||
operator<< ( ostream& out, const SGBucket& b )
|
||||
{
|
||||
return out << b.lon << ":" << b.x << ", " << b.lat << ":" << b.y;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator== ( const FGBucket& b1, const FGBucket& b2 )
|
||||
operator== ( const SGBucket& b1, const SGBucket& b2 )
|
||||
{
|
||||
return ( b1.lon == b2.lon &&
|
||||
b1.lat == b2.lat &&
|
||||
|
||||
@@ -94,6 +94,25 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* KAI C++ */
|
||||
#if defined(__KCC)
|
||||
|
||||
# define FG_NAMESPACES
|
||||
# define FG_HAVE_STD
|
||||
# define FG_HAVE_STREAMBUF
|
||||
# define FG_HAVE_TRAITS
|
||||
# define FG_HAVE_STD_INCLUDES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
#endif
|
||||
|
||||
//
|
||||
// Metrowerks
|
||||
//
|
||||
|
||||
+3
-2
@@ -86,13 +86,14 @@
|
||||
#define RESQ_FT 437882827922500. // ft
|
||||
#define RESQ_M 40680645877797.1344 // meter
|
||||
|
||||
#if 0
|
||||
// Value of earth flattening parameter from ref [8]
|
||||
//
|
||||
// Note: FP = f
|
||||
// E = 1-f
|
||||
// EPS = sqrt(1-(1-f)^2)
|
||||
//
|
||||
|
||||
|
||||
#define FP 0.003352813178
|
||||
#define E 0.996647186
|
||||
#define EPS 0.081819221
|
||||
@@ -103,7 +104,7 @@
|
||||
#define MJD0 2415020.0
|
||||
#define J2000 (2451545.0 - MJD0)
|
||||
#define SIDRATE .9972695677
|
||||
|
||||
#endif
|
||||
|
||||
// Conversions
|
||||
|
||||
|
||||
@@ -8,4 +8,4 @@ include_HEADERS = debug_types.h logstream.hxx
|
||||
|
||||
libsgdebug_a_SOURCES = logstream.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -49,8 +49,6 @@ FG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
# define cerr std::cerr
|
||||
# define endl std::endl
|
||||
FG_USING_STD(iostream);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ include_HEADERS = \
|
||||
jupiter.hxx \
|
||||
mars.hxx \
|
||||
mercury.hxx \
|
||||
moon.hxx \
|
||||
moonpos.hxx \
|
||||
neptune.hxx \
|
||||
saturn.hxx \
|
||||
star.hxx \
|
||||
stars.hxx \
|
||||
stardata.hxx \
|
||||
uranus.hxx \
|
||||
venus.hxx
|
||||
|
||||
@@ -22,13 +22,13 @@ libsgephem_a_SOURCES = \
|
||||
jupiter.cxx \
|
||||
mars.cxx \
|
||||
mercury.cxx \
|
||||
moon.cxx \
|
||||
moonpos.cxx \
|
||||
neptune.cxx \
|
||||
pluto.hxx \
|
||||
saturn.cxx \
|
||||
star.cxx \
|
||||
stars.cxx \
|
||||
stardata.cxx \
|
||||
uranus.cxx \
|
||||
venus.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -108,7 +108,7 @@ void CelestialBody::updatePosition(double mjd, Star *ourSun)
|
||||
}
|
||||
|
||||
FV = RAD_TO_DEG * acos( tmp );
|
||||
};
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* double CelestialBody::sgCalcEccAnom(double M, double e)
|
||||
|
||||
@@ -121,7 +121,7 @@ inline CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
eFirst = ef; eSec = es;
|
||||
MFirst = Mf; MSec = Ms;
|
||||
updateOrbElements(mjd);
|
||||
};
|
||||
}
|
||||
|
||||
inline CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
double If, double Is,
|
||||
@@ -136,7 +136,7 @@ inline CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
aFirst = af; aSec = as;
|
||||
eFirst = ef; eSec = es;
|
||||
MFirst = Mf; MSec = Ms;
|
||||
};
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* inline void CelestialBody::updateOrbElements(double mjd)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
// Constructor
|
||||
SGEphemeris::SGEphemeris( const string &path ) {
|
||||
our_sun = new Star;
|
||||
moon = new Moon;
|
||||
moon = new MoonPos;
|
||||
mercury = new Mercury;
|
||||
venus = new Venus;
|
||||
mars = new Mars;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
#include <simgear/ephemeris/moon.hxx>
|
||||
#include <simgear/ephemeris/moonpos.hxx>
|
||||
#include <simgear/ephemeris/mercury.hxx>
|
||||
#include <simgear/ephemeris/venus.hxx>
|
||||
#include <simgear/ephemeris/mars.hxx>
|
||||
@@ -45,13 +45,13 @@
|
||||
#include <simgear/ephemeris/saturn.hxx>
|
||||
#include <simgear/ephemeris/uranus.hxx>
|
||||
#include <simgear/ephemeris/neptune.hxx>
|
||||
#include <simgear/ephemeris/stars.hxx>
|
||||
#include <simgear/ephemeris/stardata.hxx>
|
||||
|
||||
|
||||
class SGEphemeris {
|
||||
|
||||
Star *our_sun;
|
||||
Moon *moon;
|
||||
MoonPos *moon;
|
||||
Mercury *mercury;
|
||||
Venus *venus;
|
||||
Mars *mars;
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
}
|
||||
|
||||
// moon
|
||||
inline Moon *get_moon() const { return moon; }
|
||||
inline MoonPos *get_moon() const { return moon; }
|
||||
inline double getMoonRightAscension() const {
|
||||
return moon->getRightAscension();
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef _JUPITER_HXX_
|
||||
#define _JUPITER_HXX_
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
#include <simgear/ephemeris/celestialBody.hxx>
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
|
||||
class Jupiter : public CelestialBody
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef _MARS_HXX_
|
||||
#define _MARS_HXX_
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
#include <simgear/ephemeris/celestialBody.hxx>
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
|
||||
class Mars : public CelestialBody
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**************************************************************************
|
||||
* moon.cxx
|
||||
* moonpos.cxx
|
||||
* Written by Durk Talsma. Originally started October 1997, for distribution
|
||||
* with the FlightGear project. Version 2 was written in August and
|
||||
* September 1998. This code is based upon algorithms and data kindly
|
||||
@@ -36,18 +36,18 @@
|
||||
|
||||
// #include <FDM/flight.hxx>
|
||||
|
||||
#include "moon.hxx"
|
||||
#include "moonpos.hxx"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Moon::Moon(double mjd)
|
||||
* Public constructor for class Moon. Initializes the orbital elements and
|
||||
* MoonPos::MoonPos(double mjd)
|
||||
* Public constructor for class MoonPos. Initializes the orbital elements and
|
||||
* sets up the moon texture.
|
||||
* Argument: The current time.
|
||||
* the hard coded orbital elements for Moon are passed to
|
||||
* the hard coded orbital elements for MoonPos are passed to
|
||||
* CelestialBody::CelestialBody();
|
||||
************************************************************************/
|
||||
Moon::Moon(double mjd) :
|
||||
MoonPos::MoonPos(double mjd) :
|
||||
CelestialBody(125.1228, -0.0529538083,
|
||||
5.1454, 0.00000,
|
||||
318.0634, 0.1643573223,
|
||||
@@ -57,7 +57,7 @@ Moon::Moon(double mjd) :
|
||||
{
|
||||
}
|
||||
|
||||
Moon::Moon() :
|
||||
MoonPos::MoonPos() :
|
||||
CelestialBody(125.1228, -0.0529538083,
|
||||
5.1454, 0.00000,
|
||||
318.0634, 0.1643573223,
|
||||
@@ -68,18 +68,18 @@ Moon::Moon() :
|
||||
}
|
||||
|
||||
|
||||
Moon::~Moon()
|
||||
MoonPos::~MoonPos()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* void Moon::updatePosition(double mjd, Star *ourSun)
|
||||
* void MoonPos::updatePosition(double mjd, Star *ourSun)
|
||||
* this member function calculates the actual topocentric position (i.e.)
|
||||
* the position of the moon as seen from the current position on the surface
|
||||
* of the moon.
|
||||
****************************************************************************/
|
||||
void Moon::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
{
|
||||
double
|
||||
eccAnom, ecl, actTime,
|
||||
@@ -1,5 +1,5 @@
|
||||
/**************************************************************************
|
||||
* moon.hxx
|
||||
* moonpos.hxx
|
||||
* Written by Durk Talsma. Originally started October 1997, for distribution
|
||||
* with the FlightGear project. Version 2 was written in August and
|
||||
* September 1998. This code is based upon algorithms and data kindly
|
||||
@@ -22,8 +22,8 @@
|
||||
*
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
#ifndef _MOON_HXX_
|
||||
#define _MOON_HXX_
|
||||
#ifndef _MOONPOS_HXX_
|
||||
#define _MOONPOS_HXX_
|
||||
|
||||
|
||||
#include <simgear/constants.h>
|
||||
@@ -31,7 +31,8 @@
|
||||
#include <simgear/ephemeris/celestialBody.hxx>
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
|
||||
class Moon : public CelestialBody
|
||||
|
||||
class MoonPos : public CelestialBody
|
||||
{
|
||||
|
||||
private:
|
||||
@@ -49,12 +50,12 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
Moon(double mjd);
|
||||
Moon();
|
||||
~Moon();
|
||||
MoonPos(double mjd);
|
||||
MoonPos();
|
||||
~MoonPos();
|
||||
void updatePosition(double mjd, double lst, double lat, Star *ourSun);
|
||||
// void newImage();
|
||||
};
|
||||
|
||||
|
||||
#endif // _MOON_HXX_
|
||||
#endif // _MOONPOS_HXX_
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef _NEPTUNE_HXX_
|
||||
#define _NEPTUNE_HXX_
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
#include <simgear/ephemeris/celestialBody.hxx>
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
|
||||
class Neptune : public CelestialBody
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef _SATURN_HXX_
|
||||
#define _SATURN_HXX_
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
#include <simgear/ephemeris/celestialBody.hxx>
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
|
||||
class Saturn : public CelestialBody
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// stars.cxx -- manage star data
|
||||
// stardata.cxx -- manage star data
|
||||
//
|
||||
// Written by Curtis Olson, started March 2000.
|
||||
//
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
|
||||
#include "stars.hxx"
|
||||
#include "stardata.hxx"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
FG_USING_STD(getline);
|
||||
@@ -1,4 +1,4 @@
|
||||
// stars.hxx -- manage star data
|
||||
// stardata.hxx -- manage star data
|
||||
//
|
||||
// Written by Curtis Olson, started March 2000.
|
||||
//
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef _URANUS_HXX_
|
||||
#define _URANUS_HXX_
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
#include <simgear/ephemeris/celestialBody.hxx>
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
|
||||
class Uranus : public CelestialBody
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef _VENUS_HXX_
|
||||
#define _VENUS_HXX_
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
#include <simgear/ephemeris/celestialBody.hxx>
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
|
||||
class Venus : public CelestialBody
|
||||
{
|
||||
|
||||
@@ -14,4 +14,12 @@ libsgio_a_SOURCES = \
|
||||
sg_serial.cxx \
|
||||
sg_socket.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
noinst_PROGRAMS = socktest
|
||||
|
||||
socktest_SOURCES = socktest.cxx
|
||||
|
||||
socktest_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
@@ -39,7 +39,7 @@ SGIOChannel::~SGIOChannel()
|
||||
|
||||
|
||||
// dummy configure routine
|
||||
bool SGIOChannel::open( SGProtocolDir dir ) {
|
||||
bool SGIOChannel::open( const SGProtocolDir d ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -57,13 +57,13 @@ int SGIOChannel::readline( char *buf, int length ) {
|
||||
|
||||
|
||||
// dummy process routine
|
||||
int SGIOChannel::write( char *buf, int length ) {
|
||||
int SGIOChannel::write( const char *buf, const int length ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// dummy process routine
|
||||
int SGIOChannel::writestring( char *str ) {
|
||||
int SGIOChannel::writestring( const char *str ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,21 +55,27 @@ enum SGChannelType {
|
||||
class SGIOChannel {
|
||||
|
||||
SGChannelType type;
|
||||
SGProtocolDir dir;
|
||||
bool valid;
|
||||
|
||||
public:
|
||||
|
||||
SGIOChannel();
|
||||
virtual ~SGIOChannel();
|
||||
|
||||
virtual bool open( SGProtocolDir dir );
|
||||
virtual bool open( const SGProtocolDir d );
|
||||
virtual int read( char *buf, int length );
|
||||
virtual int readline( char *buf, int length );
|
||||
virtual int write( char *buf, int length );
|
||||
virtual int writestring( char *str );
|
||||
virtual int write( const char *buf, const int length );
|
||||
virtual int writestring( const char *str );
|
||||
virtual bool close();
|
||||
|
||||
virtual void set_type( SGChannelType t ) { type = t; }
|
||||
virtual SGChannelType get_type() const { return type; }
|
||||
inline void set_type( SGChannelType t ) { type = t; }
|
||||
inline SGChannelType get_type() const { return type; }
|
||||
|
||||
inline void set_dir( const SGProtocolDir d ) { dir = d; }
|
||||
inline SGProtocolDir get_dir() const { return dir; }
|
||||
inline bool isvalid() const { return valid; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
+15
-37
@@ -47,22 +47,18 @@ SGFile::~SGFile() {
|
||||
|
||||
|
||||
// open the file based on specified direction
|
||||
bool SGFile::open( SGProtocolDir dir ) {
|
||||
if ( dir == SG_IO_OUT ) {
|
||||
bool SGFile::open( const SGProtocolDir d ) {
|
||||
set_dir( d );
|
||||
|
||||
if ( get_dir() == SG_IO_OUT ) {
|
||||
#ifdef _MSC_VER
|
||||
fp = _open( file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
|
||||
00666 );
|
||||
int mode = 00666;
|
||||
#else
|
||||
fp = std::open( file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
|
||||
S_IROTH | S_IWOTH );
|
||||
#endif
|
||||
} else if ( dir == SG_IO_IN ) {
|
||||
#ifdef _MSC_VER
|
||||
fp = _open( file_name.c_str(), O_RDONLY );
|
||||
#else
|
||||
fp = std::open( file_name.c_str(), O_RDONLY );
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
#endif
|
||||
fp = ::open( file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode );
|
||||
} else if ( get_dir() == SG_IO_IN ) {
|
||||
fp = ::open( file_name.c_str(), O_RDONLY );
|
||||
} else {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: bidirection mode not available for files." );
|
||||
@@ -81,13 +77,7 @@ bool SGFile::open( SGProtocolDir dir ) {
|
||||
// read a block of data of specified size
|
||||
int SGFile::read( char *buf, int length ) {
|
||||
// read a chunk
|
||||
#ifdef _MSC_VER
|
||||
int result = _read( fp, buf, length );
|
||||
#else
|
||||
int result = std::read( fp, buf, length );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return ::read( fp, buf, length );
|
||||
}
|
||||
|
||||
|
||||
@@ -97,11 +87,7 @@ int SGFile::readline( char *buf, int length ) {
|
||||
int pos = lseek( fp, 0, SEEK_CUR );
|
||||
|
||||
// read a chunk
|
||||
#ifdef _MSC_VER
|
||||
int result = _read( fp, buf, length );
|
||||
#else
|
||||
int result = std::read( fp, buf, length );
|
||||
#endif
|
||||
int result = ::read( fp, buf, length );
|
||||
|
||||
// find the end of line and reset position
|
||||
int i;
|
||||
@@ -121,12 +107,8 @@ int SGFile::readline( char *buf, int length ) {
|
||||
|
||||
|
||||
// write data to a file
|
||||
int SGFile::write( char *buf, int length ) {
|
||||
#ifdef _MSC_VER
|
||||
int result = _write( fp, buf, length );
|
||||
#else
|
||||
int result = std::write( fp, buf, length );
|
||||
#endif
|
||||
int SGFile::write( const char *buf, const int length ) {
|
||||
int result = ::write( fp, buf, length );
|
||||
if ( result != length ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error writing data: " << file_name );
|
||||
}
|
||||
@@ -136,7 +118,7 @@ int SGFile::write( char *buf, int length ) {
|
||||
|
||||
|
||||
// write null terminated string to a file
|
||||
int SGFile::writestring( char *str ) {
|
||||
int SGFile::writestring( const char *str ) {
|
||||
int length = strlen( str );
|
||||
return write( str, length );
|
||||
}
|
||||
@@ -144,11 +126,7 @@ int SGFile::writestring( char *str ) {
|
||||
|
||||
// close the port
|
||||
bool SGFile::close() {
|
||||
#ifdef _MSC_VER
|
||||
if ( _close( fp ) == -1 ) {
|
||||
#else
|
||||
if ( std::close( fp ) == -1 ) {
|
||||
#endif
|
||||
if ( ::close( fp ) == -1 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
~SGFile();
|
||||
|
||||
// open the file based on specified direction
|
||||
bool open( SGProtocolDir dir );
|
||||
bool open( const SGProtocolDir dir );
|
||||
|
||||
// read a block of data of specified size
|
||||
int read( char *buf, int length );
|
||||
@@ -65,10 +65,10 @@ public:
|
||||
int readline( char *buf, int length );
|
||||
|
||||
// write data to a file
|
||||
int write( char *buf, int length );
|
||||
int write( const char *buf, const int length );
|
||||
|
||||
// write null terminated string to a file
|
||||
int writestring( char *str );
|
||||
int writestring( const char *str );
|
||||
|
||||
// close file
|
||||
bool close();
|
||||
|
||||
@@ -47,7 +47,9 @@ SGSerial::~SGSerial() {
|
||||
|
||||
|
||||
// open the serial port based on specified direction
|
||||
bool SGSerial::open( SGProtocolDir dir ) {
|
||||
bool SGSerial::open( const SGProtocolDir d ) {
|
||||
set_dir( d );
|
||||
|
||||
if ( ! port.open_port( device ) ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error opening device: " << device );
|
||||
return false;
|
||||
@@ -127,7 +129,7 @@ int SGSerial::readline( char *buf, int length ) {
|
||||
|
||||
|
||||
// write data to port
|
||||
int SGSerial::write( char *buf, int length ) {
|
||||
int SGSerial::write( const char *buf, const int length ) {
|
||||
int result = port.write_port( buf, length );
|
||||
|
||||
if ( result != length ) {
|
||||
@@ -139,7 +141,7 @@ int SGSerial::write( char *buf, int length ) {
|
||||
|
||||
|
||||
// write null terminated string to port
|
||||
int SGSerial::writestring( char *str ) {
|
||||
int SGSerial::writestring( const char *str ) {
|
||||
int length = strlen( str );
|
||||
return write( str, length );
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
~SGSerial();
|
||||
|
||||
// open the serial port based on specified direction
|
||||
bool open( SGProtocolDir dir );
|
||||
bool open( const SGProtocolDir d );
|
||||
|
||||
// read a block of data of specified size
|
||||
int read( char *buf, int length );
|
||||
@@ -70,10 +70,10 @@ public:
|
||||
int readline( char *buf, int length );
|
||||
|
||||
// write data to port
|
||||
int write( char *buf, int length );
|
||||
int write( const char *buf, const int length );
|
||||
|
||||
// write null terminated string to port
|
||||
int writestring( char *str );
|
||||
int writestring( const char *str );
|
||||
|
||||
// close port
|
||||
bool close();
|
||||
|
||||
+213
-81
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#if ! defined( _MSC_VER )
|
||||
#if !defined(_MSC_VER)
|
||||
# include <sys/time.h> // select()
|
||||
# include <sys/types.h> // socket(), bind(), select(), accept()
|
||||
# include <sys/socket.h> // socket(), bind(), listen(), accept()
|
||||
@@ -31,33 +31,28 @@
|
||||
# include <netdb.h> // gethostbyname()
|
||||
# include <unistd.h> // select(), fsync()/fdatasync(), fcntl()
|
||||
# include <fcntl.h> // fcntl()
|
||||
#else
|
||||
# include <sys/timeb.h> // select()
|
||||
# include <winsock2.h> // socket(), bind(), listen(), accept(),
|
||||
// struct sockaddr_in, gethostbyname()
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#if defined( sgi )
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
|
||||
SGSocket::SGSocket( const string& host, const string& port,
|
||||
const string& style ) :
|
||||
hostname(host),
|
||||
port_str(port),
|
||||
save_len(0)
|
||||
{
|
||||
hostname = host;
|
||||
port_str = port;
|
||||
#if defined(_MSC_VER)
|
||||
if (!wsock_init && !wsastartup()) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Winsock not available");
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( style == "udp" ) {
|
||||
sock_style = SOCK_DGRAM;
|
||||
@@ -77,7 +72,7 @@ SGSocket::~SGSocket() {
|
||||
}
|
||||
|
||||
|
||||
int SGSocket::make_server_socket () {
|
||||
SGSocket::SocketType SGSocket::make_server_socket () {
|
||||
struct sockaddr_in name;
|
||||
|
||||
#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ ) || defined( sgi ) || defined( _MSC_VER )
|
||||
@@ -88,10 +83,10 @@ int SGSocket::make_server_socket () {
|
||||
|
||||
// Create the socket.
|
||||
sock = socket (PF_INET, sock_style, 0);
|
||||
if (sock < 0) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: socket() failed in make_server_socket()" );
|
||||
return -1;
|
||||
if (sock == INVALID_SOCKET) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: socket() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
// Give the socket a name.
|
||||
@@ -99,18 +94,18 @@ int SGSocket::make_server_socket () {
|
||||
name.sin_addr.s_addr = INADDR_ANY;
|
||||
name.sin_port = htons(port); // set port to zero to let system pick
|
||||
name.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: bind() failed in make_server_socket()" );
|
||||
return -1;
|
||||
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) != 0) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: bind() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
|
||||
// Find the assigned port number
|
||||
length = sizeof(struct sockaddr_in);
|
||||
if ( getsockname(sock, (struct sockaddr *) &name, &length) ) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: getsockname() failed in make_server_socket()" );
|
||||
return -1;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
port = ntohs(name.sin_port);
|
||||
|
||||
@@ -118,7 +113,7 @@ int SGSocket::make_server_socket () {
|
||||
}
|
||||
|
||||
|
||||
int SGSocket::make_client_socket () {
|
||||
SGSocket::SocketType SGSocket::make_client_socket () {
|
||||
struct sockaddr_in name;
|
||||
struct hostent *hp;
|
||||
|
||||
@@ -126,10 +121,10 @@ int SGSocket::make_client_socket () {
|
||||
|
||||
// Create the socket.
|
||||
sock = socket (PF_INET, sock_style, 0);
|
||||
if (sock < 0) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: socket() failed in make_client_socket()" );
|
||||
return -1;
|
||||
if (sock == INVALID_SOCKET) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: socket() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
// specify address family
|
||||
@@ -148,26 +143,48 @@ int SGSocket::make_client_socket () {
|
||||
name.sin_port = htons(port);
|
||||
|
||||
if ( connect(sock, (struct sockaddr *) &name,
|
||||
sizeof(struct sockaddr_in)) < 0 )
|
||||
sizeof(struct sockaddr_in)) != 0 )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
_close(sock);
|
||||
#else
|
||||
std::close(sock);
|
||||
#endif
|
||||
closesocket(sock);
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: connect() failed in make_client_socket()" );
|
||||
return -1;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
// Wrapper functions
|
||||
size_t SGSocket::readsocket( int fd, void *buf, size_t count ) {
|
||||
#if defined(_MSC_VER)
|
||||
return ::recv( fd, (char *)buf, count, 0 );
|
||||
#else
|
||||
return ::read( fd, buf, count );
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t SGSocket::writesocket( int fd, const void *buf, size_t count ) {
|
||||
#if defined(_MSC_VER)
|
||||
return ::send( fd, (const char*)buf, count, 0 );
|
||||
#else
|
||||
return ::write( fd, buf, count );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
int SGSocket::closesocket( int fd ) {
|
||||
return ::close( fd );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// If specified as a server (in direction for now) open the master
|
||||
// listening socket. If specified as a client (out direction), open a
|
||||
// connection to a server.
|
||||
bool SGSocket::open( SGProtocolDir dir ) {
|
||||
bool SGSocket::open( const SGProtocolDir d ) {
|
||||
set_dir( d );
|
||||
|
||||
if ( port_str == "" || port_str == "any" ) {
|
||||
port = 0;
|
||||
} else {
|
||||
@@ -176,36 +193,56 @@ bool SGSocket::open( SGProtocolDir dir ) {
|
||||
|
||||
// client_connections.clear();
|
||||
|
||||
if ( dir == SG_IO_IN ) {
|
||||
if ( get_dir() == SG_IO_IN ) {
|
||||
// this means server for now
|
||||
|
||||
// Setup socket to listen on. Set "port" before making this
|
||||
// call. A port of "0" indicates that we want to let the os
|
||||
// pick any available port.
|
||||
sock = make_server_socket();
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "socket creation failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
FG_LOG( FG_IO, FG_INFO, "socket is connected to port = " << port );
|
||||
|
||||
if ( sock_style == SOCK_DGRAM ) {
|
||||
// Non-blocking UDP
|
||||
fcntl( sock, F_SETFL, O_NONBLOCK );
|
||||
nonblock();
|
||||
} else {
|
||||
// Blocking TCP
|
||||
// Specify the maximum length of the connection queue
|
||||
listen( sock, SG_MAX_SOCKET_QUEUE );
|
||||
}
|
||||
|
||||
} else if ( dir == SG_IO_OUT ) {
|
||||
} else if ( get_dir() == SG_IO_OUT ) {
|
||||
// this means client for now
|
||||
|
||||
sock = make_client_socket();
|
||||
// TODO: check for error.
|
||||
|
||||
if ( sock_style == SOCK_DGRAM ) {
|
||||
// Non-blocking UDP
|
||||
fcntl( sock, F_SETFL, O_NONBLOCK );
|
||||
nonblock();
|
||||
}
|
||||
} else if ( get_dir() == SG_IO_BI && sock_style == SOCK_STREAM ) {
|
||||
// this means server for TCP sockets
|
||||
|
||||
// Setup socket to listen on. Set "port" before making this
|
||||
// call. A port of "0" indicates that we want to let the os
|
||||
// pick any available port.
|
||||
sock = make_server_socket();
|
||||
// TODO: check for error.
|
||||
|
||||
FG_LOG( FG_IO, FG_INFO, "socket is connected to port = " << port );
|
||||
|
||||
// Blocking TCP
|
||||
// Specify the maximum length of the connection queue
|
||||
listen( sock, SG_MAX_SOCKET_QUEUE );
|
||||
} else {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error: bidirection mode not available yet for sockets." );
|
||||
"Error: bidirection mode not available for UDP sockets." );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -215,6 +252,10 @@ bool SGSocket::open( SGProtocolDir dir ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// extra SOCK_STREAM stuff
|
||||
msgsock = INVALID_SOCKET;
|
||||
first_read = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -222,8 +263,11 @@ bool SGSocket::open( SGProtocolDir dir ) {
|
||||
// read data from socket (server)
|
||||
// read a block of data of specified size
|
||||
int SGSocket::read( char *buf, int length ) {
|
||||
int result = 0;
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
// check for potential input
|
||||
fd_set ready;
|
||||
FD_ZERO(&ready);
|
||||
@@ -237,11 +281,20 @@ int SGSocket::read( char *buf, int length ) {
|
||||
select(32, &ready, 0, 0, &tv);
|
||||
|
||||
if ( FD_ISSET(sock, &ready) ) {
|
||||
#ifdef _MSC_VER
|
||||
result = _read( sock, buf, length );
|
||||
#else
|
||||
result = std::read( sock, buf, length );
|
||||
#endif
|
||||
// cout << "data ready" << endl;
|
||||
|
||||
if ( sock_style == SOCK_STREAM ) {
|
||||
if ( msgsock == INVALID_SOCKET ) {
|
||||
msgsock = accept(sock, 0, 0);
|
||||
closesocket(sock);
|
||||
sock = msgsock;
|
||||
} else {
|
||||
result = readsocket( sock, buf, length );
|
||||
}
|
||||
} else {
|
||||
result = readsocket( sock, buf, length );
|
||||
}
|
||||
|
||||
if ( result != length ) {
|
||||
FG_LOG( FG_IO, FG_INFO,
|
||||
"Warning: read() not enough bytes." );
|
||||
@@ -254,7 +307,11 @@ int SGSocket::read( char *buf, int length ) {
|
||||
|
||||
// read a line of data, length is max size of input buffer
|
||||
int SGSocket::readline( char *buf, int length ) {
|
||||
int result = 0;
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// cout << "sock = " << sock << endl;
|
||||
|
||||
// check for potential input
|
||||
fd_set ready;
|
||||
@@ -266,22 +323,55 @@ int SGSocket::readline( char *buf, int length ) {
|
||||
|
||||
// test for any input read on sock (returning immediately, even if
|
||||
// nothing)
|
||||
select(32, &ready, 0, 0, &tv);
|
||||
int result = select(32, &ready, 0, 0, &tv);
|
||||
// cout << "result = " << result << endl;
|
||||
|
||||
if ( FD_ISSET(sock, &ready) ) {
|
||||
// cout << "fd change state\n";
|
||||
// read a chunk, keep in the save buffer until we have the
|
||||
// requested amount read
|
||||
|
||||
char *buf_ptr = save_buf + save_len;
|
||||
#ifdef _MSC_VER
|
||||
result = _read( sock, buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
|
||||
#else
|
||||
result = std::read( sock, buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
|
||||
#endif
|
||||
save_len += result;
|
||||
if ( sock_style == SOCK_STREAM ) {
|
||||
// cout << "sock_stream\n";
|
||||
if ( msgsock == INVALID_SOCKET ) {
|
||||
// cout << "msgsock == invalid\n";
|
||||
msgsock = accept(sock, 0, 0);
|
||||
closesocket(sock);
|
||||
sock = msgsock;
|
||||
} else {
|
||||
// cout << "ready to read\n";
|
||||
char *buf_ptr = save_buf + save_len;
|
||||
result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE
|
||||
- save_len );
|
||||
// cout << "read result = " << result << endl;
|
||||
|
||||
if ( result > 0 ) {
|
||||
first_read = true;
|
||||
}
|
||||
|
||||
save_len += result;
|
||||
|
||||
// Try and detect that the remote end died. This
|
||||
// could cause problems so if you see connections
|
||||
// dropping for unexplained reasons, LOOK HERE!
|
||||
if ( result == 0 && save_len == 0 && first_read == true ) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Connection closed by foreign host." );
|
||||
closesocket(sock);
|
||||
open( get_dir() );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char *buf_ptr = save_buf + save_len;
|
||||
result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
|
||||
save_len += result;
|
||||
}
|
||||
|
||||
// cout << "current read = " << buf_ptr << endl;
|
||||
// cout << "current save_buf = " << save_buf << endl;
|
||||
// cout << "save_len = " << save_len << endl;
|
||||
} else {
|
||||
// cout << "no data ready\n";
|
||||
}
|
||||
|
||||
// look for the end of line in save_buf
|
||||
@@ -314,14 +404,14 @@ int SGSocket::readline( char *buf, int length ) {
|
||||
|
||||
|
||||
// write data to socket (client)
|
||||
int SGSocket::write( char *buf, int length ) {
|
||||
int SGSocket::write( const char *buf, const int length ) {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool error_condition = false;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
if ( _write(sock, buf, length) < 0 ) {
|
||||
#else
|
||||
if ( std::write(sock, buf, length) < 0 ) {
|
||||
#endif
|
||||
if ( writesocket(sock, buf, length) < 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error writing to socket: " << port );
|
||||
error_condition = true;
|
||||
}
|
||||
@@ -361,11 +451,7 @@ int SGSocket::write( char *buf, int length ) {
|
||||
// std::read( msgsock, junk, SG_IO_MAX_MSG_SIZE );
|
||||
|
||||
// write the interesting data to the socket
|
||||
#ifdef _MSC_VER
|
||||
if ( _write(msgsock, buf, length) < 0 ) {
|
||||
#else
|
||||
if ( std::write(msgsock, buf, length) < 0 ) {
|
||||
#endif
|
||||
if ( writesocket(msgsock, buf, length) == SOCKET_ERROR ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error writing to socket: " << port );
|
||||
error_condition = true;
|
||||
} else {
|
||||
@@ -387,7 +473,11 @@ int SGSocket::write( char *buf, int length ) {
|
||||
|
||||
|
||||
// write null terminated string to socket (server)
|
||||
int SGSocket::writestring( char *str ) {
|
||||
int SGSocket::writestring( const char *str ) {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int length = strlen( str );
|
||||
return write( str, length );
|
||||
}
|
||||
@@ -395,21 +485,63 @@ int SGSocket::writestring( char *str ) {
|
||||
|
||||
// close the port
|
||||
bool SGSocket::close() {
|
||||
#if 0
|
||||
for ( int i = 0; i < (int)client_connections.size(); ++i ) {
|
||||
int msgsock = client_connections[i];
|
||||
#ifdef _MSC_VER
|
||||
_close( msgsock );
|
||||
#else
|
||||
std::close( msgsock );
|
||||
#endif
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
_close( sock );
|
||||
closesocket( sock );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// configure the socket as non-blocking
|
||||
bool SGSocket::nonblock() {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
u_long arg = 1;
|
||||
if (ioctlsocket( sock, FIONBIO, &arg ) != 0) {
|
||||
int error_code = WSAGetLastError();
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Error " << error_code << ": unable to set non-blocking mode"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
std::close( sock );
|
||||
fcntl( sock, F_SETFL, O_NONBLOCK );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
bool SGSocket::wsock_init = false;
|
||||
|
||||
bool
|
||||
SGSocket::wsastartup() {
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
|
||||
//wVersionRequested = MAKEWORD( 2, 2 );
|
||||
wVersionRequested = MAKEWORD( 1, 1 );
|
||||
int err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if (err != 0)
|
||||
{
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error: Couldn't load winsock" );
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( LOBYTE( wsaData.wVersion ) != 2 ||
|
||||
HIBYTE( wsaData.wVersion ) != 2 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Couldn't load a suitable winsock");
|
||||
WSACleanup( );
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
wsock_init = true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
+38
-11
@@ -31,37 +31,61 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <string>
|
||||
#include STL_STRING
|
||||
|
||||
#include <simgear/math/fg_types.hxx>
|
||||
|
||||
#include "iochannel.hxx"
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/io/iochannel.hxx>
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# include <winsock.h>
|
||||
#endif
|
||||
|
||||
#define SG_MAX_SOCKET_QUEUE 32
|
||||
|
||||
|
||||
class SGSocket : public SGIOChannel {
|
||||
public:
|
||||
#if defined(_MSC_VER)
|
||||
typedef SOCKET SocketType;
|
||||
#else
|
||||
typedef int SocketType;
|
||||
# define INVALID_SOCKET (-1)
|
||||
#endif
|
||||
|
||||
private:
|
||||
string hostname;
|
||||
string port_str;
|
||||
|
||||
char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ];
|
||||
int save_len;
|
||||
|
||||
int sock;
|
||||
SocketType sock;
|
||||
SocketType msgsock;
|
||||
short unsigned int port;
|
||||
int sock_style; // SOCK_STREAM or SOCK_DGRAM
|
||||
|
||||
bool first_read;
|
||||
|
||||
// make a server (master listening) socket
|
||||
int make_server_socket();
|
||||
SocketType make_server_socket();
|
||||
|
||||
// make a client socket
|
||||
int make_client_socket();
|
||||
SocketType make_client_socket();
|
||||
|
||||
// int_list client_connections;
|
||||
// wrapper functions
|
||||
size_t readsocket( int fd, void *buf, size_t count );
|
||||
size_t writesocket( int fd, const void *buf, size_t count );
|
||||
#if !defined(_MSC_VER)
|
||||
int closesocket(int fd);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Ensure winsock has been initialised.
|
||||
static bool wsock_init;
|
||||
static bool wsastartup();
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -71,7 +95,7 @@ public:
|
||||
// If specified as a server (in direction for now) open the master
|
||||
// listening socket. If specified as a client (out direction),
|
||||
// open a connection to a server.
|
||||
bool open( SGProtocolDir dir );
|
||||
bool open( const SGProtocolDir d );
|
||||
|
||||
// read data from socket
|
||||
int read( char *buf, int length );
|
||||
@@ -80,14 +104,17 @@ public:
|
||||
int readline( char *buf, int length );
|
||||
|
||||
// write data to a socket
|
||||
int write( char *buf, int length );
|
||||
int write( const char *buf, const int length );
|
||||
|
||||
// write null terminated string to a socket
|
||||
int writestring( char *str );
|
||||
int writestring( const char *str );
|
||||
|
||||
// close file
|
||||
bool close();
|
||||
|
||||
// Enable non-blocking mode.
|
||||
bool nonblock();
|
||||
|
||||
inline string get_hostname() const { return hostname; }
|
||||
inline string get_port_str() const { return port_str; }
|
||||
};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
int main() {
|
||||
|
||||
SGSocket s( "", "5500", "tcp" );
|
||||
|
||||
if ( !s.open( SG_IO_BI ) ) {
|
||||
cout << "error can't open socket\n";
|
||||
}
|
||||
|
||||
char buf[256];
|
||||
|
||||
while ( true ) {
|
||||
if ( s.readline( buf, 256 ) > 0 ) {
|
||||
cout << "result = " << buf;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,4 @@ testmagvar_SOURCES = testmagvar.cxx
|
||||
|
||||
testmagvar_LDADD = $(top_builddir)/simgear/magvar/libsgmagvar.a
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -3,30 +3,31 @@ includedir = @includedir@/math
|
||||
if HAVE_ZLIB
|
||||
ZLIB_INCL =
|
||||
else
|
||||
ZLIB_INCL = -I$(top_builddir)/src/zlib
|
||||
ZLIB_INCL = -I$(top_srcdir)/src/zlib
|
||||
endif
|
||||
|
||||
lib_LIBRARIES = libsgmath.a
|
||||
|
||||
include_HEADERS = \
|
||||
fg_geodesy.hxx \
|
||||
fg_memory.h \
|
||||
fg_random.h \
|
||||
fg_types.hxx \
|
||||
interpolater.hxx \
|
||||
leastsqs.hxx \
|
||||
localconsts.hxx \
|
||||
point3d.hxx \
|
||||
polar3d.hxx \
|
||||
sg_geodesy.hxx \
|
||||
sg_random.h \
|
||||
sg_types.hxx \
|
||||
vector.hxx
|
||||
|
||||
EXTRA_DIST = linintp2.h linintp2.inl sphrintp.h sphrintp.inl
|
||||
|
||||
libsgmath_a_SOURCES = \
|
||||
fg_geodesy.cxx \
|
||||
fg_random.c \
|
||||
interpolater.cxx \
|
||||
leastsqs.cxx \
|
||||
polar3d.cxx \
|
||||
sg_geodesy.cxx \
|
||||
sg_random.c \
|
||||
vector.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir) $(ZLIB_INCL)
|
||||
INCLUDES += -I$(top_srcdir) $(ZLIB_INCL)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// localconsts.hxx -- various constant that are shared
|
||||
//
|
||||
// Written by Curtis Olson, started September 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _SG_LOCAL_CONSTS_HXX
|
||||
#define _SG_LOCAL_CONSTS_HXX
|
||||
|
||||
|
||||
// Value of earth flattening parameter from ref [8]
|
||||
//
|
||||
// Note: FP = f
|
||||
// E = 1-f
|
||||
// EPS = sqrt(1-(1-f)^2)
|
||||
//
|
||||
|
||||
static const double FP = 0.003352813178;
|
||||
static const double E = 0.996647186;
|
||||
static const double EPS = 0.081819221;
|
||||
static const double INVG = 0.031080997;
|
||||
|
||||
|
||||
#endif // _SG_LOCAL_CONSTS_HXX
|
||||
@@ -46,6 +46,8 @@
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/math/localconsts.hxx>
|
||||
|
||||
// I don't understand ... <math.h> or <cmath> should be included
|
||||
// already depending on how you defined FG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
|
||||
@@ -40,13 +40,13 @@
|
||||
// Find the Altitude above the Ellipsoid (WGS84) given the Earth
|
||||
// Centered Cartesian coordinate vector Distances are specified in
|
||||
// meters.
|
||||
double fgGeodAltFromCart(const Point3D& cp);
|
||||
double sgGeodAltFromCart(const Point3D& cp);
|
||||
|
||||
|
||||
// Convert a polar coordinate to a cartesian coordinate. Lon and Lat
|
||||
// must be specified in radians. The FG convention is for distances
|
||||
// must be specified in radians. The SG convention is for distances
|
||||
// to be specified in meters
|
||||
inline Point3D fgPolarToCart3d(const Point3D& p) {
|
||||
inline Point3D sgPolarToCart3d(const Point3D& p) {
|
||||
double tmp = cos( p.lat() ) * p.radius();
|
||||
|
||||
return Point3D( cos( p.lon() ) * tmp,
|
||||
@@ -57,7 +57,7 @@ inline Point3D fgPolarToCart3d(const Point3D& p) {
|
||||
|
||||
// Convert a cartesian coordinate to polar coordinates (lon/lat
|
||||
// specified in radians. Distances are specified in meters.
|
||||
inline Point3D fgCartToPolar3d(const Point3D& cp) {
|
||||
inline Point3D sgCartToPolar3d(const Point3D& cp) {
|
||||
return Point3D( atan2( cp.y(), cp.x() ),
|
||||
FG_PI_2 -
|
||||
atan2( sqrt(cp.x()*cp.x() + cp.y()*cp.y()), cp.z() ),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// fg_geodesy.cxx -- routines to convert between geodetic and geocentric
|
||||
// sg_geodesy.cxx -- routines to convert between geodetic and geocentric
|
||||
// coordinate systems.
|
||||
//
|
||||
// Copied and adapted directly from LaRCsim/ls_geodesy.c
|
||||
@@ -21,7 +21,9 @@
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "point3d.hxx"
|
||||
#include "fg_geodesy.hxx"
|
||||
#include "sg_geodesy.hxx"
|
||||
#include "localconsts.hxx"
|
||||
|
||||
|
||||
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
|
||||
FG_USING_STD(cout);
|
||||
@@ -31,7 +33,7 @@ FG_USING_STD(cout);
|
||||
#define ONE_SECOND 4.848136811E-6
|
||||
|
||||
|
||||
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
|
||||
// sgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
|
||||
// INPUTS:
|
||||
// lat_geoc Geocentric latitude, radians, + = North
|
||||
// radius C.G. radius to earth center (meters)
|
||||
@@ -43,7 +45,7 @@ FG_USING_STD(cout);
|
||||
// local vertical (surface normal) of C.G. (meters)
|
||||
|
||||
|
||||
void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
void sgGeocToGeod( double lat_geoc, double radius, double
|
||||
*lat_geod, double *alt, double *sea_level_r )
|
||||
{
|
||||
double t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
|
||||
@@ -89,7 +91,7 @@ void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
|
||||
// check for domain error
|
||||
if ( errno == EDOM ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Domain ERROR in fgGeocToGeod!!!!" );
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Domain ERROR in sgGeocToGeod!!!!" );
|
||||
*sea_level_r = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -97,7 +99,7 @@ void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
}
|
||||
|
||||
|
||||
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
|
||||
// sgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
|
||||
// INPUTS:
|
||||
// lat_geod Geodetic latitude, radians, + = North
|
||||
// alt C.G. altitude above mean sea level (meters)
|
||||
@@ -109,7 +111,7 @@ void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
//
|
||||
|
||||
|
||||
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
void sgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
double *lat_geoc )
|
||||
{
|
||||
double lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
|
||||
@@ -1,4 +1,4 @@
|
||||
// fg_geodesy.hxx -- routines to convert between geodetic and geocentric
|
||||
// sg_geodesy.hxx -- routines to convert between geodetic and geocentric
|
||||
// coordinate systems.
|
||||
//
|
||||
// Copied and adapted directly from LaRCsim/ls_geodesy.c
|
||||
@@ -8,8 +8,8 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_GEODESY_HXX
|
||||
#define _FG_GEODESY_HXX
|
||||
#ifndef _SG_GEODESY_HXX
|
||||
#define _SG_GEODESY_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
|
||||
|
||||
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
|
||||
// sgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
|
||||
// INPUTS:
|
||||
// lat_geoc Geocentric latitude, radians, + = North
|
||||
// radius C.G. radius to earth center (meters)
|
||||
@@ -32,11 +32,11 @@
|
||||
// sea_level_r radius from earth center to sea level at
|
||||
// local vertical (surface normal) of C.G. (meters)
|
||||
|
||||
void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
void sgGeocToGeod( double lat_geoc, double radius, double
|
||||
*lat_geod, double *alt, double *sea_level_r );
|
||||
|
||||
|
||||
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
|
||||
// sgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
|
||||
// INPUTS:
|
||||
// lat_geod Geodetic latitude, radians, + = North
|
||||
// alt C.G. altitude above mean sea level (meters)
|
||||
@@ -47,27 +47,27 @@ void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
// lat_geoc Geocentric latitude, radians, + = North
|
||||
//
|
||||
|
||||
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
void sgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
double *lat_geoc );
|
||||
|
||||
|
||||
// convert a geodetic point lon(radians), lat(radians), elev(meter) to
|
||||
// a cartesian point
|
||||
|
||||
inline Point3D fgGeodToCart(const Point3D& geod) {
|
||||
inline Point3D sgGeodToCart(const Point3D& geod) {
|
||||
double gc_lon, gc_lat, sl_radius;
|
||||
|
||||
// printf("A geodetic point is (%.2f, %.2f, %.2f)\n",
|
||||
// geod[0], geod[1], geod[2]);
|
||||
|
||||
gc_lon = geod.lon();
|
||||
fgGeodToGeoc(geod.lat(), geod.radius(), &sl_radius, &gc_lat);
|
||||
sgGeodToGeoc(geod.lat(), geod.radius(), &sl_radius, &gc_lat);
|
||||
|
||||
// printf("A geocentric point is (%.2f, %.2f, %.2f)\n", gc_lon,
|
||||
// gc_lat, sl_radius+geod[2]);
|
||||
|
||||
Point3D pp = Point3D( gc_lon, gc_lat, sl_radius + geod.radius());
|
||||
return fgPolarToCart3d(pp);
|
||||
return sgPolarToCart3d(pp);
|
||||
}
|
||||
|
||||
|
||||
@@ -172,4 +172,4 @@ $Header$
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#endif // _FG_GEODESY_HXX
|
||||
#endif // _SG_GEODESY_HXX
|
||||
@@ -1,4 +1,4 @@
|
||||
// fg_random.c -- routines to handle random number generation
|
||||
// sg_random.c -- routines to handle random number generation
|
||||
//
|
||||
// Written by Curtis Olson, started July 1997.
|
||||
//
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <stdlib.h> // for random(), srandom()
|
||||
#include <time.h> // for time() to seed srandom()
|
||||
|
||||
#include "fg_random.h"
|
||||
#include "sg_random.h"
|
||||
|
||||
#ifndef HAVE_RAND
|
||||
# ifdef sgi
|
||||
@@ -49,9 +49,7 @@
|
||||
|
||||
// Seed the random number generater with time() so we don't see the
|
||||
// same sequence every time
|
||||
void fg_srandom(void) {
|
||||
// fgPrintf( FG_MATH, FG_INFO, "Seeding random number generater\n");
|
||||
|
||||
void sg_srandom_time(void) {
|
||||
#ifdef HAVE_RAND
|
||||
srand(time(NULL));
|
||||
#else
|
||||
@@ -60,8 +58,19 @@ void fg_srandom(void) {
|
||||
}
|
||||
|
||||
|
||||
// Seed the random number generater with your own seed so can set up
|
||||
// repeatable randomization.
|
||||
void sg_srandom( unsigned int seed ) {
|
||||
#ifdef HAVE_RAND
|
||||
srand( seed );
|
||||
#else
|
||||
srandom( seed );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// return a random number between [0.0, 1.0)
|
||||
double fg_random(void) {
|
||||
double sg_random(void) {
|
||||
#ifdef HAVE_RAND
|
||||
return(rand() / (double)RAND_MAX);
|
||||
#else
|
||||
@@ -1,4 +1,4 @@
|
||||
// fg_random.h -- routines to handle random number generation
|
||||
// sg_random.h -- routines to handle random number generation
|
||||
//
|
||||
// Written by Curtis Olson, started July 1997.
|
||||
//
|
||||
@@ -22,8 +22,8 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_RANDOM_H
|
||||
#define _FG_RANDOM_H
|
||||
#ifndef _SG_RANDOM_H
|
||||
#define _SG_RANDOM_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -33,10 +33,14 @@ extern "C" {
|
||||
|
||||
// Seed the random number generater with time() so we don't see the
|
||||
// same sequence every time
|
||||
void fg_srandom(void);
|
||||
void sg_srandom_time(void);
|
||||
|
||||
// Seed the random number generater with your own seed so can set up
|
||||
// repeatable randomization.
|
||||
void sg_srandom( unsigned int seed );
|
||||
|
||||
// return a random number between [0.0, 1.0)
|
||||
double fg_random(void);
|
||||
double sg_random(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -44,6 +48,6 @@ double fg_random(void);
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _FG_RANDOM_H
|
||||
#endif // _SG_RANDOM_H
|
||||
|
||||
|
||||
+51
-8
@@ -30,10 +30,54 @@
|
||||
#include "vector.hxx"
|
||||
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the closest point (p1) on the line
|
||||
void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d ) {
|
||||
|
||||
sgVec3 u, u1;
|
||||
|
||||
// u = p - p0
|
||||
sgSubVec3(u, p, p0);
|
||||
|
||||
// calculate the projection, u1, of u along d.
|
||||
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
|
||||
sgScaleVec3( u1, d, sgScalarProductVec3(u,d) / sgScalarProductVec3(d,d) );
|
||||
|
||||
// calculate the point p1 along the line that is closest to p
|
||||
// p0 = p1 + u1
|
||||
sgAddVec3(p1, p0, u1);
|
||||
}
|
||||
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the closest point (p1) on the line
|
||||
void sgdClosestPointToLine( sgdVec3 p1, const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d ) {
|
||||
|
||||
sgdVec3 u, u1;
|
||||
|
||||
// u = p - p0
|
||||
sgdSubVec3(u, p, p0);
|
||||
|
||||
// calculate the projection, u1, of u along d.
|
||||
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
|
||||
double ud = sgdScalarProductVec3(u, d);
|
||||
double dd = sgdScalarProductVec3(d, d);
|
||||
double tmp = ud / dd;
|
||||
|
||||
sgdScaleVec3(u1, d, tmp);;
|
||||
|
||||
// calculate the point p1 along the line that is closest to p
|
||||
// p0 = p1 + u1
|
||||
sgdAddVec3(p1, p0, u1);
|
||||
}
|
||||
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance (squared) from the point to the line
|
||||
double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d ) {
|
||||
double sgClosestPointToLineDistSquared( const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d ) {
|
||||
|
||||
sgVec3 u, u1, v;
|
||||
|
||||
@@ -54,20 +98,19 @@ double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance (squared) from the point to the line
|
||||
double sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d ) {
|
||||
double sgdClosestPointToLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d ) {
|
||||
|
||||
sgdVec3 u, u1, v;
|
||||
double ud, dd, tmp;
|
||||
|
||||
// u = p - p0
|
||||
sgdSubVec3(u, p, p0);
|
||||
|
||||
// calculate the projection, u1, of u along d.
|
||||
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
|
||||
ud = sgdScalarProductVec3(u, d);
|
||||
dd = sgdScalarProductVec3(d, d);
|
||||
tmp = ud / dd;
|
||||
double ud = sgdScalarProductVec3(u, d);
|
||||
double dd = sgdScalarProductVec3(d, d);
|
||||
double tmp = ud / dd;
|
||||
|
||||
sgdScaleVec3(u1, d, tmp);;
|
||||
|
||||
|
||||
+15
-5
@@ -93,14 +93,24 @@ inline void sgCopyNegateVec4( sgVec4 dst, sgVec4 src )
|
||||
}
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance (squared) from the point to the line
|
||||
double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d );
|
||||
// find the closest point (p1) on the line
|
||||
void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d );
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the closest point (p1) on the line
|
||||
void sgdClosestPointToLine( sgdVec3 p1, const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d );
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance (squared) from the point to the line
|
||||
double sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d );
|
||||
double sgClosestPointToLineDistSquared( const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d );
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance (squared) from the point to the line
|
||||
double sgdClosestPointToLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d );
|
||||
|
||||
// This is same as
|
||||
// sgMakeMatTrans4( sgMat4 sgTrans, sgVec3 trans )
|
||||
|
||||
@@ -9,4 +9,4 @@ libsgmetar_a_SOURCES = \
|
||||
MetarStation.cpp MetarStation.h \
|
||||
Prtdmetr.cpp Stspack2.cpp Stspack3.cpp
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -86,10 +86,10 @@ CMetarStation::CMetarStation(
|
||||
double ualtitude = atoi( s ) * FEET_TO_METER;
|
||||
Point3D p( longitude, latitude, altitude+EQUATORIAL_RADIUS_M );
|
||||
m_locationPolar = p;
|
||||
m_locationCart = fgPolarToCart3d( p );
|
||||
m_locationCart = sgPolarToCart3d( p );
|
||||
Point3D up( ulongitude, ulatitude, ualtitude+EQUATORIAL_RADIUS_M );
|
||||
m_upperLocationPolar = up;
|
||||
m_upperLocationCart = fgPolarToCart3d( up );
|
||||
m_upperLocationCart = sgPolarToCart3d( up );
|
||||
s = t;
|
||||
m_pFlag = s[0];
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ includedir = @includedir@/misc
|
||||
if HAVE_ZLIB
|
||||
ZLIB_INCL =
|
||||
else
|
||||
ZLIB_INCL = -I$(top_builddir)/src/zlib
|
||||
ZLIB_INCL = -I$(top_srcdir)/src/zlib
|
||||
endif
|
||||
|
||||
lib_LIBRARIES = libsgmisc.a
|
||||
@@ -26,4 +26,4 @@ libsgmisc_a_SOURCES = \
|
||||
texcoord.cxx \
|
||||
zfstream.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir) $(ZLIB_INCL)
|
||||
INCLUDES += -I$(top_srcdir) $(ZLIB_INCL)
|
||||
|
||||
+146
-32
@@ -264,7 +264,7 @@ SGValue::getBoolValue () const
|
||||
return (getRawDouble() == 0.0 ? false : true);
|
||||
case UNKNOWN:
|
||||
case STRING:
|
||||
return ((getRawString() == "false" || getIntValue() == 0) ? false : true);
|
||||
return ((getRawString() == "true" || getIntValue() != 0) ? true : false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -389,12 +389,24 @@ SGValue::getStringValue () const
|
||||
bool
|
||||
SGValue::setBoolValue (bool value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == BOOL) {
|
||||
_type = BOOL;
|
||||
if (_type == UNKNOWN)
|
||||
_type = INT;
|
||||
switch (_type) {
|
||||
case BOOL:
|
||||
return setRawBool(value);
|
||||
} else {
|
||||
return false;
|
||||
case INT:
|
||||
return setRawInt((int)value);
|
||||
case FLOAT:
|
||||
return setRawFloat((float)value);
|
||||
case DOUBLE:
|
||||
return setRawDouble((double)value);
|
||||
case STRING:
|
||||
if (value)
|
||||
return setRawString("true");
|
||||
else
|
||||
return setRawString("false");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -406,12 +418,26 @@ SGValue::setBoolValue (bool value)
|
||||
bool
|
||||
SGValue::setIntValue (int value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == INT) {
|
||||
if (_type == UNKNOWN)
|
||||
_type = INT;
|
||||
switch (_type) {
|
||||
case BOOL:
|
||||
if (value == 0)
|
||||
return setRawBool(false);
|
||||
else
|
||||
return setRawBool(true);
|
||||
case INT:
|
||||
return setRawInt(value);
|
||||
} else {
|
||||
return false;
|
||||
case FLOAT:
|
||||
return setRawFloat((float)value);
|
||||
case DOUBLE:
|
||||
return setRawDouble((double)value);
|
||||
case STRING:
|
||||
char buf[128];
|
||||
sprintf(buf, "%d", value);
|
||||
return setRawString(buf);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,12 +449,26 @@ SGValue::setIntValue (int value)
|
||||
bool
|
||||
SGValue::setFloatValue (float value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == FLOAT) {
|
||||
if (_type == UNKNOWN)
|
||||
_type = FLOAT;
|
||||
switch (_type) {
|
||||
case BOOL:
|
||||
if (value == 0.0)
|
||||
return setRawBool(false);
|
||||
else
|
||||
return setRawBool(true);
|
||||
case INT:
|
||||
return setRawInt((int)value);
|
||||
case FLOAT:
|
||||
return setRawFloat(value);
|
||||
} else {
|
||||
return false;
|
||||
case DOUBLE:
|
||||
return setRawDouble((double)value);
|
||||
case STRING:
|
||||
char buf[128];
|
||||
sprintf(buf, "%f", value);
|
||||
return setRawString(buf);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -440,12 +480,26 @@ SGValue::setFloatValue (float value)
|
||||
bool
|
||||
SGValue::setDoubleValue (double value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == DOUBLE) {
|
||||
if (_type == UNKNOWN)
|
||||
_type = DOUBLE;
|
||||
switch (_type) {
|
||||
case BOOL:
|
||||
if (value == 0.0L)
|
||||
return setRawBool(false);
|
||||
else
|
||||
return setRawBool(true);
|
||||
case INT:
|
||||
return setRawInt((int)value);
|
||||
case FLOAT:
|
||||
return setRawFloat((float)value);
|
||||
case DOUBLE:
|
||||
return setRawDouble(value);
|
||||
} else {
|
||||
return false;
|
||||
case STRING:
|
||||
char buf[128];
|
||||
sprintf(buf, "%lf", value);
|
||||
return setRawString(buf);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -457,12 +511,25 @@ SGValue::setDoubleValue (double value)
|
||||
bool
|
||||
SGValue::setStringValue (const string &value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == STRING) {
|
||||
if (_type == UNKNOWN)
|
||||
_type = STRING;
|
||||
|
||||
switch (_type) {
|
||||
case BOOL:
|
||||
if (value == "true" || atoi(value.c_str()) != 0)
|
||||
return setRawBool(true);
|
||||
else
|
||||
return setRawBool(false);
|
||||
case INT:
|
||||
return setRawInt(atoi(value.c_str()));
|
||||
case FLOAT:
|
||||
return setRawFloat(atof(value.c_str()));
|
||||
case DOUBLE:
|
||||
return setRawDouble(atof(value.c_str()));
|
||||
case STRING:
|
||||
return setRawString(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -474,11 +541,23 @@ SGValue::setStringValue (const string &value)
|
||||
bool
|
||||
SGValue::setUnknownValue (const string &value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == STRING) {
|
||||
switch (_type) {
|
||||
case BOOL:
|
||||
if (value == "true" || atoi(value.c_str()) != 0)
|
||||
return setRawBool(true);
|
||||
else
|
||||
return setRawBool(false);
|
||||
case INT:
|
||||
return setRawInt(atoi(value.c_str()));
|
||||
case FLOAT:
|
||||
return setRawFloat(atof(value.c_str()));
|
||||
case DOUBLE:
|
||||
return setRawDouble(atof(value.c_str()));
|
||||
case STRING:
|
||||
case UNKNOWN:
|
||||
return setRawString(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -497,7 +576,7 @@ SGValue::tieBool (bool_getter getter, bool_setter setter,
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
if (useDefault && setter)
|
||||
(*setter)(getBoolValue());
|
||||
_tied = true;
|
||||
_type = BOOL;
|
||||
@@ -523,7 +602,7 @@ SGValue::tieInt (int_getter getter, int_setter setter,
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
if (useDefault && setter)
|
||||
(*setter)(getIntValue());
|
||||
_tied = true;
|
||||
_type = INT;
|
||||
@@ -549,7 +628,7 @@ SGValue::tieFloat (float_getter getter, float_setter setter,
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
if (useDefault && setter)
|
||||
(*setter)(getFloatValue());
|
||||
_tied = true;
|
||||
_type = FLOAT;
|
||||
@@ -575,7 +654,7 @@ SGValue::tieDouble (double_getter getter, double_setter setter,
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
if (useDefault && setter)
|
||||
(*setter)(getDoubleValue());
|
||||
_tied = true;
|
||||
_type = DOUBLE;
|
||||
@@ -601,7 +680,7 @@ SGValue::tieString (string_getter getter, string_setter setter,
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
if (useDefault && setter)
|
||||
(*setter)(getStringValue());
|
||||
_tied = true;
|
||||
_type = STRING;
|
||||
@@ -685,6 +764,20 @@ SGPropertyList::~SGPropertyList ()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if a value is present.
|
||||
*/
|
||||
bool
|
||||
SGPropertyList::hasValue (const string &name) const
|
||||
{
|
||||
const_iterator el = _props.find(name);
|
||||
if (el == _props.end())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look up the SGValue structure associated with a property.
|
||||
*
|
||||
@@ -700,7 +793,7 @@ SGPropertyList::getValue (const string &name, bool create)
|
||||
if (!create)
|
||||
return 0;
|
||||
else {
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Creating new property '" << name << '\'');
|
||||
FG_LOG(FG_GENERAL, FG_DEBUG, "Creating new property '" << name << '\'');
|
||||
if (name.size() == 0 ||
|
||||
name[0] != '/' ||
|
||||
name[name.size()-1] == '/' ||
|
||||
@@ -916,7 +1009,8 @@ SGPropertyList::tieBool (const string &name,
|
||||
bool_setter setter,
|
||||
bool useDefault)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying bool property '" << name << '\'');
|
||||
FG_LOG(FG_GENERAL, FG_DEBUG, "Tying bool property '" << name << '\'');
|
||||
useDefault = useDefault && hasValue(name);
|
||||
return getValue(name, true)->tieBool(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
@@ -932,7 +1026,8 @@ SGPropertyList::tieInt (const string &name,
|
||||
int_setter setter,
|
||||
bool useDefault)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying int property '" << name << '\'');
|
||||
FG_LOG(FG_GENERAL, FG_DEBUG, "Tying int property '" << name << '\'');
|
||||
useDefault = useDefault && hasValue(name);
|
||||
return getValue(name, true)->tieInt(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
@@ -948,7 +1043,8 @@ SGPropertyList::tieFloat (const string &name,
|
||||
float_setter setter,
|
||||
bool useDefault)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying float property '" << name << '\'');
|
||||
FG_LOG(FG_GENERAL, FG_DEBUG, "Tying float property '" << name << '\'');
|
||||
useDefault = useDefault && hasValue(name);
|
||||
return getValue(name, true)->tieFloat(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
@@ -964,7 +1060,8 @@ SGPropertyList::tieDouble (const string &name,
|
||||
double_setter setter,
|
||||
bool useDefault)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying double property '" << name << '\'');
|
||||
FG_LOG(FG_GENERAL, FG_DEBUG, "Tying double property '" << name << '\'');
|
||||
useDefault = useDefault && hasValue(name);
|
||||
return getValue(name, true)->tieDouble(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
@@ -980,7 +1077,8 @@ SGPropertyList::tieString (const string &name,
|
||||
string_setter setter,
|
||||
bool useDefault)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying string property '" << name << '\'');
|
||||
FG_LOG(FG_GENERAL, FG_DEBUG, "Tying string property '" << name << '\'');
|
||||
useDefault = useDefault && hasValue(name);
|
||||
return getValue(name, true)->tieString(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
@@ -993,7 +1091,7 @@ SGPropertyList::tieString (const string &name,
|
||||
bool
|
||||
SGPropertyList::untie (const string &name)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Untying property '" << name << '\'');
|
||||
FG_LOG(FG_GENERAL, FG_DEBUG, "Untying property '" << name << '\'');
|
||||
return getValue(name, true)->untie();
|
||||
}
|
||||
|
||||
@@ -1198,6 +1296,22 @@ SGPropertyNode::getSubNode (const string &subpath) const
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the specified subpath has a value.
|
||||
*/
|
||||
bool
|
||||
SGPropertyNode::hasValue (const string &subpath) const
|
||||
{
|
||||
if (_props == 0)
|
||||
return false;
|
||||
|
||||
if (subpath.size() == 0)
|
||||
return _props->hasValue(_path);
|
||||
else
|
||||
return _props->hasValue(_path + string("/") + subpath);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the value of the current node.
|
||||
*
|
||||
|
||||
@@ -261,6 +261,8 @@ public:
|
||||
virtual const_iterator begin () const { return _props.begin(); }
|
||||
virtual const_iterator end () const { return _props.end(); }
|
||||
|
||||
virtual bool hasValue (const string &name) const;
|
||||
|
||||
virtual SGValue * getValue (const string &name, bool create = false);
|
||||
virtual const SGValue * getValue (const string &name) const;
|
||||
|
||||
@@ -374,6 +376,9 @@ public:
|
||||
virtual SGPropertyNode &getChild (int n) const;
|
||||
virtual SGPropertyNode &getSubNode (const string &subpath) const;
|
||||
|
||||
// Check for a value.
|
||||
virtual bool hasValue (const string &subpath = "") const;
|
||||
|
||||
// Get values directly.
|
||||
virtual SGValue * getValue (const string &subpath = "");
|
||||
virtual bool getBoolValue (const string &subpath = "",
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h> // strcmp()
|
||||
#include <stdlib.h> // atof() atoi()
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/xml/easyxml.hxx>
|
||||
|
||||
@@ -13,11 +16,11 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::istream;
|
||||
using std::ifstream;
|
||||
using std::ostream;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
FG_USING_STD(ofstream);
|
||||
FG_USING_STD(ifstream);
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(vector);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -264,6 +267,8 @@ getTypeName (SGValue::Type type)
|
||||
case SGValue::STRING:
|
||||
return "string";
|
||||
}
|
||||
|
||||
return "unknown"; // avoid a compiler warning
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +278,7 @@ getTypeName (SGValue::Type type)
|
||||
static void
|
||||
writeData (ostream &output, const string &data)
|
||||
{
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
for (int i = 0; i < (int)data.size(); i++) {
|
||||
switch (data[i]) {
|
||||
case '&':
|
||||
output << "&";
|
||||
@@ -329,6 +334,8 @@ writeNode (ostream &output, SGPropertyNode node, int indent)
|
||||
doIndent(output, indent);
|
||||
output << "</" << name << '>' << endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -344,6 +351,8 @@ writePropertyList (ostream &output, const SGPropertyList * props)
|
||||
}
|
||||
|
||||
output << "</PropertyList>" << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
+121
-6
@@ -22,12 +22,130 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
/* The following is an explanation of our somewhat conveluted and
|
||||
tricky texture scaling/offset scheme:
|
||||
|
||||
MAX_TEX_COORD is a value I arrived at by trial and error for my
|
||||
voodoo2/3 video card. If you use texture coordinates that are too
|
||||
big, you quickly start getting into round off problems and the texture
|
||||
jumps and moves relative to the polygon.
|
||||
|
||||
The point of all of this code is that I wanted to be able to define
|
||||
this size in meters of a texture and have it be applied seamlessly to
|
||||
the terrain. I wanted to be able to change the defined size (in
|
||||
meters) of textures at run time. In other words I want to be able to
|
||||
scale the textures at run time and still have them seamlessly tile
|
||||
together across fans.
|
||||
|
||||
The problem is that I have to pregenerate all the texture coordinates
|
||||
when I create the scenery, and I didn't want to burn CPU doing this
|
||||
again when I load the scenery at run time.
|
||||
|
||||
It ended up taking me a lot of thought, a lot of trial and error, and
|
||||
a lot of fiddling around to come up with a scheme that worked.
|
||||
|
||||
----------
|
||||
|
||||
Ok, so think about what needs to be done to have the texture tile
|
||||
across a series of triangles and fans ...
|
||||
|
||||
Basically you want to use some function of lon/lat mod your max
|
||||
texture coordinate size to calculate the texture coordinate of each
|
||||
vertex. This should result in nice tiling across distinct triangles
|
||||
and fans.
|
||||
|
||||
Pretend our MAX_TEX_COORD = 4.0 and half of this is 2.0
|
||||
|
||||
Imagine the following two adjacent polygons with the "X" component of
|
||||
the initial texture coordinate based on longitude (Note they are drawn
|
||||
spaced apart, but in reality the two polygons are adjacent):
|
||||
|
||||
7.0 8.6 8.6 9.0
|
||||
*-----* *------*
|
||||
| | | |
|
||||
|
||||
Now, this exceeds our MAX_TEX_COORD of 4.0 so we have to scale these
|
||||
texture coordinates by some integer value. Let's say we always want
|
||||
to minimize the tex coordinates to minimize rounding error so we will
|
||||
offset the first polygon by 7.0 and the second by 8.0:
|
||||
|
||||
0.0 --- 1.6 and 0.6 --- 1.0
|
||||
|
||||
Our tiling is maintianed becuase the coordinates are continous (mod
|
||||
1.0) and we still get the double repeat across both polygons.
|
||||
|
||||
We want to be able to scale these values by an arbitrary constant and
|
||||
still have proper tiling.
|
||||
|
||||
Let's try doubling the coordinates:
|
||||
|
||||
0.0 --- 3.2 and 1.2 --- 2.0
|
||||
|
||||
Everything still tiles nicely (because the coordinates are continuous
|
||||
mod 1.0) and the texture is now repeated 4x across the two polygons.
|
||||
Before it was repeated 2x.
|
||||
|
||||
Let's try halving the coordinates:
|
||||
|
||||
0.0 --- 0.8 and 0.3 --- 0.5
|
||||
|
||||
Ooop! We lost continuity in texture coordinate space ... no we will
|
||||
have a visual discontinuity in the texture tiling!
|
||||
|
||||
Ok, so we need some other scheme to keep our texture coordinates
|
||||
smaller than MAX_TEX_COORD that preserves continuity in texture
|
||||
space. <Deep breath> let's try the scheme that I have coded up that
|
||||
you are asking about ... <fingers crossed> :-)
|
||||
|
||||
Going way back to the top before we shifted the texture coordinates.
|
||||
tmin for the first polygon is 7.0, this is then adjusted to:
|
||||
|
||||
(int)(tmin.x() / HALF_MAX_TEX_COORD) ) * HALF_MAX_TEX_COORD
|
||||
|
||||
= (int)(7.0/2.0) * 2.0 = 3.0 * 2.0 = 6.0
|
||||
|
||||
The two texture coordinates are offset by 6.0 which yields 1.0 -- 2.6
|
||||
|
||||
tmin for the second polygon is 8.6 which is adjusted to:
|
||||
|
||||
(int)(tmin.x() / HALF_MAX_TEX_COORD) ) * HALF_MAX_TEX_COORD
|
||||
= (int)( 8.6 / 2.0 ) * 2.0 = 4.0 * 2.0 = 8.0
|
||||
|
||||
The offset for the second polygon is 8.0 which yields 0.6 --- 1.0
|
||||
|
||||
So now we have:
|
||||
|
||||
1.0 --- 2.6 and 0.6 --- 1.0
|
||||
|
||||
This still tiles nicely and strethes our texture across completely, so
|
||||
far we haven't done any damage.
|
||||
|
||||
Now let's double the coordinates:
|
||||
|
||||
2.0 --- 5.2 and 1.2 --- 2.0
|
||||
|
||||
The texture is repeated 4x as it should be and is still continuous.
|
||||
|
||||
How about halfing the coordinates. This is where the first scheme
|
||||
broke down. Halving the coordinates yields
|
||||
|
||||
0.5 --- 1.3 and 0.3 --- 0.5
|
||||
|
||||
Woohoo, we still have texture space continuity (mod 1.0) and the
|
||||
texture is repeated 1x.
|
||||
|
||||
Note, it took me almost as long to re-figure this out and write this
|
||||
explanation as it did to figure out the scheme originally. I better
|
||||
enter this in the official comments in case I forget again. :-)
|
||||
|
||||
*/
|
||||
|
||||
#include "texcoord.hxx"
|
||||
|
||||
|
||||
#define FG_STANDARD_TEXTURE_DIMENSION 1000.0 // meters
|
||||
#define MAX_TEX_COORD 8.0
|
||||
#define HALF_MAX_TEX_COORD ( MAX_TEX_COORD / 2.0 )
|
||||
#define HALF_MAX_TEX_COORD ( MAX_TEX_COORD * 0.5 )
|
||||
|
||||
|
||||
// return the basic unshifted/unmoded texture coordinate for a lat/lon
|
||||
@@ -37,7 +155,7 @@ inline Point3D basic_tex_coord( const Point3D& p,
|
||||
{
|
||||
return Point3D( p.x() * ( degree_width * scale /
|
||||
FG_STANDARD_TEXTURE_DIMENSION ),
|
||||
p.y() * ( degree_width * scale /
|
||||
p.y() * ( degree_height * scale /
|
||||
FG_STANDARD_TEXTURE_DIMENSION ),
|
||||
0.0 );
|
||||
}
|
||||
@@ -45,7 +163,7 @@ inline Point3D basic_tex_coord( const Point3D& p,
|
||||
|
||||
// traverse the specified fan/strip/list of vertices and attempt to
|
||||
// calculate "none stretching" texture coordinates
|
||||
point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
|
||||
point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
|
||||
const int_list& fan, double scale )
|
||||
{
|
||||
// cout << "calculating texture coordinates for a specific fan of size = "
|
||||
@@ -113,14 +231,12 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
|
||||
double dy = fabs( tmax.y() - tmin.y() );
|
||||
// cout << "dx = " << dx << " dy = " << dy << endl;
|
||||
|
||||
bool do_shift = false;
|
||||
// Point3D mod_shift;
|
||||
if ( (dx > HALF_MAX_TEX_COORD) || (dy > HALF_MAX_TEX_COORD) ) {
|
||||
// structure is too big, we'll just have to shift it so that
|
||||
// tmin = (0,0). This messes up subsequent texture scaling,
|
||||
// but is the best we can do.
|
||||
// cout << "SHIFTING" << endl;
|
||||
do_shift = true;
|
||||
if ( tmin.x() < 0 ) {
|
||||
tmin.setx( (double)( (int)tmin.x() - 1 ) );
|
||||
} else {
|
||||
@@ -193,7 +309,6 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
|
||||
t = basic_tex_coord( p, degree_width, degree_height, scale );
|
||||
// cout << "second t = " << t << endl;
|
||||
|
||||
// if ( do_shift ) {
|
||||
adjusted_t = t - tmin;
|
||||
#if 0
|
||||
} else {
|
||||
|
||||
@@ -32,12 +32,12 @@
|
||||
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/math/fg_types.hxx>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
|
||||
// traverse the specified fan/strip/list of vertices and attempt to
|
||||
// calculate "none stretching" texture coordinates
|
||||
point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
|
||||
point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
|
||||
const int_list& fan, double scale = 1.0 );
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
includedir = @includedir@/route
|
||||
|
||||
lib_LIBRARIES = libsgroute.a
|
||||
|
||||
include_HEADERS = route.hxx waypoint.hxx
|
||||
|
||||
libsgroute_a_SOURCES = \
|
||||
route.cxx \
|
||||
waypoint.cxx
|
||||
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
noinst_PROGRAMS = waytest routetest
|
||||
|
||||
waytest_SOURCES = waytest.cxx
|
||||
|
||||
waytest_LDADD = \
|
||||
$(top_builddir)/simgear/route/libsgroute.a \
|
||||
$(top_builddir)/simgear/math/libsgmath.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
|
||||
routetest_SOURCES = routetest.cxx
|
||||
|
||||
routetest_LDADD = \
|
||||
$(top_builddir)/simgear/route/libsgroute.a \
|
||||
$(top_builddir)/simgear/math/libsgmath.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
@@ -0,0 +1,70 @@
|
||||
// route.cxx -- Class to manage a list of waypoints (route)
|
||||
//
|
||||
// Written by Curtis Olson, started October 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@hfrl.umn.edu
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/math/vector.hxx>
|
||||
|
||||
#include "route.hxx"
|
||||
|
||||
|
||||
// constructor
|
||||
SGRoute::SGRoute() {
|
||||
route.clear();
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
SGRoute::~SGRoute() {
|
||||
}
|
||||
|
||||
|
||||
// Calculate perpendicular distance from the current route segment
|
||||
// This routine assumes all points are laying on a flat plane and
|
||||
// ignores the altitude (or Z) dimension. For best results, use with
|
||||
// CARTESIAN way points.
|
||||
double SGRoute::distance_off_route( double x, double y ) const {
|
||||
if ( current_wp > 0 ) {
|
||||
int n0 = current_wp - 1;
|
||||
int n1 = current_wp;
|
||||
sgdVec3 p, p0, p1, d;
|
||||
sgdSetVec3( p, x, y, 0.0 );
|
||||
sgdSetVec3( p0,
|
||||
route[n0].get_target_lon(), route[n0].get_target_lat(),
|
||||
0.0 );
|
||||
sgdSetVec3( p1,
|
||||
route[n1].get_target_lon(), route[n1].get_target_lat(),
|
||||
0.0 );
|
||||
sgdSubVec3( d, p0, p1 );
|
||||
|
||||
return sqrt( sgdClosestPointToLineDistSquared( p, p0, d ) );
|
||||
|
||||
} else {
|
||||
// We are tracking the first waypoint so there is no route
|
||||
// segment. If you add the current location as the first
|
||||
// waypoint and the actual waypoint as the second, then we
|
||||
// will have a route segment and calculate distance from it.
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// route.hxx -- Class to manage a list of waypoints (route)
|
||||
//
|
||||
// Written by Curtis Olson, started October 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@hfrl.umn.edu
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _ROUTE_HXX
|
||||
#define _ROUTE_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(vector);
|
||||
|
||||
#include <simgear/route/waypoint.hxx>
|
||||
|
||||
|
||||
class SGRoute {
|
||||
|
||||
private:
|
||||
|
||||
typedef vector < SGWayPoint > route_list;
|
||||
route_list route;
|
||||
int current_wp;
|
||||
|
||||
public:
|
||||
|
||||
SGRoute();
|
||||
~SGRoute();
|
||||
|
||||
// clear the entire route
|
||||
inline void clear() {
|
||||
route.clear();
|
||||
current_wp = 0;
|
||||
}
|
||||
|
||||
// add a waypoint
|
||||
inline void add_waypoint( const SGWayPoint &wp ) {
|
||||
route.push_back( wp );
|
||||
|
||||
int size = route.size();
|
||||
if ( size > 1 ) {
|
||||
SGWayPoint next_to_last = route[ size - 2 ];
|
||||
double tmpd, tmpc;
|
||||
wp.CourseAndDistance( next_to_last, &tmpc, &tmpd );
|
||||
route[size - 1].set_distance( tmpd );
|
||||
}
|
||||
}
|
||||
|
||||
// get the number of waypoints
|
||||
inline int size() const { return route.size(); }
|
||||
|
||||
// get the front waypoint
|
||||
inline SGWayPoint get_first() const {
|
||||
if ( route.size() ) {
|
||||
return route[0];
|
||||
} else {
|
||||
return SGWayPoint( 0.0, 0.0, 0.0, SGWayPoint::WGS84, "invalid" );
|
||||
}
|
||||
}
|
||||
|
||||
// get the current waypoint
|
||||
inline SGWayPoint get_current() const {
|
||||
if ( current_wp < (int)route.size() ) {
|
||||
return route[current_wp];
|
||||
} else {
|
||||
return SGWayPoint( 0.0, 0.0, 0.0, SGWayPoint::WGS84, "invalid" );
|
||||
}
|
||||
}
|
||||
|
||||
// set the current waypoint
|
||||
inline void set_current( int n ) {
|
||||
if ( n >= 0 && n < (int)route.size() ) {
|
||||
current_wp = n;
|
||||
}
|
||||
}
|
||||
|
||||
// increment the current waypoint
|
||||
inline void increment_current() {
|
||||
if ( current_wp < (int)route.size() - 1 ) {
|
||||
++current_wp;
|
||||
}
|
||||
}
|
||||
|
||||
// get the nth waypoint
|
||||
inline SGWayPoint get_waypoint( const int n ) const {
|
||||
if ( n < (int)route.size() ) {
|
||||
return route[n];
|
||||
} else {
|
||||
return SGWayPoint( 0.0, 0.0, 0.0, SGWayPoint::WGS84, "invalid" );
|
||||
}
|
||||
}
|
||||
|
||||
// delete the front waypoint
|
||||
inline void delete_first() {
|
||||
if ( route.size() ) {
|
||||
route.erase( route.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate perpendicular distance from the current route segment
|
||||
// This routine assumes all points are laying on a flat plane and
|
||||
// ignores the altitude (or Z) dimension. For best results, use
|
||||
// with CARTESIAN way points.
|
||||
double distance_off_route( double x, double y ) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // _ROUTE_HXX
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include "route.hxx"
|
||||
#include "waypoint.hxx"
|
||||
|
||||
int main() {
|
||||
SGRoute route;
|
||||
|
||||
route.add_waypoint( SGWayPoint(0, 0, 0, SGWayPoint::CARTESIAN, "Start") );
|
||||
route.add_waypoint( SGWayPoint(1, 0, 0, SGWayPoint::CARTESIAN, "1") );
|
||||
route.add_waypoint( SGWayPoint(2, 0, 0, SGWayPoint::CARTESIAN, "2") );
|
||||
route.add_waypoint( SGWayPoint(2, 2, 0, SGWayPoint::CARTESIAN, "3") );
|
||||
route.add_waypoint( SGWayPoint(4, 2, 0, SGWayPoint::CARTESIAN, "4") );
|
||||
|
||||
route.set_current( 1 );
|
||||
|
||||
cout << "( 0.5, 0 ) = " << route.distance_off_route( 0.5, 0 ) << endl;
|
||||
cout << "( 0.5, 1 ) = " << route.distance_off_route( 0.5, 1 ) << endl;
|
||||
cout << "( 0.5, -1 ) = " << route.distance_off_route( 0.5, 1 ) << endl;
|
||||
|
||||
route.set_current( 3 );
|
||||
|
||||
cout << "( 2, 4 ) = " << route.distance_off_route( 2, 4 ) << endl;
|
||||
cout << "( 2.5, 4 ) = " << route.distance_off_route( 2.5, 4 ) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// waypoint.cxx -- Class to hold data and return info relating to a waypoint
|
||||
//
|
||||
// Written by Curtis Olson, started September 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@hfrl.umn.edu
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
#include "waypoint.hxx"
|
||||
|
||||
|
||||
// Constructor
|
||||
SGWayPoint::SGWayPoint( const double lon, const double lat, const double alt,
|
||||
const modetype m, const string s ) {
|
||||
target_lon = lon;
|
||||
target_lat = lat;
|
||||
target_alt = alt;
|
||||
mode = m;
|
||||
id = s;
|
||||
}
|
||||
|
||||
|
||||
SGWayPoint::SGWayPoint() {
|
||||
SGWayPoint( 0.0, 0.0, 0.0, WGS84, "" );
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
SGWayPoint::~SGWayPoint() {
|
||||
}
|
||||
|
||||
|
||||
// Calculate course and distances. For WGS84 and SPHERICAL
|
||||
// coordinates lat, lon, and course are in degrees, alt and distance
|
||||
// are in meters. For CARTESIAN coordinates x = lon, y = lat. Course
|
||||
// is in degrees and distance is in what ever units x and y are in.
|
||||
void SGWayPoint::CourseAndDistance( const double cur_lon,
|
||||
const double cur_lat,
|
||||
const double cur_alt,
|
||||
double *course, double *distance ) const {
|
||||
if ( mode == WGS84 ) {
|
||||
double reverse;
|
||||
geo_inverse_wgs_84( cur_alt, cur_lat, cur_lon, target_lat, target_lon,
|
||||
course, &reverse, distance );
|
||||
} else if ( mode == SPHERICAL ) {
|
||||
Point3D current( cur_lon * DEG_TO_RAD, cur_lat * DEG_TO_RAD, 0.0 );
|
||||
Point3D target( target_lon * DEG_TO_RAD, target_lat * DEG_TO_RAD, 0.0 );
|
||||
calc_gc_course_dist( current, target, course, distance );
|
||||
*course = 360.0 - *course * RAD_TO_DEG;
|
||||
} else if ( mode == CARTESIAN ) {
|
||||
double dx = target_lon - cur_lon;
|
||||
double dy = target_lat - cur_lat;
|
||||
*course = -atan2( dy, dx ) * RAD_TO_DEG - 90;
|
||||
while ( *course < 0 ) {
|
||||
*course += 360.0;
|
||||
}
|
||||
while ( *course > 360.0 ) {
|
||||
*course -= 360.0;
|
||||
}
|
||||
*distance = sqrt( dx * dx + dy * dy );
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate course and distances between two waypoints
|
||||
void SGWayPoint::CourseAndDistance( const SGWayPoint &wp,
|
||||
double *course, double *distance ) const {
|
||||
CourseAndDistance( wp.get_target_lon(),
|
||||
wp.get_target_lat(),
|
||||
wp.get_target_alt(),
|
||||
course, distance );
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// waypoint.hxx -- Class to hold data and return info relating to a waypoint
|
||||
//
|
||||
// Written by Curtis Olson, started September 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@hfrl.umn.edu
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _WAYPOINT_HXX
|
||||
#define _WAYPOINT_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
|
||||
class SGWayPoint {
|
||||
|
||||
public:
|
||||
|
||||
enum modetype {
|
||||
WGS84 = 0,
|
||||
SPHERICAL = 1,
|
||||
CARTESIAN = 2
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
modetype mode;
|
||||
|
||||
double target_lon;
|
||||
double target_lat;
|
||||
double target_alt;
|
||||
double distance;
|
||||
|
||||
string id;
|
||||
|
||||
public:
|
||||
|
||||
SGWayPoint();
|
||||
SGWayPoint( const double lon, const double lat, const double alt,
|
||||
const modetype m = WGS84, const string s = "" );
|
||||
~SGWayPoint();
|
||||
|
||||
// Calculate course and distances. For WGS84 and SPHERICAL
|
||||
// coordinates lat, lon, and course are in degrees, alt and
|
||||
// distance are in meters. For CARTESIAN coordinates x = lon, y =
|
||||
// lat. Course is in degrees and distance is in what ever units x
|
||||
// and y are in.
|
||||
void CourseAndDistance( const double cur_lon, const double cur_lat,
|
||||
const double cur_alt,
|
||||
double *course, double *distance ) const;
|
||||
|
||||
// Calculate course and distances between two waypoints
|
||||
void CourseAndDistance( const SGWayPoint &wp,
|
||||
double *course, double *distance ) const;
|
||||
|
||||
inline modetype get_mode() const { return mode; }
|
||||
inline double get_target_lon() const { return target_lon; }
|
||||
inline double get_target_lat() const { return target_lat; }
|
||||
inline double get_target_alt() const { return target_alt; }
|
||||
inline double get_distance() const { return distance; }
|
||||
inline string get_id() const { return id; }
|
||||
|
||||
inline void set_distance( double d ) { distance = d; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _WAYPOINT_HXX
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <simgear/constants.h>
|
||||
#include "waypoint.hxx"
|
||||
|
||||
int main() {
|
||||
SGWayPoint a1(-93.216923, 44.880547, 0.0, SGWayPoint::WGS84, "KMSP");
|
||||
SGWayPoint a2(-93.216923, 44.880547, 0.0, SGWayPoint::SPHERICAL, "KMSP");
|
||||
|
||||
// KMSN (Madison)
|
||||
double cur_lon = -89.336939;
|
||||
double cur_lat = 43.139541;
|
||||
double cur_alt = 0.0;
|
||||
|
||||
double course, distance;
|
||||
|
||||
a1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << a1.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << a1.get_id() << " is " << distance * METER_TO_NM
|
||||
<< endl;
|
||||
|
||||
a2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << a2.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << a2.get_id() << " is " << distance * METER_TO_NM
|
||||
<< endl;
|
||||
cout << endl;
|
||||
|
||||
SGWayPoint b1(-88.237037, 43.041038, 0.0, SGWayPoint::WGS84, "KUES");
|
||||
SGWayPoint b2(-88.237037, 43.041038, 0.0, SGWayPoint::SPHERICAL, "KUES");
|
||||
|
||||
b1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << b1.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << b1.get_id() << " is " << distance * METER_TO_NM
|
||||
<< endl;
|
||||
|
||||
b2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << b2.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << b2.get_id() << " is " << distance * METER_TO_NM
|
||||
<< endl;
|
||||
cout << endl;
|
||||
|
||||
cur_lon = 10;
|
||||
cur_lat = 10;
|
||||
|
||||
SGWayPoint c1(-20, 10, 0, SGWayPoint::CARTESIAN, "Due East");
|
||||
c1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << c1.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << c1.get_id() << " is " << distance << endl;
|
||||
|
||||
SGWayPoint c2(20, 20, 0, SGWayPoint::CARTESIAN, "Due SW");
|
||||
c2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << c2.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << c2.get_id() << " is " << distance << endl;
|
||||
|
||||
SGWayPoint c3(20, 0, 0, SGWayPoint::CARTESIAN, "Due NW");
|
||||
c3.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << c3.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << c3.get_id() << " is " << distance << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -9,4 +9,4 @@ libsgscreen_a_SOURCES = \
|
||||
screen-dump.cxx \
|
||||
win32-printer.h
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -14,4 +14,4 @@ testserial_LDADD = \
|
||||
$(top_builddir)/simgear/serial/libsgserial.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -20,4 +20,4 @@ libsgsky_a_SOURCES = \
|
||||
sphere.cxx \
|
||||
stars.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include <simgear/math/fg_random.h>
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
#include <simgear/math/sg_random.h>
|
||||
|
||||
#include "cloud.hxx"
|
||||
|
||||
@@ -70,7 +70,7 @@ void SGCloudLayer::build( double s, double asl, double thickness,
|
||||
|
||||
sgSetVec3( vertex, -size, -size, 0.0f );
|
||||
sgVec2 base;
|
||||
sgSetVec2( base, fg_random(), fg_random() );
|
||||
sgSetVec2( base, sg_random(), sg_random() );
|
||||
sgSetVec2( tc, base[0], base[1] );
|
||||
cl->add( color );
|
||||
vl->add( vertex );
|
||||
|
||||
@@ -42,9 +42,9 @@ FG_USING_STD(string);
|
||||
|
||||
enum SGCloudType {
|
||||
SG_CLOUD_OVERCAST = 0,
|
||||
SG_CLOUD_MOSTLY_CLOUDY = 1,
|
||||
SG_CLOUD_MOSTLY_SUNNY = 2,
|
||||
SG_CLOUD_CIRRUS = 3,
|
||||
SG_CLOUD_MOSTLY_CLOUDY,
|
||||
SG_CLOUD_MOSTLY_SUNNY,
|
||||
SG_CLOUD_CIRRUS
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/fg_random.h>
|
||||
|
||||
#include "dome.hxx"
|
||||
|
||||
@@ -357,11 +356,11 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
|
||||
lower_color[i][j] = fog_color[j] + outer_amt[j];
|
||||
|
||||
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
|
||||
if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
|
||||
if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
|
||||
if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
|
||||
if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
|
||||
if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
|
||||
if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
|
||||
if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; }
|
||||
if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
|
||||
}
|
||||
upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
|
||||
|
||||
@@ -398,11 +397,11 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
|
||||
lower_color[i][j] = fog_color[j] + outer_amt[j];
|
||||
|
||||
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
|
||||
if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
|
||||
if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
|
||||
if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
|
||||
if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
|
||||
if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
|
||||
if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
|
||||
if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; }
|
||||
if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
|
||||
}
|
||||
upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
|
||||
|
||||
@@ -420,8 +419,8 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
|
||||
printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
|
||||
lower_color[i][0], lower_color[i][1], lower_color[i][2],
|
||||
lower_color[i][3]);
|
||||
*/
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
for ( i = 0; i < 12; i++ ) {
|
||||
sgCopyVec4( bottom_color[i], fog_color );
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
@@ -88,7 +90,7 @@ static int sgMoonHaloPreDraw( ssgEntity *e ) {
|
||||
if ( f -> hasState () ) f->getState()->apply() ;
|
||||
|
||||
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT);
|
||||
cout << "push error = " << glGetError() << endl;
|
||||
// cout << "push error = " << glGetError() << endl;
|
||||
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_FOG );
|
||||
@@ -105,7 +107,7 @@ static int sgMoonHaloPostDraw( ssgEntity *e ) {
|
||||
// glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
||||
|
||||
glPopAttrib();
|
||||
cout << "pop error = " << glGetError() << endl;
|
||||
// cout << "pop error = " << glGetError() << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-3
@@ -30,7 +30,7 @@
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include <simgear/math/fg_random.h>
|
||||
#include <simgear/math/sg_random.h>
|
||||
|
||||
#include "sky.hxx"
|
||||
|
||||
@@ -328,11 +328,11 @@ void SGSky::modify_vis( float alt, float time_factor ) {
|
||||
if ( ratio < 1.0 ) {
|
||||
if ( ! in_puff ) {
|
||||
// calc chance of entering cloud puff
|
||||
double rnd = fg_random();
|
||||
double rnd = sg_random();
|
||||
double chance = rnd * rnd * rnd;
|
||||
if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) {
|
||||
in_puff = true;
|
||||
puff_length = fg_random() * 2.0; // up to 2 seconds
|
||||
puff_length = sg_random() * 2.0; // up to 2 seconds
|
||||
puff_progression = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,8 @@
|
||||
|
||||
#include "stars.hxx"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
FG_USING_STD(cout);
|
||||
FG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
|
||||
// Set up star rendering call backs
|
||||
|
||||
@@ -6,6 +6,7 @@ include_HEADERS = \
|
||||
geocoord.h \
|
||||
lowleveltime.h \
|
||||
sg_time.hxx \
|
||||
timestamp.hxx \
|
||||
timezone.h
|
||||
|
||||
libsgtiming_a_SOURCES = \
|
||||
@@ -20,4 +21,4 @@ libsgtiming_a_SOURCES = \
|
||||
# sunpos.cxx sunpos.hxx \
|
||||
# timestamp.hxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -304,7 +304,7 @@ static void fgtzset_internal (int always, const char *tz)
|
||||
/* User specified the empty string; use UTC explicitly. */
|
||||
tz = "Universal";
|
||||
|
||||
#ifdef MACOS
|
||||
#ifdef macintosh
|
||||
/* as you well know, mac paths contain leading colon, this code
|
||||
messes things up.... */
|
||||
#else
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
#define RADHR(x) DEGHR(x*RAD_TO_DEG)
|
||||
|
||||
|
||||
static const double MJD0 = 2415020.0;
|
||||
static const double J2000 = 2451545.0 - MJD0;
|
||||
static const double SIDRATE = 0.9972695677;
|
||||
|
||||
|
||||
SGTime::SGTime( double lon, double lat, const string& root )
|
||||
{
|
||||
FG_LOG( FG_EVENT, FG_INFO, "Initializing Time" );
|
||||
@@ -413,7 +418,7 @@ time_t sgTimeGetGMT(int year, int month, int day, int hour, int min, int sec)
|
||||
# define TIMEZONE_OFFSET_WORKS 1
|
||||
# endif
|
||||
|
||||
long int start = mktime(&mt);
|
||||
time_t start = mktime(&mt);
|
||||
|
||||
FG_LOG( FG_EVENT, FG_DEBUG, "start1 = " << start );
|
||||
// the ctime() call can screw up time progression on some versions
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
// timestamp.hxx -- class for managing a timestamp (seconds & milliseconds.)
|
||||
//
|
||||
// Written by Curtis Olson, started December 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _TIMESTAMP_HXX
|
||||
#define _TIMESTAMP_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <ctime>
|
||||
#else
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIMEB_H
|
||||
# include <sys/timeb.h> // for ftime() and struct timeb
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h> // for gettimeofday()
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h> // for get/setitimer, gettimeofday, struct timeval
|
||||
#endif
|
||||
|
||||
// -dw- want to use metrowerks time.h
|
||||
#ifdef macintosh
|
||||
# include <time.h>
|
||||
# include <timer.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
# if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
|
||||
# define NEAR /* */
|
||||
# define FAR /* */
|
||||
# endif
|
||||
# include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
// MSVC++ 6.0 kuldge - Need forward declaration of friends.
|
||||
class SGTimeStamp;
|
||||
SGTimeStamp operator + (const SGTimeStamp& t, const long& m);
|
||||
long operator - (const SGTimeStamp& a, const SGTimeStamp& b);
|
||||
|
||||
class SGTimeStamp {
|
||||
|
||||
private:
|
||||
|
||||
long seconds;
|
||||
long usec;
|
||||
|
||||
public:
|
||||
|
||||
SGTimeStamp();
|
||||
SGTimeStamp( const long s, const long m );
|
||||
~SGTimeStamp();
|
||||
|
||||
// Set time to current time
|
||||
void stamp();
|
||||
|
||||
SGTimeStamp& operator = ( const SGTimeStamp& t );
|
||||
|
||||
friend SGTimeStamp operator + (const SGTimeStamp& t, const long& m);
|
||||
friend long operator - (const SGTimeStamp& a, const SGTimeStamp& b);
|
||||
|
||||
inline long get_seconds() const { return seconds; }
|
||||
// inline long get_usec() const { return usec; }
|
||||
};
|
||||
|
||||
inline SGTimeStamp::SGTimeStamp() {
|
||||
}
|
||||
|
||||
inline SGTimeStamp::SGTimeStamp( const long s, const long u ) {
|
||||
seconds = s;
|
||||
usec = u;
|
||||
}
|
||||
|
||||
inline SGTimeStamp::~SGTimeStamp() {
|
||||
}
|
||||
|
||||
inline SGTimeStamp& SGTimeStamp::operator = (const SGTimeStamp& t)
|
||||
{
|
||||
seconds = t.seconds;
|
||||
usec = t.usec;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void SGTimeStamp::stamp() {
|
||||
#if defined( WIN32 )
|
||||
unsigned int t;
|
||||
t = timeGetTime();
|
||||
seconds = 0;
|
||||
usec = t * 1000;
|
||||
#elif defined( HAVE_GETTIMEOFDAY )
|
||||
struct timeval current;
|
||||
struct timezone tz;
|
||||
// sg_timestamp currtime;
|
||||
gettimeofday(¤t, &tz);
|
||||
seconds = current.tv_sec;
|
||||
usec = current.tv_usec;
|
||||
#elif defined( HAVE_GETLOCALTIME )
|
||||
SYSTEMTIME current;
|
||||
GetLocalTime(¤t);
|
||||
seconds = current.wSecond;
|
||||
usec = current.wMilliseconds * 1000;
|
||||
#elif defined( HAVE_FTIME )
|
||||
struct timeb current;
|
||||
ftime(¤t);
|
||||
seconds = current.time;
|
||||
usec = current.millitm * 1000;
|
||||
// -dw- uses time manager
|
||||
#elif defined( macintosh )
|
||||
UnsignedWide ms;
|
||||
Microseconds(&ms);
|
||||
|
||||
seconds = ms.lo / 1000000;
|
||||
usec = ms.lo - ( seconds * 1000000 );
|
||||
#else
|
||||
# error Port me
|
||||
#endif
|
||||
}
|
||||
|
||||
// increment the time stamp by the number of microseconds (usec)
|
||||
inline SGTimeStamp operator + (const SGTimeStamp& t, const long& m) {
|
||||
#ifdef WIN32
|
||||
return SGTimeStamp( 0, t.usec + m );
|
||||
#else
|
||||
return SGTimeStamp( t.seconds + ( t.usec + m ) / 1000000,
|
||||
( t.usec + m ) % 1000000 );
|
||||
#endif
|
||||
}
|
||||
|
||||
// difference between time stamps in microseconds (usec)
|
||||
inline long operator - (const SGTimeStamp& a, const SGTimeStamp& b)
|
||||
{
|
||||
#if defined( WIN32 )
|
||||
return a.usec - b.usec;
|
||||
#else
|
||||
return 1000000 * (a.seconds - b.seconds) + (a.usec - b.usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // _TIMESTAMP_HXX
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@ include_HEADERS = xgl.h
|
||||
|
||||
libsgxgl_a_SOURCES = xgl.c xglUtils.c
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
if HAVE_ZLIB
|
||||
ZLIB_INCL =
|
||||
else
|
||||
XLIB_INCL = -I$(top_builddir)/src/zlib
|
||||
XLIB_INCL = -I$(top_srcdir)/src/zlib
|
||||
endif
|
||||
|
||||
lib_LIBRARIES = libsgxml.a
|
||||
@@ -22,4 +22,4 @@ libsgxml_a_SOURCES = \
|
||||
xmltok.h xmltok.c \
|
||||
xmltok_impl.h
|
||||
|
||||
INCLUDES += -I$(top_builddir) $(ZLIB_INCL)
|
||||
INCLUDES += -I$(top_srcdir) $(ZLIB_INCL)
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
// easyxml.cxx - implementation of EasyXML interfaces.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <string.h> // strcmp()
|
||||
|
||||
#include "easyxml.hxx"
|
||||
#include "xmlparse.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user