Compare commits

...
Author SHA1 Message Date
curt 1b129b289c Ready for 0.0.14 release. 2000-12-14 21:21:13 +00:00
curt a89ceb96b9 Tweak ... 2000-12-14 15:10:56 +00:00
curt 9af5f9f094 MacOS tweaks contributed by Darrell Walisser. 2000-12-13 21:12:15 +00:00
curt 6776c2e536 oops again, fixed. 2000-12-13 19:35:32 +00:00
curt 4c3b4219fe Oops, fixed ... :-) 2000-12-13 19:30:57 +00:00
curt a09806bb98 Tweaks to newbucket organization. 2000-12-13 19:18:29 +00:00
curt e175c8cc4d Tweaks to property manager write routine to return true as it should when
the write succeeds.
2000-12-08 15:22:09 +00:00
curt a53faf4565 Updated random interface so we can optionally specify our own seed value. 2000-12-06 19:01:57 +00:00
curt dc653ac46c Removed some previously added debugging output. 2000-12-04 22:24:08 +00:00
curt c544777d37 Minor fix to make the dome always match the fog / horizon color at the
horizon, so we don't see the extreme far tile edges when it is really dark.
2000-12-04 21:31:58 +00:00
curt 93a37df90a Renamed fg_random -> sg_random. 2000-12-04 04:12:33 +00:00
curt 1da02cca4c Added methods to return tile dimension in meters. 2000-12-04 04:11:03 +00:00
curt 4b1d777ad4 Updated some "const" stuff. 2000-12-03 19:32:42 +00:00
curt fb0916be0f Added an explanation of what this code does. 2000-12-01 22:13:41 +00:00
curt 806083cb25 Initial revision. 2000-11-30 17:38:23 +00:00
curt 5ba74e30b8 Reduced debugging output. 2000-10-23 15:10:45 +00:00
curt c39e08cb2a Added a distance off route routine (works best with 2d cartesian coordinates.) 2000-10-23 14:57:29 +00:00
curt e4653be9a1 MSVC++ fixes. 2000-10-19 22:27:27 +00:00
curt cd5765be1e Tweaks to waypoints and routing. Added distance_to field for each waypoint. 2000-10-13 21:32:51 +00:00
curt c481b06451 Added route.[ch]xx which maintains a list of waypoints (i.e. a route)
Added an elevation field to each waypoint.  This can be used by the calling
program however it wishes.
2000-10-11 23:04:09 +00:00
curt 91ba4618e7 Initial revision. 2000-10-10 23:41:25 +00:00
curt fdc5521389 First working revision. 2000-10-10 22:15:11 +00:00
curt e88c915206 A bit of file renaming to avoid problems with MSVC++ 2000-10-10 17:19:17 +00:00
curt 1e60698053 Initial revision. 2000-10-04 21:55:11 +00:00
curt 5702bd7ee8 io changes and tweaks. Working on adding SOCK_STREAM (tcp) support. Still
needs some work, but is basically there.
2000-10-04 20:14:26 +00:00
curt 8eef3eb582 MSVC++ tweaks. 2000-10-02 18:55:26 +00:00
curt 31db353173 Changes from Bernie Bright:
Added '--with-cxx=COMPILER[:flags]' to ./configure in order to set the
compiler and flags.  If this option is omitted then the default compiler
is assumed (ie the current behaviour).  This duplicates the effect of
passing CC, CFLAGS, CXX and CXXFLAGS on the command line to configure
and make.

SimGear/simgear/compiler.h
Initial support for KAI C++ on linux.

SimGear/simgear/ephemeris/celestialBody.[ch]xx
Removed extraneous semicolons.

SimGear/simgear/io/sg_file.cxx
MSVC tidy up.
2000-10-02 18:52:32 +00:00
curt 2c4a0dd998 Updates from David Megginson:
These patches also eliminate the spurious warning messages about not being
able to set values for joystick buttons.
2000-09-30 01:34:46 +00:00
curt 7d7e41dacc Cleaned up a few poluting #defines.
Did some fg -> sg name space updating (lots more to do but we'll get there
  eventually)
2000-09-27 18:00:04 +00:00
curt 453a53b372 Oops! fixed a typo ... 2000-09-26 21:28:46 +00:00
curt ef68d18f64 Renames fg_types.hxx -> sg_types.hxx 2000-09-26 21:03:31 +00:00
curt ded1d2343f Renamed fg_types.hxx -> sg_types.hxx 2000-09-26 21:01:46 +00:00
curt e6241a2f73 Renamed fg_types.hxx -> sg_types.hxx 2000-09-26 20:52:01 +00:00
curt 467254ec66 MSVC socket support added by Bernie Bright. 2000-09-25 17:32:44 +00:00
curt 135e137921 Initial revision. 2000-09-22 19:24:41 +00:00
curt e13a5b57d4 Oops, references to built libs need to be relative to $(top_builddir) 2000-09-20 21:21:13 +00:00
curt f1c00cdd18 #includes based off of srcdir rather than builddir. 2000-09-20 21:14:42 +00:00
curt 8c3de351b0 Use time_t rather than long int as return type for mktime(). 2000-09-18 17:00:16 +00:00
curt 0bcdb7eb70 Ready for 0.0.13 release. 2000-09-14 16:56:13 +00:00
curt a92b71fffc MSVC changes ... 2000-09-13 20:21:39 +00:00
curt 89960ab715 MacOS portability tweaks from Darrell Walisser. 2000-09-13 19:29:01 +00:00
curt 2a369803ae MACOS -> macintosh 2000-09-09 20:53:44 +00:00
curt b0134a377e Added a touch of error checking to the screen dump routine, i.e. don't
die if you can't open the output file.
2000-09-09 13:31:45 +00:00
curt 502c650cd9 Sep. 8, 2000 updates from David Megginson. 2000-09-08 18:34:45 +00:00
curt a1bf8d2229 9/05/2000 updates from David Megginson relating to the property manager and
easyxml support.  This is a bit of simgear side support to facilitate a
configurable instrument panel in flightgear.
2000-09-05 21:38:00 +00:00
curt 25b743bdec Preserve initial "state" by careful use of glPushAttrib() and glPopAttrib()
being careful to manually call getState()->apply() before the glPushAttrib()
so that the ssg state handling mechanism doesn't get derailed accidentally.
2000-08-22 02:40:13 +00:00
curt dbf7db02a2 Tiny bug fix/tweak. 2000-08-08 14:54:09 +00:00
curt 8c998659c6 Missed some files needed in make dist. 2000-08-08 03:21:26 +00:00
curt 4e23b3dff5 Clean up constructor a bit. 2000-08-08 03:20:02 +00:00
curt 159d3c4c6c Restructured the magvar code a bit to make it more usable. 2000-08-07 18:26:35 +00:00
curt 612b5ae0bc Added simgear/xml. 2000-07-27 02:55:47 +00:00
curt 60cbe9c1d4 Initial revision. 2000-07-26 19:17:43 +00:00
curt 4dadd29727 Updates for 0.0.13 2000-07-22 21:34:58 +00:00
113 changed files with 13076 additions and 1215 deletions
+31
View File
@@ -1,3 +1,34 @@
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)
* Then updates to property manager and xml code.
* Update magnetic variation code.
* Sky code now uses glPushAttrib and glPopAttrib so it plays better with
other ssg based apps.
* MacOS tweaks.
* MSVC tweaks.
New in 0.0.12
* July 19, 2000
* Converted project license from GPL to LGPL.
+21
View File
@@ -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])
+21 -1
View File
@@ -6,7 +6,24 @@ dnl $Id$
AC_INIT(simgear/bucket/newbucket.cxx)
dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 0.0.12)
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,17 +268,20 @@ 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 \
simgear/timing/Makefile \
simgear/xgl/Makefile \
simgear/xml/Makefile \
simgear/zlib/Makefile \
)
+2
View File
@@ -33,10 +33,12 @@ SUBDIRS = \
math \
$(METAR_DIRS) \
misc \
route \
screen \
$(SERIAL_DIRS) \
sky \
timing \
xgl \
xml \
$(ZLIB_DIRS)
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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 &&
+20 -1
View File
@@ -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
//
@@ -118,7 +137,7 @@
# define bcopy(from, to, n) memcpy(to, from, n)
// -rp- please use FG_MEM_COPY everywhere !
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
// #define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
// -dw- currently used glut has no game mode stuff
# define GLUT_WRONG_VERSION
+3 -2
View File
@@ -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
+1 -1
View File
@@ -8,4 +8,4 @@ include_HEADERS = debug_types.h logstream.hxx
libsgdebug_a_SOURCES = logstream.cxx
INCLUDES += -I$(top_builddir)
INCLUDES += -I$(top_srcdir)
-2
View File
@@ -49,8 +49,6 @@ FG_USING_STD(endl);
#endif
#ifdef __MWERKS__
# define cerr std::cerr
# define endl std::endl
FG_USING_STD(iostream);
#endif
+5 -5
View File
@@ -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)
+1 -1
View File
@@ -108,7 +108,7 @@ void CelestialBody::updatePosition(double mjd, Star *ourSun)
}
FV = RAD_TO_DEG * acos( tmp );
};
}
/****************************************************************************
* double CelestialBody::sgCalcEccAnom(double M, double e)
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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;
+12 -12
View File
@@ -36,22 +36,22 @@
#include <plib/sg.h>
#include "star.hxx"
#include "moon.hxx"
#include "mercury.hxx"
#include "venus.hxx"
#include "mars.hxx"
#include "jupiter.hxx"
#include "saturn.hxx"
#include "uranus.hxx"
#include "neptune.hxx"
#include "stars.hxx"
#include <simgear/ephemeris/star.hxx>
#include <simgear/ephemeris/moonpos.hxx>
#include <simgear/ephemeris/mercury.hxx>
#include <simgear/ephemeris/venus.hxx>
#include <simgear/ephemeris/mars.hxx>
#include <simgear/ephemeris/jupiter.hxx>
#include <simgear/ephemeris/saturn.hxx>
#include <simgear/ephemeris/uranus.hxx>
#include <simgear/ephemeris/neptune.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();
}
+2 -2
View File
@@ -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
{
+2 -2
View File
@@ -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
{
+2 -2
View File
@@ -25,8 +25,8 @@
#ifndef _MERCURY_HXX_
#define _MERCURY_HXX_
#include "celestialBody.hxx"
#include "star.hxx"
#include <simgear/ephemeris/celestialBody.hxx>
#include <simgear/ephemeris/star.hxx>
class Mercury : 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,16 +22,17 @@
*
* $Id$
**************************************************************************/
#ifndef _MOON_HXX_
#define _MOON_HXX_
#ifndef _MOONPOS_HXX_
#define _MOONPOS_HXX_
#include <simgear/constants.h>
#include "celestialBody.hxx"
#include "star.hxx"
#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_
+2 -2
View File
@@ -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
{
+2 -2
View File
@@ -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 -1
View File
@@ -26,7 +26,7 @@
#define _STAR_HXX_
#include "celestialBody.hxx"
#include <simgear/ephemeris/celestialBody.hxx>
class Star : 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.
//
+2 -2
View File
@@ -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
{
+2 -2
View File
@@ -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
{
+9 -1
View File
@@ -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
+3 -3
View File
@@ -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;
}
+11 -5
View File
@@ -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
View File
@@ -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;
}
+3 -3
View File
@@ -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();
+5 -3
View File
@@ -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 );
}
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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; }
};
+21
View File
@@ -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);
}
}
+4 -2
View File
@@ -4,7 +4,9 @@ lib_LIBRARIES = libsgmagvar.a
include_HEADERS = magvar.hxx
libsgmagvar_a_SOURCES = magvar.cxx
libsgmagvar_a_SOURCES = \
coremag.hxx coremag.cxx \
magvar.cxx
noinst_PROGRAMS = testmagvar
@@ -12,4 +14,4 @@ testmagvar_SOURCES = testmagvar.cxx
testmagvar_LDADD = $(top_builddir)/simgear/magvar/libsgmagvar.a
INCLUDES += -I$(top_builddir)
INCLUDES += -I$(top_srcdir)
+453
View File
@@ -0,0 +1,453 @@
// coremag.cxx -- compute local magnetic variation given position,
// altitude, and date
//
// This is an implementation of the NIMA (formerly DMA) WMM2000
//
// http://www.nima.mil/GandG/ngdc-wmm2000.html
//
// Copyright (C) 2000 Edward A Williams <Ed_Williams@compuserve.com>
//
// Adapted from Excel 3.0 version 3/27/94 EAW
// Recoded in C++ by Starry Chan
// WMM95 added and rearranged in ANSI-C EAW 7/9/95
// Put shell around program and made Borland & GCC compatible EAW 11/22/95
// IGRF95 added 2/96 EAW
// WMM2000 IGR2000 added 2/00 EAW
// Released under GPL 3/26/00 EAW
// Adaptions and modifications for the SimGear project 3/27/2000 CLO
//
// Removed all pow() calls and made static roots[][] arrays to
// save many sqrt() calls on subsequent invocations
// left old code as SGMagVarOrig() for testing purposes
// 3/28/2000 Norman Vine -- nhv@yahoo.com
//
// Put in some bullet-proofing to handle magnetic and geographic poles.
// 3/28/2000 EAW
// The routine uses a spherical harmonic expansion of the magnetic
// potential up to twelfth order, together with its time variation, as
// described in Chapter 4 of "Geomagnetism, Vol 1, Ed. J.A.Jacobs,
// Academic Press (London 1987)". The program first converts geodetic
// coordinates (lat/long on elliptic earth and altitude) to spherical
// geocentric (spherical lat/long and radius) coordinates. Using this,
// the spherical (B_r, B_theta, B_phi) magnetic field components are
// computed from the model. These are finally referred to surface (X, Y,
// Z) coordinates.
//
// Fields are accurate to better than 200nT, variation and dip to
// better than 0.5 degrees, with the exception of the declination near
// the magnetic poles (where it is ill-defined) where the error may reach
// 4 degrees or more.
//
// Variation is undefined at both the geographic and
// magnetic poles, even though the field itself is well-behaved. To
// avoid the routine blowing up, latitude entries corresponding to
// the geographic poles are slightly offset. At the magnetic poles,
// the routine returns zero variation.
//
// 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$
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <simgear/constants.h>
#include "coremag.hxx"
#define max(a,b) (((a) > (b)) ? (a) : (b))
static const double pi = 3.14159265358979;
static const double a = 6378.16; /* major radius (km) IAU66 ellipsoid */
static const double f = 1.0 / 298.25; /* inverse flattening IAU66 ellipsoid */
static const double b = 6378.16 * (1.0 -1.0 / 298.25 );
/* minor radius b=a*(1-f) */
static const double r_0 = 6371.2; /* "mean radius" for spherical harmonic expansion */
static double gnm_wmm2000[13][13] =
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-29616.0, -1722.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-2266.7, 3070.2, 1677.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{1322.4, -2291.5, 1255.9, 724.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{932.1, 786.3, 250.6, -401.5, 106.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-211.9, 351.6, 220.8, -134.5, -168.8, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{73.8, 68.2, 74.1, -163.5, -3.8, 17.1, -85.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{77.4, -73.9, 2.2, 35.7, 7.3, 5.2, 8.4, -1.5, 0.0, 0.0, 0.0, 0.0, 0.0},
{23.3, 7.3, -8.5, -6.6, -16.9, 8.6, 4.9, -7.8, -7.6, 0.0, 0.0, 0.0, 0.0},
{5.7, 8.5, 2.0, -9.8, 7.6, -7.0, -2.0, 9.2, -2.2, -6.6, 0.0, 0.0, 0.0},
{-2.2, -5.7, 1.6, -3.7, -0.6, 4.1, 2.2, 2.2, 4.6, 2.3, 0.1, 0.0, 0.0},
{3.3, -1.1, -2.4, 2.6, -1.3, -1.7, -0.6, 0.4, 0.7, -0.3, 2.3, 4.2, 0.0},
{-1.5, -0.2, -0.3, 0.5, 0.2, 0.9, -1.4, 0.6, -0.6, -1.0, -0.3, 0.3, 0.4},
};
static double hnm_wmm2000[13][13]=
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 5194.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -2484.8, -467.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -224.7, 293.0, -486.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 273.3, -227.9, 120.9, -302.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 42.0, 173.8, -135.0, -38.6, 105.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -17.4, 61.2, 63.2, -62.9, 0.2, 43.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -62.3, -24.5, 8.9, 23.4, 15.0, -27.6, -7.8, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 12.4, -20.8, 8.4, -21.2, 15.5, 9.1, -15.5, -5.4, 0.0, 0.0, 0.0, 0.0},
{0.0, -20.4, 13.9, 12.0, -6.2, -8.6, 9.4, 5.0, -8.4, 3.2, 0.0, 0.0, 0.0},
{0.0, 0.9, -0.7, 3.9, 4.8, -5.3, -1.0, -2.4, 1.3, -2.3, -6.4, 0.0, 0.0},
{0.0, -1.5, 0.7, -1.1, -2.3, 1.3, -0.6, -2.8, -1.6, -0.1, -1.9, 1.4, 0.0},
{0.0, -1.0, 0.7, 2.2, -2.5, -0.2, 0.0, -0.2, 0.0, 0.2, -0.9, -0.2, 1.0},
};
static double gtnm_wmm2000[13][13]=
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{14.7, 11.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-13.6, -0.7, -1.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.3, -4.3, 0.9, -8.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-1.6, 0.9, -7.6, 2.2, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.9, -0.2, -2.5, -2.7, -0.9, 1.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{1.2, 0.2, 1.7, 1.6, -0.1, -0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.4, -0.8, -0.2, 1.1, 0.4, 0.0, -0.2, -0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.3, 0.6, -0.8, 0.3, -0.2, 0.5, 0.0, -0.6, 0.1, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
};
static double htnm_wmm2000[13][13]=
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -20.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -21.5, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 6.4, -1.3, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 2.3, 0.7, 3.7, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 2.1, 2.3, 3.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.3, -1.7, -0.9, -1.0, -0.1, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 1.4, 0.2, 0.7, 0.4, -0.3, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.5, 0.1, -0.2, 0.0, 0.1, -0.1, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
};
static const int nmax = 12;
static double P[13][13];
static double DP[13][13];
static double gnm[13][13];
static double hnm[13][13];
static double sm[13];
static double cm[13];
static double root[13];
static double roots[13][13][2];
/* Convert date to Julian day 1950-2049 */
unsigned long int yymmdd_to_julian_days( int yy, int mm, int dd )
{
unsigned long jd;
yy = (yy < 50) ? (2000 + yy) : (1900 + yy);
jd = dd - 32075L + 1461L * (yy + 4800L + (mm - 14) / 12 ) / 4;
jd = jd + 367L * (mm - 2 - (mm - 14) / 12*12) / 12;
jd = jd - 3 * ((yy + 4900L + (mm - 14) / 12) / 100) / 4;
/* printf("julian date = %d\n", jd ); */
return jd;
}
/*
* return variation (in radians) given geodetic latitude (radians),
* longitude(radians), height (km) and (Julian) date
* N and E lat and long are positive, S and W negative
*/
double calc_magvar( double lat, double lon, double h, long dat, double* field )
{
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
int n,m;
/* reference dates */
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z;
double sinpsi, cospsi, inv_s;
static int been_here = 0;
double sinlat = sin(lat);
double coslat = cos(lat);
/* convert to geocentric coords: */
// sr = sqrt(pow(a*coslat,2.0)+pow(b*sinlat,2.0));
sr = sqrt(a*a*coslat*coslat + b*b*sinlat*sinlat);
/* sr is effective radius */
theta = atan2(coslat * (h*sr + a*a),
sinlat * (h*sr + b*b));
/* theta is geocentric co-latitude */
r = h*h + 2.0*h * sr +
(a*a*a*a - ( a*a*a*a - b*b*b*b ) * sinlat*sinlat ) /
(a*a - (a*a - b*b) * sinlat*sinlat );
r = sqrt(r);
/* r is geocentric radial distance */
c = cos(theta);
s = sin(theta);
/* protect against zero divide at geographic poles */
inv_s = 1.0 / (s + (s == 0.)*1.0e-8);
/* zero out arrays */
for ( n = 0; n <= nmax; n++ ) {
for ( m = 0; m <= n; m++ ) {
P[n][m] = 0;
DP[n][m] = 0;
}
}
/* diagonal elements */
P[0][0] = 1;
P[1][1] = s;
DP[0][0] = 0;
DP[1][1] = c;
P[1][0] = c ;
DP[1][0] = -s;
// these values will not change for subsequent function calls
if( !been_here ) {
for ( n = 2; n <= nmax; n++ ) {
root[n] = sqrt((2.0*n-1) / (2.0*n));
}
for ( m = 0; m <= nmax; m++ ) {
double mm = m*m;
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
roots[m][n][0] = sqrt((n-1)*(n-1) - mm);
roots[m][n][1] = 1.0 / sqrt( n*n - mm);
}
}
been_here = 1;
}
for ( n=2; n <= nmax; n++ ) {
// double root = sqrt((2.0*n-1) / (2.0*n));
P[n][n] = P[n-1][n-1] * s * root[n];
DP[n][n] = (DP[n-1][n-1] * s + P[n-1][n-1] * c) *
root[n];
}
/* lower triangle */
for ( m = 0; m <= nmax; m++ ) {
// double mm = m*m;
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
// double root1 = sqrt((n-1)*(n-1) - mm);
// double root2 = 1.0 / sqrt( n*n - mm);
P[n][m] = (P[n-1][m] * c * (2.0*n-1) -
P[n-2][m] * roots[m][n][0]) *
roots[m][n][1];
DP[n][m] = ((DP[n-1][m] * c - P[n-1][m] * s) *
(2.0*n-1) - DP[n-2][m] * roots[m][n][0]) *
roots[m][n][1];
}
}
/* compute gnm, hnm at dat */
/* WMM2000 */
yearfrac = (dat - date0_wmm2000) / 365.25;
for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
}
}
/* compute sm (sin(m lon) and cm (cos(m lon)) */
for ( m = 0; m <= nmax; m++ ) {
sm[m] = sin(m * lon);
cm[m] = cos(m * lon);
}
/* compute B fields */
B_r = 0.0;
B_theta = 0.0;
B_phi = 0.0;
fn_0 = r_0/r;
fn = fn_0 * fn_0;
for ( n = 1; n <= nmax; n++ ) {
double c1_n=0;
double c2_n=0;
double c3_n=0;
for ( m = 0; m <= n; m++ ) {
double tmp = (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]);
c1_n=c1_n + tmp * P[n][m];
c2_n=c2_n + tmp * DP[n][m];
c3_n=c3_n + m * (gnm[n][m] * sm[m] - hnm[n][m] * cm[m]) * P[n][m];
}
// fn=pow(r_0/r,n+2.0);
fn *= fn_0;
B_r = B_r + (n + 1) * c1_n * fn;
B_theta = B_theta - c2_n * fn;
B_phi = B_phi + c3_n * fn * inv_s;
}
/* Find geodetic field components: */
psi = theta - ((pi / 2.0) - lat);
sinpsi = sin(psi);
cospsi = cos(psi);
X = -B_theta * cospsi - B_r * sinpsi;
Y = B_phi;
Z = B_theta * sinpsi - B_r * cospsi;
field[0]=B_r;
field[1]=B_theta;
field[2]=B_phi;
field[3]=X;
field[4]=Y;
field[5]=Z; /* output fields */
/* find variation in radians */
/* return zero variation at magnetic pole X=Y=0. */
/* E is positive */
return (X != 0. || Y != 0.) ? atan2(Y, X) : (double) 0.;
}
#ifdef TEST_NHV_HACKS
double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
{
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
int n,m;
/* reference dates */
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
double yearfrac,sr,r,theta,c,s,psi,fn,B_r,B_theta,B_phi,X,Y,Z;
/* convert to geocentric coords: */
sr = sqrt(pow(a*cos(lat),2.0)+pow(b*sin(lat),2.0));
/* sr is effective radius */
theta = atan2(cos(lat) * (h * sr + a * a),
sin(lat) * (h * sr + b * b));
/* theta is geocentric co-latitude */
r = h * h + 2.0*h * sr +
(pow(a,4.0) - (pow(a,4.0) - pow(b,4.0)) * pow(sin(lat),2.0)) /
(a * a - (a * a - b * b) * pow(sin(lat),2.0));
r = sqrt(r);
/* r is geocentric radial distance */
c = cos(theta);
s = sin(theta);
/* zero out arrays */
for ( n = 0; n <= nmax; n++ ) {
for ( m = 0; m <= n; m++ ) {
P[n][m] = 0;
DP[n][m] = 0;
}
}
/* diagonal elements */
P[0][0] = 1;
P[1][1] = s;
DP[0][0] = 0;
DP[1][1] = c;
P[1][0] = c ;
DP[1][0] = -s;
for ( n = 2; n <= nmax; n++ ) {
P[n][n] = P[n-1][n-1] * s * sqrt((2.0*n-1) / (2.0*n));
DP[n][n] = (DP[n-1][n-1] * s + P[n-1][n-1] * c) *
sqrt((2.0*n-1) / (2.0*n));
}
/* lower triangle */
for ( m = 0; m <= nmax; m++ ) {
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
P[n][m] = (P[n-1][m] * c * (2.0*n-1) - P[n-2][m] *
sqrt(1.0*(n-1)*(n-1) - m * m)) /
sqrt(1.0* n * n - m * m);
DP[n][m] = ((DP[n-1][m] * c - P[n-1][m] * s) *
(2.0*n-1) - DP[n-2][m] *
sqrt(1.0*(n-1) * (n-1) - m * m)) /
sqrt(1.0* n * n - m * m);
}
}
/* compute gnm, hnm at dat */
/* WMM2000 */
yearfrac = (dat - date0_wmm2000) / 365.25;
for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
}
}
/* compute sm (sin(m lon) and cm (cos(m lon)) */
for ( m = 0; m <= nmax; m++ ) {
sm[m] = sin(m * lon);
cm[m] = cos(m * lon);
}
/* compute B fields */
B_r = 0.0;
B_theta = 0.0;
B_phi = 0.0;
for ( n = 1; n <= nmax; n++ ) {
double c1_n=0;
double c2_n=0;
double c3_n=0;
for ( m = 0; m <= n; m++ ) {
c1_n=c1_n + (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]) * P[n][m];
c2_n=c2_n + (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]) * DP[n][m];
c3_n=c3_n + m * (gnm[n][m] * sm[m] - hnm[n][m] * cm[m]) * P[n][m];
}
fn=pow(r_0/r,n+2.0);
B_r = B_r + (n + 1) * c1_n * fn;
B_theta = B_theta - c2_n * fn;
B_phi = B_phi + c3_n * fn / s;
}
/* Find geodetic field components: */
psi = theta - (pi / 2.0 - lat);
X = -B_theta * cos(psi) - B_r * sin(psi);
Y = B_phi;
Z = B_theta * sin(psi) - B_r * cos(psi);
field[0]=B_r;
field[1]=B_theta;
field[2]=B_phi;
field[3]=X;
field[4]=Y;
field[5]=Z; /* output fields */
/* find variation, leave in radians! */
return atan2(Y, X); /* E is positive */
}
#endif // TEST_NHV_HACKS
+51
View File
@@ -0,0 +1,51 @@
// coremag.hxx -- compute local magnetic variation given position,
// altitude, and date
//
// This is an implimentation of the NIMA WMM 2000
//
// http://www.nima.mil/GandG/ngdc-wmm2000.html
//
// Copyright (C) 2000 Edward A Williams <Ed_Williams@compuserve.com>
//
// Adapted from Excel 3.0 version 3/27/94 EAW
// Recoded in C++ by Starry Chan
// WMM95 added and rearranged in ANSI-C EAW 7/9/95
// Put shell around program and made Borland & GCC compatible EAW 11/22/95
// IGRF95 added 2/96 EAW
// WMM2000 IGR2000 added 2/00 EAW
// Released under GPL 3/26/00 EAW
// Adaptions and modifications for the SimGear project 3/27/2000 CLO
//
// 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_MAGVAR_HXX
#define SG_MAGVAR_HXX
/* Convert date to Julian day 1950-2049 */
unsigned long int yymmdd_to_julian_days( int yy, int mm, int dd );
/* return variation (in degrees) given geodetic latitude (radians), longitude
(radians) ,height (km) and (Julian) date
N and E lat and long are positive, S and W negative
*/
double calc_magvar( double lat, double lon, double h, long dat, double* field );
#endif // SG_MAGVAR_HXX
+30 -444
View File
@@ -1,465 +1,51 @@
// magvar.cxx -- compute local magnetic variation given position,
// altitude, and date
// magvar.cxx -- magnetic variation wrapper class
//
// This is an implementation of the NIMA (formerly DMA) WMM2000
// Written by Curtis Olson, started July 2000.
//
// http://www.nima.mil/GandG/ngdc-wmm2000.html
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
//
// Copyright (C) 2000 Edward A Williams <Ed_Williams@compuserve.com>
// 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.
//
// Adapted from Excel 3.0 version 3/27/94 EAW
// Recoded in C++ by Starry Chan
// WMM95 added and rearranged in ANSI-C EAW 7/9/95
// Put shell around program and made Borland & GCC compatible EAW 11/22/95
// IGRF95 added 2/96 EAW
// WMM2000 IGR2000 added 2/00 EAW
// Released under GPL 3/26/00 EAW
// Adaptions and modifications for the SimGear project 3/27/2000 CLO
//
// Removed all pow() calls and made static roots[][] arrays to
// save many sqrt() calls on subsequent invocations
// left old code as SGMagVarOrig() for testing purposes
// 3/28/2000 Norman Vine -- nhv@yahoo.com
//
// Put in some bullet-proofing to handle magnetic and geographic poles.
// 3/28/2000 EAW
// The routine uses a spherical harmonic expansion of the magnetic
// potential up to twelfth order, together with its time variation, as
// described in Chapter 4 of "Geomagnetism, Vol 1, Ed. J.A.Jacobs,
// Academic Press (London 1987)". The program first converts geodetic
// coordinates (lat/long on elliptic earth and altitude) to spherical
// geocentric (spherical lat/long and radius) coordinates. Using this,
// the spherical (B_r, B_theta, B_phi) magnetic field components are
// computed from the model. These are finally referred to surface (X, Y,
// Z) coordinates.
//
// Fields are accurate to better than 200nT, variation and dip to
// better than 0.5 degrees, with the exception of the declination near
// the magnetic poles (where it is ill-defined) where the error may reach
// 4 degrees or more.
//
// Variation is undefined at both the geographic and
// magnetic poles, even though the field itself is well-behaved. To
// avoid the routine blowing up, latitude entries corresponding to
// the geographic poles are slightly offset. At the magnetic poles,
// the routine returns zero variation.
//
// 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
// 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
// Library General Public License for more details.
// 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.
// 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 <stdio.h>
#include <stdlib.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <math.h>
#include <simgear/misc/fgpath.hxx>
#include <simgear/magvar/magvar.hxx>
#include "coremag.hxx"
#include "magvar.hxx"
#define max(a,b) (((a) > (b)) ? (a) : (b))
SGMagVar::SGMagVar() {
}
static const double pi = 3.14159265358979;
static const double a = 6378.16; /* major radius (km) IAU66 ellipsoid */
static const double f = 1.0 / 298.25; /* inverse flattening IAU66 ellipsoid */
static const double b = 6378.16 * (1.0 -1.0 / 298.25 );
/* minor radius b=a*(1-f) */
static const double r_0 = 6371.2; /* "mean radius" for spherical harmonic expansion */
static double gnm_wmm2000[13][13] =
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-29616.0, -1722.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-2266.7, 3070.2, 1677.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{1322.4, -2291.5, 1255.9, 724.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{932.1, 786.3, 250.6, -401.5, 106.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-211.9, 351.6, 220.8, -134.5, -168.8, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{73.8, 68.2, 74.1, -163.5, -3.8, 17.1, -85.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{77.4, -73.9, 2.2, 35.7, 7.3, 5.2, 8.4, -1.5, 0.0, 0.0, 0.0, 0.0, 0.0},
{23.3, 7.3, -8.5, -6.6, -16.9, 8.6, 4.9, -7.8, -7.6, 0.0, 0.0, 0.0, 0.0},
{5.7, 8.5, 2.0, -9.8, 7.6, -7.0, -2.0, 9.2, -2.2, -6.6, 0.0, 0.0, 0.0},
{-2.2, -5.7, 1.6, -3.7, -0.6, 4.1, 2.2, 2.2, 4.6, 2.3, 0.1, 0.0, 0.0},
{3.3, -1.1, -2.4, 2.6, -1.3, -1.7, -0.6, 0.4, 0.7, -0.3, 2.3, 4.2, 0.0},
{-1.5, -0.2, -0.3, 0.5, 0.2, 0.9, -1.4, 0.6, -0.6, -1.0, -0.3, 0.3, 0.4},
};
static double hnm_wmm2000[13][13]=
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 5194.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -2484.8, -467.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -224.7, 293.0, -486.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 273.3, -227.9, 120.9, -302.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 42.0, 173.8, -135.0, -38.6, 105.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -17.4, 61.2, 63.2, -62.9, 0.2, 43.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -62.3, -24.5, 8.9, 23.4, 15.0, -27.6, -7.8, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 12.4, -20.8, 8.4, -21.2, 15.5, 9.1, -15.5, -5.4, 0.0, 0.0, 0.0, 0.0},
{0.0, -20.4, 13.9, 12.0, -6.2, -8.6, 9.4, 5.0, -8.4, 3.2, 0.0, 0.0, 0.0},
{0.0, 0.9, -0.7, 3.9, 4.8, -5.3, -1.0, -2.4, 1.3, -2.3, -6.4, 0.0, 0.0},
{0.0, -1.5, 0.7, -1.1, -2.3, 1.3, -0.6, -2.8, -1.6, -0.1, -1.9, 1.4, 0.0},
{0.0, -1.0, 0.7, 2.2, -2.5, -0.2, 0.0, -0.2, 0.0, 0.2, -0.9, -0.2, 1.0},
};
static double gtnm_wmm2000[13][13]=
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{14.7, 11.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-13.6, -0.7, -1.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.3, -4.3, 0.9, -8.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-1.6, 0.9, -7.6, 2.2, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.9, -0.2, -2.5, -2.7, -0.9, 1.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{1.2, 0.2, 1.7, 1.6, -0.1, -0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.4, -0.8, -0.2, 1.1, 0.4, 0.0, -0.2, -0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.3, 0.6, -0.8, 0.3, -0.2, 0.5, 0.0, -0.6, 0.1, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
};
static double htnm_wmm2000[13][13]=
{
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -20.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -21.5, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 6.4, -1.3, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 2.3, 0.7, 3.7, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 2.1, 2.3, 3.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.3, -1.7, -0.9, -1.0, -0.1, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 1.4, 0.2, 0.7, 0.4, -0.3, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.5, 0.1, -0.2, 0.0, 0.1, -0.1, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
};
static const int nmax = 12;
static double P[13][13];
static double DP[13][13];
static double gnm[13][13];
static double hnm[13][13];
static double sm[13];
static double cm[13];
static double root[13];
static double roots[13][13][2];
/* Convert date to Julian day 1950-2049 */
unsigned long int yymmdd_to_julian_days( int yy, int mm, int dd )
{
unsigned long jd;
yy = (yy < 50) ? (2000 + yy) : (1900 + yy);
jd = dd - 32075L + 1461L * (yy + 4800L + (mm - 14) / 12 ) / 4;
jd = jd + 367L * (mm - 2 - (mm - 14) / 12*12) / 12;
jd = jd - 3 * ((yy + 4900L + (mm - 14) / 12) / 100) / 4;
/* printf("julian date = %d\n", jd ); */
return jd;
}
/* Convert degrees to radians */
double deg_to_rad( double deg )
{
return deg*pi/180.;
SGMagVar::~SGMagVar() {
}
/* Convert radians to degrees */
double rad_to_deg( double rad )
{
return rad*180./pi;
}
/*
* return variation (in radians) given geodetic latitude (radians),
* longitude(radians), height (km) and (Julian) date
* N and E lat and long are positive, S and W negative
*/
double SGMagVar( double lat, double lon, double h, long dat, double* field )
{
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
int n,m;
/* reference dates */
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z;
double sinpsi, cospsi, inv_s;
static int been_here = 0;
double sinlat = sin(lat);
double coslat = cos(lat);
/* convert to geocentric coords: */
// sr = sqrt(pow(a*coslat,2.0)+pow(b*sinlat,2.0));
sr = sqrt(a*a*coslat*coslat + b*b*sinlat*sinlat);
/* sr is effective radius */
theta = atan2(coslat * (h*sr + a*a),
sinlat * (h*sr + b*b));
/* theta is geocentric co-latitude */
r = h*h + 2.0*h * sr +
(a*a*a*a - ( a*a*a*a - b*b*b*b ) * sinlat*sinlat ) /
(a*a - (a*a - b*b) * sinlat*sinlat );
r = sqrt(r);
/* r is geocentric radial distance */
c = cos(theta);
s = sin(theta);
/* protect against zero divide at geographic poles */
inv_s = 1.0 / (s + (s == 0.)*1.0e-8);
/* zero out arrays */
for ( n = 0; n <= nmax; n++ ) {
for ( m = 0; m <= n; m++ ) {
P[n][m] = 0;
DP[n][m] = 0;
}
}
/* diagonal elements */
P[0][0] = 1;
P[1][1] = s;
DP[0][0] = 0;
DP[1][1] = c;
P[1][0] = c ;
DP[1][0] = -s;
// these values will not change for subsequent function calls
if( !been_here ) {
for ( n = 2; n <= nmax; n++ ) {
root[n] = sqrt((2.0*n-1) / (2.0*n));
}
for ( m = 0; m <= nmax; m++ ) {
double mm = m*m;
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
roots[m][n][0] = sqrt((n-1)*(n-1) - mm);
roots[m][n][1] = 1.0 / sqrt( n*n - mm);
}
}
been_here = 1;
}
for ( n=2; n <= nmax; n++ ) {
// double root = sqrt((2.0*n-1) / (2.0*n));
P[n][n] = P[n-1][n-1] * s * root[n];
DP[n][n] = (DP[n-1][n-1] * s + P[n-1][n-1] * c) *
root[n];
}
/* lower triangle */
for ( m = 0; m <= nmax; m++ ) {
// double mm = m*m;
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
// double root1 = sqrt((n-1)*(n-1) - mm);
// double root2 = 1.0 / sqrt( n*n - mm);
P[n][m] = (P[n-1][m] * c * (2.0*n-1) -
P[n-2][m] * roots[m][n][0]) *
roots[m][n][1];
DP[n][m] = ((DP[n-1][m] * c - P[n-1][m] * s) *
(2.0*n-1) - DP[n-2][m] * roots[m][n][0]) *
roots[m][n][1];
}
}
/* compute gnm, hnm at dat */
/* WMM2000 */
yearfrac = (dat - date0_wmm2000) / 365.25;
for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
}
}
/* compute sm (sin(m lon) and cm (cos(m lon)) */
for ( m = 0; m <= nmax; m++ ) {
sm[m] = sin(m * lon);
cm[m] = cos(m * lon);
}
/* compute B fields */
B_r = 0.0;
B_theta = 0.0;
B_phi = 0.0;
fn_0 = r_0/r;
fn = fn_0 * fn_0;
for ( n = 1; n <= nmax; n++ ) {
double c1_n=0;
double c2_n=0;
double c3_n=0;
for ( m = 0; m <= n; m++ ) {
double tmp = (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]);
c1_n=c1_n + tmp * P[n][m];
c2_n=c2_n + tmp * DP[n][m];
c3_n=c3_n + m * (gnm[n][m] * sm[m] - hnm[n][m] * cm[m]) * P[n][m];
}
// fn=pow(r_0/r,n+2.0);
fn *= fn_0;
B_r = B_r + (n + 1) * c1_n * fn;
B_theta = B_theta - c2_n * fn;
B_phi = B_phi + c3_n * fn * inv_s;
}
/* Find geodetic field components: */
psi = theta - ((pi / 2.0) - lat);
sinpsi = sin(psi);
cospsi = cos(psi);
X = -B_theta * cospsi - B_r * sinpsi;
Y = B_phi;
Z = B_theta * sinpsi - B_r * cospsi;
field[0]=B_r;
field[1]=B_theta;
field[2]=B_phi;
field[3]=X;
field[4]=Y;
field[5]=Z; /* output fields */
/* find variation in radians */
/* return zero variation at magnetic pole X=Y=0. */
/* E is positive */
return (X != 0. || Y != 0.) ? atan2(Y, X) : (double) 0.;
void SGMagVar::update( double lon, double lat, double alt_m, double jd ) {
// Calculate local magnetic variation
double field[6];
// cout << "alt_m = " << alt_m << endl;
magvar = calc_magvar( lat, lon, alt_m / 1000.0, (long)jd, field );
magdip = atan(field[5]/sqrt(field[3]*field[3]+field[4]*field[4]));
}
#ifdef TEST_NHV_HACKS
double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
{
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
int n,m;
/* reference dates */
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
double yearfrac,sr,r,theta,c,s,psi,fn,B_r,B_theta,B_phi,X,Y,Z;
/* convert to geocentric coords: */
sr = sqrt(pow(a*cos(lat),2.0)+pow(b*sin(lat),2.0));
/* sr is effective radius */
theta = atan2(cos(lat) * (h * sr + a * a),
sin(lat) * (h * sr + b * b));
/* theta is geocentric co-latitude */
r = h * h + 2.0*h * sr +
(pow(a,4.0) - (pow(a,4.0) - pow(b,4.0)) * pow(sin(lat),2.0)) /
(a * a - (a * a - b * b) * pow(sin(lat),2.0));
r = sqrt(r);
/* r is geocentric radial distance */
c = cos(theta);
s = sin(theta);
/* zero out arrays */
for ( n = 0; n <= nmax; n++ ) {
for ( m = 0; m <= n; m++ ) {
P[n][m] = 0;
DP[n][m] = 0;
}
}
/* diagonal elements */
P[0][0] = 1;
P[1][1] = s;
DP[0][0] = 0;
DP[1][1] = c;
P[1][0] = c ;
DP[1][0] = -s;
for ( n = 2; n <= nmax; n++ ) {
P[n][n] = P[n-1][n-1] * s * sqrt((2.0*n-1) / (2.0*n));
DP[n][n] = (DP[n-1][n-1] * s + P[n-1][n-1] * c) *
sqrt((2.0*n-1) / (2.0*n));
}
/* lower triangle */
for ( m = 0; m <= nmax; m++ ) {
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
P[n][m] = (P[n-1][m] * c * (2.0*n-1) - P[n-2][m] *
sqrt(1.0*(n-1)*(n-1) - m * m)) /
sqrt(1.0* n * n - m * m);
DP[n][m] = ((DP[n-1][m] * c - P[n-1][m] * s) *
(2.0*n-1) - DP[n-2][m] *
sqrt(1.0*(n-1) * (n-1) - m * m)) /
sqrt(1.0* n * n - m * m);
}
}
/* compute gnm, hnm at dat */
/* WMM2000 */
yearfrac = (dat - date0_wmm2000) / 365.25;
for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
}
}
/* compute sm (sin(m lon) and cm (cos(m lon)) */
for ( m = 0; m <= nmax; m++ ) {
sm[m] = sin(m * lon);
cm[m] = cos(m * lon);
}
/* compute B fields */
B_r = 0.0;
B_theta = 0.0;
B_phi = 0.0;
for ( n = 1; n <= nmax; n++ ) {
double c1_n=0;
double c2_n=0;
double c3_n=0;
for ( m = 0; m <= n; m++ ) {
c1_n=c1_n + (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]) * P[n][m];
c2_n=c2_n + (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]) * DP[n][m];
c3_n=c3_n + m * (gnm[n][m] * sm[m] - hnm[n][m] * cm[m]) * P[n][m];
}
fn=pow(r_0/r,n+2.0);
B_r = B_r + (n + 1) * c1_n * fn;
B_theta = B_theta - c2_n * fn;
B_phi = B_phi + c3_n * fn / s;
}
/* Find geodetic field components: */
psi = theta - (pi / 2.0 - lat);
X = -B_theta * cos(psi) - B_r * sin(psi);
Y = B_phi;
Z = B_theta * sin(psi) - B_r * cos(psi);
field[0]=B_r;
field[1]=B_theta;
field[2]=B_phi;
field[3]=X;
field[4]=Y;
field[5]=Z; /* output fields */
/* find variation, leave in radians! */
return atan2(Y, X); /* E is positive */
}
#endif // TEST_NHV_HACKS
+44 -43
View File
@@ -1,57 +1,58 @@
// magvar.hxx -- compute local magnetic variation given position,
// altitude, and date
// magvar.hxx -- magnetic variation wrapper class
//
// This is an implimentation of the NIMA WMM 2000
// Written by Curtis Olson, started July 2000.
//
// http://www.nima.mil/GandG/ngdc-wmm2000.html
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
//
// Copyright (C) 2000 Edward A Williams <Ed_Williams@compuserve.com>
// 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.
//
// Adapted from Excel 3.0 version 3/27/94 EAW
// Recoded in C++ by Starry Chan
// WMM95 added and rearranged in ANSI-C EAW 7/9/95
// Put shell around program and made Borland & GCC compatible EAW 11/22/95
// IGRF95 added 2/96 EAW
// WMM2000 IGR2000 added 2/00 EAW
// Released under GPL 3/26/00 EAW
// Adaptions and modifications for the SimGear project 3/27/2000 CLO
//
// 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
// 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
// Library General Public License for more details.
// 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.
// 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 SG_MAGVAR_HXX
#define SG_MAGVAR_HXX
#ifndef _MAGVAR_HXX
#define _MAGVAR_HXX
/* Convert date to Julian day 1950-2049 */
unsigned long int yymmdd_to_julian_days( int yy, int mm, int dd );
/* Convert degrees to radians */
double deg_to_rad( double deg );
/* Convert radians to degrees */
double rad_to_deg( double rad );
/* return variation (in degrees) given geodetic latitude (radians), longitude
(radians) ,height (km) and (Julian) date
N and E lat and long are positive, S and W negative
*/
double SGMagVar( double lat, double lon, double h, long dat, double* field );
#ifndef __cplusplus
# error This library requires C++
#endif
#endif // SG_MAGVAR_HXX
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
class SGMagVar {
private:
double magvar;
double magdip;
public:
SGMagVar();
~SGMagVar();
// recalculate the magnetic offset and dip
void update( double lon, double lat, double alt_m, double jd );
double get_magvar() const { return magvar; }
double get_magdip() const { return magdip; }
};
#endif // _LIGHT_HXX
+7 -5
View File
@@ -4,7 +4,9 @@
#include <stdlib.h>
#include <math.h>
#include "magvar.hxx"
#include <simgear/constants.h>
#include "coremag.hxx"
int main(int argc, char *argv[])
@@ -40,15 +42,15 @@ if (argc == 8){
}
var = SGMagVar( deg_to_rad(lat_deg), deg_to_rad(lon_deg), h,
yymmdd_to_julian_days(yy,mm,dd), field );
var = calc_magvar( DEG_TO_RAD * lat_deg, DEG_TO_RAD * lon_deg, h,
yymmdd_to_julian_days(yy,mm,dd), field );
fprintf(stdout,"%6.0lf %6.0lf %6.0lf\n", field[0], field[1], field[2] );
fprintf(stdout,"%6.0lf %6.0lf %6.0lf\n", field[3], field[4], field[5] );
fprintf(stdout,"%6.0lf %6.0lf %6.0lf %4.2lf %4.2lf \n",
field[3],field[4],field[5],
rad_to_deg(atan(field[5]/pow(field[3]*field[3]+field[4]*field[4],0.5))),
rad_to_deg(var));
RAD_TO_DEG * (atan(field[5]/pow(field[3]*field[3]+field[4]*field[4],0.5))),
RAD_TO_DEG * var);
exit(0);
}
+8 -7
View File
@@ -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)
+42
View File
@@ -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
+2
View File
@@ -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
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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 )
+1 -1
View File
@@ -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)
+28 -30
View File
@@ -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];
}
@@ -100,44 +100,42 @@ CMetarStation::CMetarStation(
int CMetarStation::initialize()
{
// Read the list of metar stations, decoding and adding to global list.
// Read the list of metar stations, decoding and adding to global list.
CMetarStation *m;
char buf[256];
CMetarStation *m;
char buf[256];
// Goto the Flight Gear installation directory
// Goto the Flight Gear installation directory
#ifdef TESTPROG
FGPath weatherPath( "/mkv/Build/FlightGear" );
//FGPath weatherPath( "/mkv/Build/FlightGear" );
FGPath weatherPath( ":Data" );
#else
FGPath weatherPath( current_options.get_fg_root() );
#endif
weatherPath.append( "Weather/MetarStations" );
// Open the metar station list
FILE *f = fopen( weatherPath.c_str(), "r" );
weatherPath.append( "Weather" );
weatherPath.append( "MetarStations" );
// Open the metar station list
FILE *f = fopen( weatherPath.c_str(), "r" );
if ( f != NULL )
{
// Read each line, create an instance of a station, and add it to the vector
while ( fgets( buf, 256, f) != NULL && feof( f ) == 0 )
{
//std::cout << buf << std::endl;
m = new CMetarStation( buf );
//m->dump();
METAR_Stations.push_back( m );
}
if ( f != NULL ) {
// Read each line, create an instance of a station, and add it to the vector
while ( fgets( buf, 256, f) != NULL && feof( f ) == 0 ) {
//std::cout << buf << std::endl;
m = new CMetarStation( buf );
//m->dump();
METAR_Stations.push_back( m );
}
// Close the list
fclose( f );
std::cout << METAR_Stations.size() << " Metar stations" << std::endl;
return 1;
}
else
{
std::cout << "Could not open MetarStations file " << std::endl;
return 0;
}
// Close the list
fclose( f );
// std::cout << METAR_Stations.size() << " Metar stations" << std::endl;
return 1;
} else {
// std::cout << "Could not open MetarStations file " << std::endl;
return 0;
}
}
+3 -2
View File
@@ -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
@@ -21,8 +21,9 @@ libsgmisc_a_SOURCES = \
fgpath.cxx \
fgstream.cxx \
props.cxx \
props_io.cxx \
strutils.cxx \
texcoord.cxx \
zfstream.cxx
INCLUDES += -I$(top_builddir) $(ZLIB_INCL)
INCLUDES += -I$(top_srcdir) $(ZLIB_INCL)
+1 -1
View File
@@ -39,7 +39,7 @@
FG_USING_STD(string);
#ifdef MACOS
#ifdef macintosh
# define FG_PATH_SEP ':'
# define FG_BAD_PATH_SEP '/'
#else
+325 -102
View File
@@ -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;
}
@@ -304,8 +304,6 @@ float
SGValue::getFloatValue () const
{
switch (_type) {
case UNKNOWN:
return 0.0;
case BOOL:
return (float)(getRawBool());
case INT:
@@ -314,6 +312,7 @@ SGValue::getFloatValue () const
return getRawFloat();
case DOUBLE:
return (float)(getRawDouble());
case UNKNOWN:
case STRING:
return (float)atof(getRawString().c_str());
}
@@ -330,8 +329,6 @@ double
SGValue::getDoubleValue () const
{
switch (_type) {
case UNKNOWN:
return 0.0;
case BOOL:
return (double)(getRawBool());
case INT:
@@ -340,6 +337,7 @@ SGValue::getDoubleValue () const
return (double)(getRawFloat());
case DOUBLE:
return getRawDouble();
case UNKNOWN:
case STRING:
return atof(getRawString().c_str());
}
@@ -357,8 +355,6 @@ SGValue::getStringValue () const
{
char buf[512];
switch (_type) {
case UNKNOWN:
return getRawString();
case BOOL:
if (getRawBool())
string_val = "true";
@@ -377,6 +373,7 @@ SGValue::getStringValue () const
sprintf(buf, "%f", getRawDouble());
string_val = buf;
return string_val;
case UNKNOWN:
case STRING:
return getRawString();
}
@@ -392,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;
}
@@ -409,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;
}
@@ -426,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;
}
@@ -443,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;
}
@@ -460,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;
}
@@ -477,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;
}
@@ -494,13 +570,13 @@ SGValue::setUnknownValue (const string &value)
* Returns true on success (i.e. the value is not currently tied).
*/
bool
SGValue::tieBool (bool_getter getter, bool_setter setter = 0,
bool useDefault = true)
SGValue::tieBool (bool_getter getter, bool_setter setter,
bool useDefault)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
if (useDefault && setter)
(*setter)(getBoolValue());
_tied = true;
_type = BOOL;
@@ -520,13 +596,13 @@ SGValue::tieBool (bool_getter getter, bool_setter setter = 0,
* Returns true on success (i.e. the value is not currently tied).
*/
bool
SGValue::tieInt (int_getter getter, int_setter setter = 0,
bool useDefault = true)
SGValue::tieInt (int_getter getter, int_setter setter,
bool useDefault)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
if (useDefault && setter)
(*setter)(getIntValue());
_tied = true;
_type = INT;
@@ -546,13 +622,13 @@ SGValue::tieInt (int_getter getter, int_setter setter = 0,
* Returns true on success (i.e. the value is not currently tied).
*/
bool
SGValue::tieFloat (float_getter getter, float_setter setter = 0,
bool useDefault = true)
SGValue::tieFloat (float_getter getter, float_setter setter,
bool useDefault)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
if (useDefault && setter)
(*setter)(getFloatValue());
_tied = true;
_type = FLOAT;
@@ -572,13 +648,13 @@ SGValue::tieFloat (float_getter getter, float_setter setter = 0,
* Returns true on success (i.e. the value is not currently tied).
*/
bool
SGValue::tieDouble (double_getter getter, double_setter setter = 0,
bool useDefault = true)
SGValue::tieDouble (double_getter getter, double_setter setter,
bool useDefault)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
if (useDefault && setter)
(*setter)(getDoubleValue());
_tied = true;
_type = DOUBLE;
@@ -598,13 +674,13 @@ SGValue::tieDouble (double_getter getter, double_setter setter = 0,
* Returns true on success (i.e. the value is not currently tied).
*/
bool
SGValue::tieString (string_getter getter, string_setter setter = 0,
bool useDefault = true)
SGValue::tieString (string_getter getter, string_setter setter,
bool useDefault)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
if (useDefault && setter)
(*setter)(getStringValue());
_tied = true;
_type = STRING;
@@ -688,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.
*
@@ -696,14 +786,14 @@ SGPropertyList::~SGPropertyList ()
* and must not end with '/'.
*/
SGValue *
SGPropertyList::getValue (const string &name, bool create = false)
SGPropertyList::getValue (const string &name, bool create)
{
const_iterator el = _props.find(name);
if (el == _props.end()) {
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] == '/' ||
@@ -739,11 +829,11 @@ SGPropertyList::getValue (const string &name) const
* better to get the SGValue and query it repeatedly.
*/
bool
SGPropertyList::getBoolValue (const string &name) const
SGPropertyList::getBoolValue (const string &name, bool defaultValue) const
{
const SGValue * val = getValue(name);
if (val == 0)
return false;
return defaultValue;
else
return val->getBoolValue();
}
@@ -756,11 +846,11 @@ SGPropertyList::getBoolValue (const string &name) const
* better to get the SGValue and query it repeatedly.
*/
int
SGPropertyList::getIntValue (const string &name) const
SGPropertyList::getIntValue (const string &name, int defaultValue) const
{
const SGValue * val = getValue(name);
if (val == 0)
return 0;
return defaultValue;
else
return val->getIntValue();
}
@@ -773,11 +863,11 @@ SGPropertyList::getIntValue (const string &name) const
* better to get the SGValue and query it repeatedly.
*/
float
SGPropertyList::getFloatValue (const string &name) const
SGPropertyList::getFloatValue (const string &name, float defaultValue) const
{
const SGValue * val = getValue(name);
if (val == 0)
return 0.0;
return defaultValue;
else
return val->getFloatValue();
}
@@ -790,11 +880,11 @@ SGPropertyList::getFloatValue (const string &name) const
* better to get the SGValue and query it repeatedly.
*/
double
SGPropertyList::getDoubleValue (const string &name) const
SGPropertyList::getDoubleValue (const string &name, double defaultValue) const
{
const SGValue * val = getValue(name);
if (val == 0)
return 0.0;
return defaultValue;
else
return val->getDoubleValue();
}
@@ -807,11 +897,12 @@ SGPropertyList::getDoubleValue (const string &name) const
* better to save the SGValue and query it repeatedly.
*/
const string &
SGPropertyList::getStringValue (const string &name) const
SGPropertyList::getStringValue (const string &name,
const string &defaultValue) const
{
const SGValue * val = getValue(name);
if (val == 0)
return empty_string;
return defaultValue;
else
return val->getStringValue();
}
@@ -916,9 +1007,10 @@ bool
SGPropertyList::tieBool (const string &name,
bool_getter getter,
bool_setter setter,
bool useDefault = true)
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,9 +1024,10 @@ bool
SGPropertyList::tieInt (const string &name,
int_getter getter,
int_setter setter,
bool useDefault = true)
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,9 +1041,10 @@ bool
SGPropertyList::tieFloat (const string &name,
float_getter getter,
float_setter setter,
bool useDefault = true)
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,9 +1058,10 @@ bool
SGPropertyList::tieDouble (const string &name,
double_getter getter,
double_setter setter,
bool useDefault = true)
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,9 +1075,10 @@ bool
SGPropertyList::tieString (const string &name,
string_getter getter,
string_setter setter,
bool useDefault = true)
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);
}
@@ -995,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();
}
@@ -1039,9 +1135,9 @@ get_base (const string &parent, const string &child,
/**
* Constructor.
*/
SGPropertyNode::SGPropertyNode (const string &path = "",
SGPropertyList * props = 0)
: _props(props)
SGPropertyNode::SGPropertyNode (const string &path,
SGPropertyList * props)
: _props(props), _node(0)
{
setPath(path);
}
@@ -1052,6 +1148,8 @@ SGPropertyNode::SGPropertyNode (const string &path = "",
*/
SGPropertyNode::~SGPropertyNode ()
{
delete _node;
_node = 0;
}
@@ -1089,24 +1187,6 @@ SGPropertyNode::getName () const
}
/**
* Return the value of the current node.
*
* Currently, this does a lookup each time, but we could cache the
* value safely as long as it's non-zero.
*
* Note that this will not create the value if it doesn't already exist.
*/
SGValue *
SGPropertyNode::getValue ()
{
if (_props == 0 || _path.size() == 0)
return 0;
else
return _props->getValue(_path);
}
/**
* Return the number of children for the current node.
*/
@@ -1143,17 +1223,18 @@ SGPropertyNode::size () const
* A return value of true means success; otherwise, the node supplied
* is unmodified.
*/
bool
SGPropertyNode::getParent (SGPropertyNode &parent) const
SGPropertyNode &
SGPropertyNode::getParent () const
{
if (_node == 0)
_node = new SGPropertyNode();
string::size_type pos = _path.rfind('/');
if (pos != string::npos) {
parent.setPath(_path.substr(0, pos-1));
parent.setPropertyList(_props);
return true;
} else {
return false;
_node->setPropertyList(_props);
_node->setPath(_path.substr(0, pos-1));
}
return *_node;
}
@@ -1163,11 +1244,14 @@ SGPropertyNode::getParent (SGPropertyNode &parent) const
* A return value of true means success; otherwise, the node supplied
* is unmodified.
*/
bool
SGPropertyNode::getChild (SGPropertyNode &child, int n) const
SGPropertyNode &
SGPropertyNode::getChild (int n) const
{
if (_node == 0)
_node = new SGPropertyNode();
if (_props == 0)
return false;
return *_node;
int s = 0;
string base;
@@ -1180,12 +1264,9 @@ SGPropertyNode::getChild (SGPropertyNode &child, int n) const
while (it != end) {
if (get_base(pattern, it->first, base) && base != lastBase) {
if (s == n) {
string path = _path;
path += '/';
path += base;
child.setPath(path);
child.setPropertyList(_props);
return true;
_node->setPropertyList(_props);
_node->setPath(_path + string("/") + base);
return *_node;
} else {
s++;
lastBase = base;
@@ -1194,7 +1275,149 @@ SGPropertyNode::getChild (SGPropertyNode &child, int n) const
it++;
}
return false;
return *_node;
}
/**
* Return a node for an arbitrary subpath.
*
* Never returns 0.
*/
SGPropertyNode &
SGPropertyNode::getSubNode (const string &subpath) const
{
if (_node == 0)
_node = new SGPropertyNode();
_node->setPropertyList(_props);
_node->setPath(_path + string("/") + subpath);
return *_node;
}
/**
* 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.
*
* Currently, this does a lookup each time, but we could cache the
* value safely as long as it's non-zero.
*
* Note that this will not create the value if it doesn't already exist.
*/
SGValue *
SGPropertyNode::getValue (const string &subpath)
{
if (_props == 0)
return 0;
if (subpath.size() == 0)
return _props->getValue(_path);
else
return _props->getValue(_path + string("/") + subpath);
}
/**
* Return a bool value.
*/
bool
SGPropertyNode::getBoolValue (const string &subpath, bool defaultValue) const
{
if (_props == 0)
return defaultValue;
if (subpath == "")
return _props->getBoolValue(_path, defaultValue);
else
return _props->getBoolValue(_path + string("/") + subpath,
defaultValue);
}
/**
* Return an int value.
*/
int
SGPropertyNode::getIntValue (const string &subpath, int defaultValue) const
{
if (_props == 0)
return defaultValue;
if (subpath == "")
return _props->getIntValue(_path, defaultValue);
else
return _props->getIntValue(_path + string("/") + subpath,
defaultValue);
}
/**
* Return a float value.
*/
float
SGPropertyNode::getFloatValue (const string &subpath, float defaultValue) const
{
if (_props == 0)
return defaultValue;
if (subpath == "")
return _props->getFloatValue(_path, defaultValue);
else
return _props->getFloatValue(_path + string("/") + subpath,
defaultValue);
}
/**
* Return a double value.
*/
double
SGPropertyNode::getDoubleValue (const string &subpath,
double defaultValue) const
{
if (_props == 0)
return defaultValue;
if (subpath == "")
return _props->getDoubleValue(_path, defaultValue);
else
return _props->getDoubleValue(_path + string("/") + subpath,
defaultValue);
}
/**
* Return a string value.
*/
const string &
SGPropertyNode::getStringValue (const string &subpath,
const string &defaultValue) const
{
if (_props == 0)
return defaultValue;
if (subpath == "")
return _props->getStringValue(_path, defaultValue);
else
return _props->getStringValue(_path + string("/") + subpath,
defaultValue);
}
// end of props.cxx
+86 -11
View File
@@ -19,9 +19,42 @@
#include <string>
#include <map>
#include <iostream>
using std::string;
using std::map;
using std::istream;
using std::ostream;
#ifdef UNKNOWN
#pragma warn A sloppy coder has defined UNKNOWN as a macro!
#undef UNKNOWN
#endif
#ifdef BOOL
#pragma warn A sloppy coder has defined BOOL as a macro!
#undef BOOL
#endif
#ifdef INT
#pragma warn A sloppy coder has defined INT as a macro!
#undef INT
#endif
#ifdef FLOAT
#pragma warn A sloppy coder has defined FLOAT as a macro!
#undef FLOAT
#endif
#ifdef DOUBLE
#pragma warn A sloppy coder has defined DOUBLE as a macro!
#undef DOUBLE
#endif
#ifdef STRING
#pragma warn A sloppy coder has defined STRING as a macro!
#undef STRING
#endif
@@ -80,7 +113,7 @@ public:
virtual int getIntValue () const;
virtual float getFloatValue () const;
virtual double getDoubleValue () const;
virtual const string &getStringValue () const;
virtual const string & getStringValue () const;
// Setters.
virtual bool setBoolValue (bool value);
@@ -228,14 +261,22 @@ 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;
virtual bool getBoolValue (const string &name) const;
virtual int getIntValue (const string &name) const;
virtual float getFloatValue (const string &name) const;
virtual double getDoubleValue (const string &name) const;
virtual const string &getStringValue (const string &name) const;
virtual bool getBoolValue (const string &name,
bool defaultValue = false) const;
virtual int getIntValue (const string &name,
int defaultValue = 0) const;
virtual float getFloatValue (const string &name,
float defaultValue = 0.0) const;
virtual double getDoubleValue (const string &name,
double defaultValue = 0.0L) const;
virtual const string & getStringValue (const string &name,
const string &defaultValue = "")
const;
virtual bool setBoolValue (const string &name, bool value);
virtual bool setIntValue (const string &name, int value);
@@ -331,17 +372,51 @@ public:
// Accessors for derived information.
virtual int size () const;
virtual const string &getName () const;
virtual SGValue * getValue ();
virtual bool getParent (SGPropertyNode &parent) const;
virtual bool getChild (SGPropertyNode &child, int n) const;
virtual SGPropertyNode &getParent () const;
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 = "",
bool defaultValue = false) const;
virtual int getIntValue (const string &subpath = "",
int defaultValue = 0) const;
virtual float getFloatValue (const string &subpath = "",
float defaultValue = 0.0) const;
virtual double getDoubleValue (const string &subpath = "",
double defaultValue = 0.0L) const;
virtual const string &
getStringValue (const string &subpath = "",
const string &defaultValue = "") const;
private:
string _path;
mutable string _name; // for pointer persistence only
SGPropertyList * _props;
// for pointer persistence...
// NOT THREAD SAFE!!!
// (each thread must have its own node
// object)
mutable string _name;
mutable SGPropertyNode * _node;
};
////////////////////////////////////////////////////////////////////////
// Input and output.
////////////////////////////////////////////////////////////////////////
extern bool readPropertyList (istream &input, SGPropertyList * props);
extern bool readPropertyList (const string &file, SGPropertyList * props);
extern bool writePropertyList (ostream &output, const SGPropertyList * props);
extern bool writePropertyList (const string &file,
const SGPropertyList * props);
////////////////////////////////////////////////////////////////////////
// Global property manager.
@@ -350,6 +425,6 @@ private:
extern SGPropertyList current_properties;
#endif __PROPS_HXX
#endif // __PROPS_HXX
// end of props.hxx
+369
View File
@@ -0,0 +1,369 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h> // strcmp()
#include <stdlib.h> // atof() atoi()
#include <simgear/debug/logstream.hxx>
#include <simgear/xml/easyxml.hxx>
#include "props.hxx"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
FG_USING_STD(ofstream);
FG_USING_STD(ifstream);
FG_USING_STD(string);
FG_USING_STD(vector);
////////////////////////////////////////////////////////////////////////
// Visitor class for building the property list.
////////////////////////////////////////////////////////////////////////
class PropVisitor : public XMLVisitor
{
public:
PropVisitor (SGPropertyList * props) : _props(props), _level(0), _ok(true) {}
void startDocument ();
void startElement (const char * name, const XMLAttributes &atts);
void endElement (const char * name);
void data (const char * s, int length);
void warning (const char * message, int line, int col);
void error (const char * message, int line, int col);
bool isOK () const { return _ok; }
private:
void pushState (const char * name) {
_states.push_back(_state);
_level++;
_state.name = name;
_state.type = SGValue::UNKNOWN;
_state.data = "";
_state.hasChildren = false;
_state.hasData = false;
}
void popState () {
_state = _states.back();
_states.pop_back();
_level--;
}
struct State
{
State () : hasChildren(false), hasData(false) {}
string name;
SGValue::Type type;
string data;
bool hasChildren;
bool hasData;
};
SGPropertyList * _props;
State _state;
vector<State> _states;
int _level;
bool _ok;
};
void
PropVisitor::startDocument ()
{
_level = 0;
_ok = true;
}
void
PropVisitor::startElement (const char * name, const XMLAttributes &atts)
{
if (!_ok)
return;
if (_level == 0 && strcmp(name, "PropertyList")) {
_ok = false;
FG_LOG(FG_INPUT, FG_ALERT, "XML document has root element \""
<< name << "\" instead of \"PropertyList\"");
return;
}
// Mixed content?
_state.hasChildren = true;
if (_state.hasData) {
FG_LOG(FG_INPUT, FG_ALERT,
"XML element has mixed elements and data in element "
<< _state.name);
_ok = false;
return;
}
// Start a new state.
pushState(name);
// See if there's a type specified.
const char * type = atts.getValue("type");
if (type == 0 || !strcmp("unknown", type))
_state.type = SGValue::UNKNOWN;
else if (!strcmp("bool", type))
_state.type = SGValue::BOOL;
else if (!strcmp("int", type))
_state.type = SGValue::INT;
else if (!strcmp("float", type))
_state.type = SGValue::FLOAT;
else if (!strcmp("double", type))
_state.type = SGValue::DOUBLE;
else if (!strcmp("string", type))
_state.type = SGValue::STRING;
else
FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized type " << type
<< ", using UNKNOWN");
}
void
PropVisitor::endElement (const char * name)
{
if (!_ok)
return;
// See if there's a property to add.
if (_state.hasData) {
bool status = false;
// Figure out the path name.
string path = "";
for (int i = 2; i < _level; i++) {
path += '/';
path += _states[i].name;
}
path += '/';
path += _state.name;
// Set the value
switch (_state.type) {
case SGValue::BOOL:
if (_state.data == "true" || _state.data == "TRUE") {
status = _props->setBoolValue(path, true);
} else if (atof(_state.data.c_str()) != 0.0) {
status = _props->setBoolValue(path, true);
} else {
status =_props->setBoolValue(path, false);
}
break;
case SGValue::INT :
status = _props->setIntValue(path, atoi(_state.data.c_str()));
break;
case SGValue::FLOAT:
status = _props->setFloatValue(path, atof(_state.data.c_str()));
break;
case SGValue::DOUBLE:
status = _props->setDoubleValue(path, atof(_state.data.c_str()));
break;
case SGValue::STRING:
status = _props->setStringValue(path, _state.data);
break;
default:
status = _props->setUnknownValue(path, _state.data);
break;
}
if (!status)
FG_LOG(FG_INPUT, FG_ALERT, "Failed to set property "
<< path << " to " << _state.data);
}
// Pop the stack.
popState();
}
void
PropVisitor::data (const char * s, int length)
{
if (!_ok)
return;
// Check if there is any non-whitespace
if (!_state.hasData)
for (int i = 0; i < length; i++)
if (s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r')
_state.hasData = true;
_state.data += string(s, length); // FIXME: inefficient
}
void
PropVisitor::warning (const char * message, int line, int col)
{
FG_LOG(FG_INPUT, FG_ALERT, "Warning importing property list: "
<< message << " (" << line << ',' << col << ')');
}
void
PropVisitor::error (const char * message, int line, int col)
{
FG_LOG(FG_INPUT, FG_ALERT, "Error importing property list: "
<< message << " (" << line << ',' << col << ')');
_ok = false;
}
////////////////////////////////////////////////////////////////////////
// Property list reader.
////////////////////////////////////////////////////////////////////////
bool
readPropertyList (istream &input, SGPropertyList * props)
{
PropVisitor visitor(props);
return readXML(input, visitor) && visitor.isOK();
}
bool
readPropertyList (const string &file, SGPropertyList * props)
{
ifstream input(file.c_str());
if (input.good()) {
return readPropertyList(input, props);
} else {
FG_LOG(FG_INPUT, FG_ALERT, "Error reading property list from file "
<< file);
return false;
}
}
////////////////////////////////////////////////////////////////////////
// Property list writer.
////////////////////////////////////////////////////////////////////////
#define INDENT_STEP 2
/**
* Return the type name.
*/
static const char *
getTypeName (SGValue::Type type)
{
switch (type) {
case SGValue::UNKNOWN:
return "unknown";
case SGValue::BOOL:
return "bool";
case SGValue::INT:
return "int";
case SGValue::FLOAT:
return "float";
case SGValue::DOUBLE:
return "double";
case SGValue::STRING:
return "string";
}
return "unknown"; // avoid a compiler warning
}
/**
* Escape characters for output.
*/
static void
writeData (ostream &output, const string &data)
{
for (int i = 0; i < (int)data.size(); i++) {
switch (data[i]) {
case '&':
output << "&amp;";
break;
case '<':
output << "&lt;";
break;
case '>':
output << "&gt;";
break;
default:
output << data[i];
break;
}
}
}
static void
doIndent (ostream &output, int indent)
{
while (indent-- > 0) {
output << ' ';
}
}
static bool
writeNode (ostream &output, SGPropertyNode node, int indent)
{
const string &name = node.getName();
int size = node.size();
// Write out the literal value, if any.
SGValue * value = node.getValue();
if (value != 0) {
SGValue::Type type = value->getType();
doIndent(output, indent);
output << '<' << name;
if (type != SGValue::UNKNOWN)
output << " type=\"" << getTypeName(type) << '"';
output << '>';
writeData(output, value->getStringValue());
output << "</" << name << '>' << endl;
}
// Write out the children, if any.
if (size > 0) {
doIndent(output, indent);
output << '<' << name << '>' << endl;;
for (int i = 0; i < size; i++) {
writeNode(output, node.getChild(i), indent + INDENT_STEP);
}
doIndent(output, indent);
output << "</" << name << '>' << endl;
}
return true;
}
bool
writePropertyList (ostream &output, const SGPropertyList * props)
{
SGPropertyNode root ("/", (SGPropertyList *)props); // FIXME
output << "<?xml version=\"1.0\"?>" << endl << endl;
output << "<PropertyList>" << endl;
for (int i = 0; i < root.size(); i++) {
writeNode(output, root.getChild(i), INDENT_STEP);
}
output << "</PropertyList>" << endl;
return true;
}
bool
writePropertyList (const string &file, const SGPropertyList * props)
{
ofstream output(file.c_str());
if (output.good()) {
return writePropertyList(output, props);
} else {
FG_LOG(FG_INPUT, FG_ALERT, "Cannot write property list to file "
<< file);
return false;
}
}
+121 -6
View File
@@ -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 {
+2 -2
View File
@@ -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 );
+27
View File
@@ -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
+70
View File
@@ -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;
}
}
+139
View File
@@ -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
+27
View File
@@ -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;
}
+89
View File
@@ -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 );
}
+96
View File
@@ -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
+59
View File
@@ -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;
}
+1 -1
View File
@@ -9,4 +9,4 @@ libsgscreen_a_SOURCES = \
screen-dump.cxx \
win32-printer.h
INCLUDES += -I$(top_builddir)
INCLUDES += -I$(top_srcdir)
+5 -1
View File
@@ -50,7 +50,11 @@ void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int
ibuffer = (unsigned char *) malloc(win_width*win_height*RGB);
fp = fopen(filename, "wb");
if ( (fp = fopen(filename, "wb")) == NULL ) {
printf("Warning: cannot open %s\n", filename);
return;
}
fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n",
win_width, win_height, UCHAR_MAX);
q = 0;
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -20,4 +20,4 @@ libsgsky_a_SOURCES = \
sphere.cxx \
stars.cxx
INCLUDES += -I$(top_builddir)
INCLUDES += -I$(top_srcdir)
+2 -2
View File
@@ -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 );
+3 -3
View File
@@ -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
};
+18 -11
View File
@@ -39,7 +39,6 @@
#include <plib/sg.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/fg_random.h>
#include "dome.hxx"
@@ -69,6 +68,13 @@
static int sgSkyDomePreDraw( ssgEntity *e ) {
/* cout << endl << "Dome Pre Draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
@@ -78,9 +84,10 @@ static int sgSkyDomePreDraw( ssgEntity *e ) {
static int sgSkyDomePostDraw( ssgEntity *e ) {
/* cout << endl << "Dome Post Draw" << endl << "----------------"
<< endl << endl; */
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
return true;
}
@@ -349,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;
@@ -390,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;
@@ -412,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 );
+28 -6
View File
@@ -29,6 +29,8 @@
# include <config.h>
#endif
#include <simgear/compiler.h>
#include <stdio.h>
#include <iostream>
@@ -45,6 +47,13 @@
static int sgMoonOrbPreDraw( ssgEntity *e ) {
/* cout << endl << "Moon orb pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE ) ;
@@ -55,10 +64,13 @@ static int sgMoonOrbPreDraw( ssgEntity *e ) {
static int sgMoonOrbPostDraw( ssgEntity *e ) {
/* cout << endl << "Moon orb post draw" << endl << "----------------"
<< endl << endl; */
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
// glEnable( GL_DEPTH_TEST );
// glEnable( GL_FOG );
// glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
/* test
glDisable( GL_LIGHTING );
glDisable( GL_CULL_FACE );
@@ -73,6 +85,13 @@ static int sgMoonOrbPostDraw( ssgEntity *e ) {
static int sgMoonHaloPreDraw( ssgEntity *e ) {
/* cout << endl << "Moon halo pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT);
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
@@ -83,9 +102,12 @@ static int sgMoonHaloPreDraw( ssgEntity *e ) {
static int sgMoonHaloPostDraw( ssgEntity *e ) {
/* cout << endl << "Moon halo post draw" << endl << "----------------"
<< endl << endl; */
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
// glEnable( GL_DEPTH_TEST );
// glEnable( GL_FOG );
// glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
return true;
}
+26 -4
View File
@@ -43,6 +43,13 @@
static int sgSunOrbPreDraw( ssgEntity *e ) {
/* cout << endl << "Sun orb pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
@@ -52,8 +59,12 @@ static int sgSunOrbPreDraw( ssgEntity *e ) {
static int sgSunOrbPostDraw( ssgEntity *e ) {
/* cout << endl << "Sun orb post draw" << endl << "----------------"
<< endl << endl; */
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
// glEnable( GL_DEPTH_TEST );
// glEnable( GL_FOG );
return true;
}
@@ -61,6 +72,13 @@ static int sgSunOrbPostDraw( ssgEntity *e ) {
static int sgSunHaloPreDraw( ssgEntity *e ) {
/* cout << endl << "Sun halo pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
@@ -71,8 +89,12 @@ static int sgSunHaloPreDraw( ssgEntity *e ) {
static int sgSunHaloPostDraw( ssgEntity *e ) {
/* cout << endl << "Sun halo post draw" << endl << "----------------"
<< endl << endl; */
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
// glEnable( GL_DEPTH_TEST );
// glEnable( GL_FOG );
return true;
}
+14 -12
View File
@@ -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"
@@ -193,8 +193,10 @@ void SGSky::postDraw( float alt ) {
int in_cloud = -1; // cloud we are in
int i;
// check where we are relative to the cloud layers
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->get_asl();
float thickness = cloud_layers[i]->get_thickness();
@@ -220,14 +222,14 @@ void SGSky::postDraw( float alt ) {
if ( pos == 0 ) {
// we are below all the cloud layers, draw top to bottom
for ( int i = cloud_layers.size() - 1; i >= 0; --i ) {
for ( i = cloud_layers.size() - 1; i >= 0; --i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
} else if ( pos >= (int)cloud_layers.size() ) {
// we are above all the cloud layers, draw bottom to top
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
@@ -235,12 +237,12 @@ void SGSky::postDraw( float alt ) {
} else {
// we are between cloud layers, draw lower layers bottom to
// top and upper layers top to bottom
for ( int i = 0; i < pos; ++i ) {
for ( i = 0; i < pos; ++i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
for ( int i = cloud_layers.size() - 1; i >= pos; --i ) {
for ( i = cloud_layers.size() - 1; i >= pos; --i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
@@ -267,10 +269,10 @@ void SGSky::add_cloud_layer( double asl, double thickness,
cloud_layers.push_back( layer );
}
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
cout << "layer " << i << " = " << cloud_layers[i]->get_asl() << endl;
}
cout << endl;
// for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
// cout << "layer " << i << " = " << cloud_layers[i]->get_asl() << endl;
// }
// cout << endl;
}
@@ -326,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;
}
}
+5 -5
View File
@@ -39,11 +39,11 @@
#include <vector>
#include "cloud.hxx"
#include "dome.hxx"
#include "moon.hxx"
#include "oursun.hxx"
#include "stars.hxx"
#include <simgear/sky/cloud.hxx>
#include <simgear/sky/dome.hxx>
#include <simgear/sky/moon.hxx>
#include <simgear/sky/oursun.hxx>
#include <simgear/sky/stars.hxx>
FG_USING_STD(vector);
+3 -2
View File
@@ -34,6 +34,7 @@
#include <plib/sg.h>
#include <plib/ssg.h>
FG_USING_NAMESPACE(std);
// return a sphere object as an ssgBranch
ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
@@ -113,11 +114,11 @@ ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );
if ( vl->getNum() != nl->getNum() ) {
cout << "bad sphere1\n";
std::cout << "bad sphere1\n";
exit(-1);
}
if ( vl->getNum() != tl->getNum() ) {
cout << "bad sphere2\n";
std::cout << "bad sphere2\n";
exit(-1);
}
slice->setState( state );
+14 -5
View File
@@ -35,21 +35,27 @@
#include <plib/sg.h>
#include <plib/ssg.h>
#include <compiler.h>
#include "stars.hxx"
#ifdef _MSC_VER
FG_USING_STD(cout);
FG_USING_STD(endl);
#endif
// Set up star rendering call backs
static int sgStarPreDraw( ssgEntity *e ) {
/* cout << endl << "Star pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
// glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
}
@@ -57,8 +63,11 @@ static int sgStarPreDraw( ssgEntity *e ) {
static int sgStarPostDraw( ssgEntity *e ) {
/* cout << endl << "Star post draw" << endl << "----------------"
<< endl << endl; */
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
glPopAttrib();
// glEnable( GL_DEPTH_TEST );
// glEnable( GL_FOG );
return true;
}
+2 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+30 -12
View File
@@ -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" );
@@ -75,18 +80,24 @@ SGTime::SGTime( double lon, double lat, const string& root )
// cout << "Current local time = "
// << asctime(localtime(&cur_time)) << endl;
FGPath zone( root );
zone.append( "zone.tab" );
FG_LOG( FG_EVENT, FG_DEBUG, "Reading timezone info from: " << zone.str() );
tzContainer = new TimezoneContainer( zone.c_str() );
if ( root != "" ) {
FGPath zone( root );
zone.append( "zone.tab" );
FG_LOG( FG_EVENT, FG_DEBUG, "Reading timezone info from: "
<< zone.str() );
tzContainer = new TimezoneContainer( zone.c_str() );
GeoCoord location( RAD_TO_DEG * lat, RAD_TO_DEG * lon );
GeoCoord* nearestTz = tzContainer->getNearest(location);
GeoCoord location( RAD_TO_DEG * lat, RAD_TO_DEG * lon );
GeoCoord* nearestTz = tzContainer->getNearest(location);
FGPath name( root );
name.append( nearestTz->getDescription() );
zonename = strdup( name.c_str() );
// cout << "Using zonename = " << zonename << endl;
FGPath name( root );
name.append( nearestTz->getDescription() );
zonename = strdup( name.c_str() );
// cout << "Using zonename = " << zonename << endl;
} else {
tzContainer = NULL;
zonename = NULL;
}
}
@@ -95,9 +106,16 @@ SGTime::SGTime( const string& root ) {
}
SGTime::SGTime() {
SGTime( 0.0, 0.0, "" );
}
SGTime::~SGTime()
{
delete tzContainer;
if ( tzContainer != NULL ) {
delete tzContainer;
}
if ( zonename != NULL ) {
delete zonename;
@@ -400,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
+2 -1
View File
@@ -43,7 +43,7 @@
# include <time.h>
#endif
#include "timezone.h"
#include <simgear/timing/timezone.h>
// Define a structure containing time parameters
@@ -86,6 +86,7 @@ public:
SGTime( double lon, double lat, const string& root );
SGTime( const string& root );
SGTime();
~SGTime();
// Update the time related variables
+180
View File
@@ -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(&current, &tz);
seconds = current.tv_sec;
usec = current.tv_usec;
#elif defined( HAVE_GETLOCALTIME )
SYSTEMTIME current;
GetLocalTime(&current);
seconds = current.wSecond;
usec = current.wMilliseconds * 1000;
#elif defined( HAVE_FTIME )
struct timeb current;
ftime(&current);
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
+2 -1
View File
@@ -30,9 +30,10 @@
#ifndef _TIMEZONE_H_
#define _TIMEZONE_H_
#include "geocoord.h"
#include <stdio.h>
#include <simgear/timing/geocoord.h>
class Timezone : public GeoCoord
{
private:
+1 -1
View File
@@ -6,4 +6,4 @@ include_HEADERS = xgl.h
libsgxgl_a_SOURCES = xgl.c xglUtils.c
INCLUDES += -I$(top_builddir)
INCLUDES += -I$(top_srcdir)
+25
View File
@@ -0,0 +1,25 @@
if HAVE_ZLIB
ZLIB_INCL =
else
XLIB_INCL = -I$(top_srcdir)/src/zlib
endif
lib_LIBRARIES = libsgxml.a
include_HEADERS = \
easyxml.hxx
noinst_HEADERS = \
xmltok_impl.c xmltok_ns.c
libsgxml_a_SOURCES = \
asciitab.h \
easyxml.cxx \
hashtable.h hashtable.c \
iasciitab.h latin1tab.h nametab.h utf8tab.h xmldef.h \
xmlparse.h xmlparse.c \
xmlrole.h xmlrole.c \
xmltok.h xmltok.c \
xmltok_impl.h
INCLUDES += -I$(top_srcdir) $(ZLIB_INCL)
+62
View File
@@ -0,0 +1,62 @@
/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is expat.
The Initial Developer of the Original Code is James Clark.
Portions created by James Clark are Copyright (C) 1998, 1999
James Clark. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms
of the GNU General Public License (the "GPL"), in which case the
provisions of the GPL are applicable instead of those above. If you
wish to allow use of your version of this file only under the terms of
the GPL and not to allow others to use your version of this file under
the MPL, indicate your decision by deleting the provisions above and
replace them with the notice and other provisions required by the
GPL. If you do not delete the provisions above, a recipient may use
your version of this file under either the MPL or the GPL.
*/
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
+239
View File
@@ -0,0 +1,239 @@
// 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"
////////////////////////////////////////////////////////////////////////
// Implementation of XMLAttributes.
////////////////////////////////////////////////////////////////////////
XMLAttributes::XMLAttributes ()
{
}
XMLAttributes::~XMLAttributes ()
{
}
int
XMLAttributes::findAttribute (const char * name) const
{
int s = size();
for (int i = 0; i < s; i++) {
if (strcmp(name, getName(i)) == 0)
return i;
}
return -1;
}
bool
XMLAttributes::hasAttribute (const char * name) const
{
return (findAttribute(name) != -1);
}
const char *
XMLAttributes::getValue (const char * name) const
{
int pos = findAttribute(name);
if (pos >= 0)
return getValue(pos);
else
return 0;
}
////////////////////////////////////////////////////////////////////////
// Implementation of XMLAttributesDefault.
////////////////////////////////////////////////////////////////////////
XMLAttributesDefault::XMLAttributesDefault ()
{
}
XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
{
int s = atts.size();
for (int i = 0; i < s; i++)
addAttribute(atts.getName(i), atts.getValue(i));
}
XMLAttributesDefault::~XMLAttributesDefault ()
{
}
int
XMLAttributesDefault::size () const
{
return _atts.size() / 2;
}
const char *
XMLAttributesDefault::getName (int i) const
{
return _atts[i*2].c_str();
}
const char *
XMLAttributesDefault::getValue (int i) const
{
return _atts[i*2+1].c_str();
}
void
XMLAttributesDefault::addAttribute (const char * name, const char * value)
{
_atts.push_back(name);
_atts.push_back(value);
}
void
XMLAttributesDefault::setName (int i, const char * name)
{
_atts[i*2] = name;
}
void
XMLAttributesDefault::setValue (int i, const char * name)
{
_atts[i*2+1] = name;
}
void
XMLAttributesDefault::setValue (const char * name, const char * value)
{
int pos = findAttribute(name);
if (pos >= 0) {
setName(pos, name);
setValue(pos, value);
} else {
addAttribute(name, value);
}
}
////////////////////////////////////////////////////////////////////////
// Attribute list wrapper for Expat.
////////////////////////////////////////////////////////////////////////
class ExpatAtts : public XMLAttributes
{
public:
ExpatAtts (const char ** atts) : _atts(atts) {}
virtual int size () const;
virtual const char * getName (int i) const;
virtual const char * getValue (int i) const;
private:
const char ** _atts;
};
int
ExpatAtts::size () const
{
int s = 0;
for (int i = 0; _atts[i] != 0; i += 2)
s++;
return s;
}
const char *
ExpatAtts::getName (int i) const
{
return _atts[i*2];
}
const char *
ExpatAtts::getValue (int i) const
{
return _atts[i*2+1];
}
////////////////////////////////////////////////////////////////////////
// Static callback functions for Expat.
////////////////////////////////////////////////////////////////////////
#define VISITOR (*((XMLVisitor*)userData))
static void
start_element (void * userData, const char * name, const char ** atts)
{
VISITOR.startElement(name, ExpatAtts(atts));
}
static void
end_element (void * userData, const char * name)
{
VISITOR.endElement(name);
}
static void
character_data (void * userData, const char * s, int len)
{
VISITOR.data(s, len);
}
static void
processing_instruction (void * userData,
const char * target,
const char * data)
{
VISITOR.pi(target, data);
}
#undef VISITOR
////////////////////////////////////////////////////////////////////////
// Implementation of XMLReader.
////////////////////////////////////////////////////////////////////////
bool
readXML (istream &input, XMLVisitor &visitor)
{
bool retval = true;
XML_Parser parser = XML_ParserCreate(0);
XML_SetUserData(parser, &visitor);
XML_SetElementHandler(parser, start_element, end_element);
XML_SetCharacterDataHandler(parser, character_data);
XML_SetProcessingInstructionHandler(parser, processing_instruction);
visitor.startXML();
char buf[16384];
while (!input.eof()) {
input.read(buf,16384);
// TODO: deal with bad stream.
if (!XML_Parse(parser, buf, input.gcount(), false)) {
visitor.error(XML_ErrorString(XML_GetErrorCode(parser)),
XML_GetCurrentColumnNumber(parser),
XML_GetCurrentLineNumber(parser));
retval = false;
}
}
if (retval)
visitor.endXML();
XML_ParserFree(parser);
return retval;
}
// end of easyxml.cxx
+91
View File
@@ -0,0 +1,91 @@
#ifndef __EASYXML_HXX
#define __EASYXML_HXX
#include <iostream>
#include <string>
#include <vector>
using std::istream;
using std::string;
using std::vector;
/**
* Interface for XML attributes.
*/
class XMLAttributes
{
public:
XMLAttributes ();
virtual ~ XMLAttributes ();
virtual int size () const = 0;
virtual const char * getName (int i) const = 0;
virtual const char * getValue (int i) const = 0;
virtual int findAttribute (const char * name) const;
virtual bool hasAttribute (const char * name) const;
virtual const char * getValue (const char * name) const;
};
/**
* Default mutable attributes implementation.
*/
class XMLAttributesDefault : public XMLAttributes
{
public:
XMLAttributesDefault ();
XMLAttributesDefault (const XMLAttributes & atts);
virtual ~XMLAttributesDefault ();
virtual int size () const;
virtual const char * getName (int i) const;
virtual const char * getValue (int i) const;
virtual void addAttribute (const char * name, const char * value);
virtual void setName (int i, const char * name);
virtual void setValue (int i, const char * value);
virtual void setValue (const char * name, const char * value);
private:
vector<string> _atts;
};
/**
* Visitor class for an XML document.
*
* To read an XML document, a module must subclass the visitor to do
* something useful for the different XML events.
*/
class XMLVisitor
{
public:
// start an XML document
virtual void startXML () {}
// end an XML document
virtual void endXML () {}
// start an element
virtual void startElement (const char * name, const XMLAttributes &atts) {}
// end an element
virtual void endElement (const char * name) {}
// character data
virtual void data (const char * s, int length) {}
// processing instruction
virtual void pi (const char * target, const char * data) {}
// non-fatal warning
virtual void warning (const char * message, int line, int column) {}
// fatal error
virtual void error (const char * message, int line, int column) = 0;
};
/**
* Read an XML document.
*/
extern bool readXML (istream &input, XMLVisitor &visitor);
#endif // __EASYXML_HXX
+151
View File
@@ -0,0 +1,151 @@
/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
csompliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is expat.
The Initial Developer of the Original Code is James Clark.
Portions created by James Clark are Copyright (C) 1998, 1999
James Clark. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms
of the GNU General Public License (the "GPL"), in which case the
provisions of the GPL are applicable instead of those above. If you
wish to allow use of your version of this file only under the terms of
the GPL and not to allow others to use your version of this file under
the MPL, indicate your decision by deleting the provisions above and
replace them with the notice and other provisions required by the
GPL. If you do not delete the provisions above, a recipient may use
your version of this file under either the MPL or the GPL.
*/
#include "xmldef.h"
#ifdef XML_UNICODE_WCHAR_T
#ifndef XML_UNICODE
#define XML_UNICODE
#endif
#endif
#include "hashtable.h"
#define INIT_SIZE 64
static
int keyeq(KEY s1, KEY s2)
{
for (; *s1 == *s2; s1++, s2++)
if (*s1 == 0)
return 1;
return 0;
}
static
unsigned long hash(KEY s)
{
unsigned long h = 0;
while (*s)
h = (h << 5) + h + (unsigned char)*s++;
return h;
}
NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
{
size_t i;
if (table->size == 0) {
if (!createSize)
return 0;
table->v = calloc(INIT_SIZE, sizeof(NAMED *));
if (!table->v)
return 0;
table->size = INIT_SIZE;
table->usedLim = INIT_SIZE / 2;
i = hash(name) & (table->size - 1);
}
else {
unsigned long h = hash(name);
for (i = h & (table->size - 1);
table->v[i];
i == 0 ? i = table->size - 1 : --i) {
if (keyeq(name, table->v[i]->name))
return table->v[i];
}
if (!createSize)
return 0;
if (table->used == table->usedLim) {
/* check for overflow */
size_t newSize = table->size * 2;
NAMED **newV = calloc(newSize, sizeof(NAMED *));
if (!newV)
return 0;
for (i = 0; i < table->size; i++)
if (table->v[i]) {
size_t j;
for (j = hash(table->v[i]->name) & (newSize - 1);
newV[j];
j == 0 ? j = newSize - 1 : --j)
;
newV[j] = table->v[i];
}
free(table->v);
table->v = newV;
table->size = newSize;
table->usedLim = newSize/2;
for (i = h & (table->size - 1);
table->v[i];
i == 0 ? i = table->size - 1 : --i)
;
}
}
table->v[i] = calloc(1, createSize);
if (!table->v[i])
return 0;
table->v[i]->name = name;
(table->used)++;
return table->v[i];
}
void hashTableDestroy(HASH_TABLE *table)
{
size_t i;
for (i = 0; i < table->size; i++) {
NAMED *p = table->v[i];
if (p)
free(p);
}
free(table->v);
}
void hashTableInit(HASH_TABLE *p)
{
p->size = 0;
p->usedLim = 0;
p->used = 0;
p->v = 0;
}
void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
{
iter->p = table->v;
iter->end = iter->p + table->size;
}
NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
{
while (iter->p != iter->end) {
NAMED *tem = *(iter->p)++;
if (tem)
return tem;
}
return 0;
}
+69
View File
@@ -0,0 +1,69 @@
/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is expat.
The Initial Developer of the Original Code is James Clark.
Portions created by James Clark are Copyright (C) 1998, 1999
James Clark. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms
of the GNU General Public License (the "GPL"), in which case the
provisions of the GPL are applicable instead of those above. If you
wish to allow use of your version of this file only under the terms of
the GPL and not to allow others to use your version of this file under
the MPL, indicate your decision by deleting the provisions above and
replace them with the notice and other provisions required by the
GPL. If you do not delete the provisions above, a recipient may use
your version of this file under either the MPL or the GPL.
*/
#include <stddef.h>
#ifdef XML_UNICODE
#ifdef XML_UNICODE_WCHAR_T
typedef const wchar_t *KEY;
#else /* not XML_UNICODE_WCHAR_T */
typedef const unsigned short *KEY;
#endif /* not XML_UNICODE_WCHAR_T */
#else /* not XML_UNICODE */
typedef const char *KEY;
#endif /* not XML_UNICODE */
typedef struct {
KEY name;
} NAMED;
typedef struct {
NAMED **v;
size_t size;
size_t used;
size_t usedLim;
} HASH_TABLE;
NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
void hashTableInit(HASH_TABLE *);
void hashTableDestroy(HASH_TABLE *);
typedef struct {
NAMED **p;
NAMED **end;
} HASH_TABLE_ITER;
void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
NAMED *hashTableIterNext(HASH_TABLE_ITER *);
+63
View File
@@ -0,0 +1,63 @@
/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is expat.
The Initial Developer of the Original Code is James Clark.
Portions created by James Clark are Copyright (C) 1998, 1999
James Clark. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms
of the GNU General Public License (the "GPL"), in which case the
provisions of the GPL are applicable instead of those above. If you
wish to allow use of your version of this file only under the terms of
the GPL and not to allow others to use your version of this file under
the MPL, indicate your decision by deleting the provisions above and
replace them with the notice and other provisions required by the
GPL. If you do not delete the provisions above, a recipient may use
your version of this file under either the MPL or the GPL.
*/
/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
+62
View File
@@ -0,0 +1,62 @@
/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is expat.
The Initial Developer of the Original Code is James Clark.
Portions created by James Clark are Copyright (C) 1998, 1999
James Clark. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms
of the GNU General Public License (the "GPL"), in which case the
provisions of the GPL are applicable instead of those above. If you
wish to allow use of your version of this file only under the terms of
the GPL and not to allow others to use your version of this file under
the MPL, indicate your decision by deleting the provisions above and
replace them with the notice and other provisions required by the
GPL. If you do not delete the provisions above, a recipient may use
your version of this file under either the MPL or the GPL.
*/
/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+150
View File
@@ -0,0 +1,150 @@
static const unsigned namingBitmap[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
0x40000000, 0xF580C900, 0x00000007, 0x02010800,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
0x00000000, 0x00004C40, 0x00000000, 0x00000000,
0x00000007, 0x00000000, 0x00000000, 0x00000000,
0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
};
static const unsigned char nmstrtPages[] = {
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char namePages[] = {
0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

Some files were not shown because too many files have changed in this diff Show More