- The new classes in libmisc.tgz define a stream interface into zlib.
I've put these in a new directory, Lib/Misc. Feel free to rename it
to something more appropriate. However you'll have to change the
include directives in all the other files. Additionally you'll have
add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
test so I've included the required changes in config.tgz.
There are a fair few changes to Simulator/Objects as I've moved
things around. Loading tiles is quicker but thats not where the delay
is. Tile loading takes a few tenths of a second per file on a P200
but it seems to be the post-processing that leads to a noticeable
blip in framerate. I suppose its time to start profiling to see where
the delays are.
I've included a brief description of each archives contents.
Lib/Misc/
zfstream.cxx
zfstream.hxx
C++ stream interface into zlib.
Taken from zlib-1.1.3/contrib/iostream/.
Minor mods for STL compatibility.
There's no copyright associated with these so I assume they're
covered by zlib's.
fgstream.cxx
fgstream.hxx
FlightGear input stream using gz_ifstream. Tries to open the
given filename. If that fails then filename is examined and a
".gz" suffix is removed or appended and that file is opened.
stopwatch.hxx
A simple timer for benchmarking. Not used in production code.
Taken from the Blitz++ project. Covered by GPL.
strutils.cxx
strutils.hxx
Some simple string manipulation routines.
Simulator/Airports/
Load airports database using fgstream.
Changed fgAIRPORTS to use set<> instead of map<>.
Added bool fgAIRPORTS::search() as a neater way doing the lookup.
Returns true if found.
Simulator/Astro/
Modified fgStarsInit() to load stars database using fgstream.
Simulator/Objects/
Modified fgObjLoad() to use fgstream.
Modified fgMATERIAL_MGR::load_lib() to use fgstream.
Many changes to fgMATERIAL.
Some changes to fgFRAGMENT but I forget what!
#include <string>
#include <Debug/fg_debug.h>
-#include <Include/fg_zlib.h>
#include <Main/options.hxx>
+#include <Misc/fgstream.hxx>
+#include <Misc/stopwatch.hxx>
#include "simple.hxx"
+#include "Include/fg_stl_config.h"
+#include STL_FUNCTIONAL
+#include STL_ALGORITHM
-// Constructor
-fgAIRPORTS::fgAIRPORTS( void ) {
+fgAIRPORTS::fgAIRPORTS() {
}
// load the data
int fgAIRPORTS::load( const string& file ) {
- fgAIRPORT a;
- string path, fgpath, id;
- char id_raw[256], line[256];
- fgFile f;
-
// build the path name to the airport file
- path = current_options.get_fg_root() + "/Airports/" + file;
- fgpath = path + ".gz";
-
- // first try "path.gz"
- if ( (f = fgopen(fgpath.c_str(), "rb")) == NULL ) {
- // next try "path"
- if ( (f = fgopen(path.c_str(), "rb")) == NULL ) {
- fgPrintf( FG_GENERAL, FG_EXIT, "Cannot open file: %s\n",
- path.c_str());
- }
- }
+ string path = current_options.get_fg_root() + "/Airports/" + file;
+ StopWatch t;
- while ( fggets(f, line, 250) != NULL ) {
- // printf("%s", line);
+ airports.erase( airports.begin(), airports.end() );
- sscanf( line, "%s %lf %lf %lfl\n", id_raw, &a.longitude, &a.latitude,
- &a.elevation );
- id = id_raw;
- airports[id] = a;
- }
+ fg_gzifstream in( path );
+ if ( !in )
+ fgPrintf( FG_GENERAL, FG_EXIT, "Cannot open file: %s\n",
+ path.c_str());
+
+ t.start();
+
+ // We can use the STL copy algorithm because the input
+ // file doesn't contain and comments or blank lines.
+ copy( istream_iterator<fgAIRPORT,ptrdiff_t>(in.stream()),
+ istream_iterator<fgAIRPORT,ptrdiff_t>(),
+ inserter( airports, airports.begin() ) );
+
+ t.stop();
- fgclose(f);
+ fgPrintf( FG_GENERAL, FG_INFO, "Loaded %d airports in %f seconds\n",
+ airports.size(), t.elapsedSeconds() );
- return(1);
+ return 1;
}
+// class fgAIRPORT_eq : public unary_function<fgAIRPORT,bool>
+// {
+// public:
+// explicit fgAIRPORT_eq( const string& id ) : _id(id) {}
+// bool operator () ( const fgAIRPORT& a ) const { return a.id == _id; }
+// private:
+// string _id;
+// };
// search for the specified id
-fgAIRPORT fgAIRPORTS::search( char *id ) {
- map < string, fgAIRPORT, less<string> > :: iterator find;
- fgAIRPORT a;
-
- find = airports.find(id);
- if ( find == airports.end() ) {
- // not found
- a.longitude = a.latitude = a.elevation = 0;
- } else {
- a = (*find).second;
+bool
+fgAIRPORTS::search( const string& id, fgAIRPORT* a ) const
+{
+ StopWatch t;
+ t.start();
+// const_iterator it = find_if( airports.begin(),
+// airports.end(), fgAIRPORT_eq(id) );
+
+ const_iterator it = airports.find( fgAIRPORT(id) );
+ t.stop();
+ if ( it != airports.end() )
+ {
+ *a = *it;
+ cout << "Found " << id << " in " << t.elapsedSeconds()
+ << " seconds" << endl;
+ return true;
}
+ else
+ {
+ return false;
+ }
+}
- return(a);
+
+fgAIRPORT
+fgAIRPORTS::search( const string& id ) const
+{
+ fgAIRPORT a;
+ this->search( id, &a );
+ return a;
}
// $Log$
+// Revision 1.4 1998/09/01 19:02:53 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.3 1998/08/27 17:01:55 curt
// Contributions from Bernie Bright <bbright@c031.aone.net.au>
// - use strings for fg_root and airport_id and added methods to return
#include <string> // Standard C++ string library
-#include <map> // STL associative "array"
+#include <set>
#ifdef NEEDNAMESPACESTD
using namespace std;
#endif
-typedef struct {
- // char id[5];
+class fgAIRPORT {
+public:
+ fgAIRPORT( const string& name = "",
+ double lon = 0.0,
+ double lat = 0.0,
+ double ele = 0.0 )
+ : id(name), longitude(lon), latitude(lat), elevation(ele) {}
+
+ bool operator < ( const fgAIRPORT& a ) const {
+ return id < a.id;
+ }
+
+public:
+ string id;
double longitude;
double latitude;
double elevation;
-} fgAIRPORT;
+};
+inline istream&
+operator >> ( istream& in, fgAIRPORT& a )
+{
+ return in >> a.id >> a.longitude >> a.latitude >> a.elevation;
+}
class fgAIRPORTS {
- map < string, fgAIRPORT, less<string> > airports;
+public:
+ typedef set< fgAIRPORT > container;
+ typedef container::iterator iterator;
+ typedef container::const_iterator const_iterator;
+
+private:
+ container airports;
public:
// Constructor
- fgAIRPORTS( void );
+ fgAIRPORTS();
+
+ // Destructor
+ ~fgAIRPORTS();
// load the data
int load( const string& file );
- // search for the specified id
- fgAIRPORT search( char *id );
-
- // Destructor
- ~fgAIRPORTS( void );
-
+ // search for the specified id.
+ // Returns true if successful, otherwise returns false.
+ // On success, airport data is returned thru "airport" pointer.
+ // "airport" is not changed if "id" is not found.
+ bool search( const string& id, fgAIRPORT* airport ) const;
+ fgAIRPORT search( const string& id ) const;
};
// $Log$
+// Revision 1.3 1998/09/01 19:02:54 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.2 1998/08/27 17:01:56 curt
// Contributions from Bernie Bright <bbright@c031.aone.net.au>
// - use strings for fg_root and airport_id and added methods to return
#include <Debug/fg_debug.h>
#include <Include/fg_constants.h>
#include <Include/fg_types.h>
-#include <Include/fg_zlib.h>
+#include "Misc/fgstream.hxx"
#include <Main/options.hxx>
#include <Main/views.hxx>
+#include <Misc/stopwatch.hxx>
#include <Time/fg_time.hxx>
#include "orbits.hxx"
/* Initialize the Star Management Subsystem */
int fgStarsInit( void ) {
fgPoint3d starlist[FG_MAX_STARS];
- fgFile fd;
/* struct CelestialCoord pltPos; */
- string path, gzpath;
- char line[256], name[256];
- char *front, *end;
double right_ascension, declination, magnitude;
double min_magnitude[FG_STAR_LEVELS];
/* double ra_save, decl_save; */
fgPrintf( FG_ASTRO, FG_INFO, "Initializing stars\n");
- /* build the full path name to the stars data base file */
- path = current_options.get_fg_root() + "/Astro/stars";
- gzpath = path + ".gz";
-
if ( FG_STAR_LEVELS < 4 ) {
fgPrintf( FG_ASTRO, FG_EXIT, "Big whups in stars.cxx\n");
}
+ // build the full path name to the stars data base file
+ string path = current_options.get_fg_root() + "/Astro/stars" + ".gz";
+
fgPrintf( FG_ASTRO, FG_INFO, " Loading stars from %s\n", path.c_str() );
- // load star data file
- if ( (fd = fgopen(path.c_str(), "rb")) == NULL ) {
- if ( (fd = fgopen(gzpath.c_str(), "rb")) == NULL ) {
- // Oops, lets not even try to continue. This is critical.
- fgPrintf( FG_ASTRO, FG_EXIT,
- "Cannot open star file: '%s'\n", path.c_str() );
- }
- }
+ fg_gzifstream in( path );
+ if ( ! in )
+ fgPrintf( FG_ASTRO, FG_EXIT,
+ "Cannot open star file: '%s'\n", path.c_str() );
starcount = 0;
- // read in each line of the file
- while ( (fggets(fd, line, 256) != NULL) && (starcount < FG_MAX_STARS) ) {
- front = line;
-
- // printf(" Read line = %s", front);
+ StopWatch timer;
+ timer.start();
- // advance to first non-whitespace character
- while ( (front[0] == ' ') || (front[0] == '\t') ) {
- front++;
- }
-
- // printf(" Line length (after trimming) = %d\n", strlen(front));
-
- if ( front[0] == '#' ) {
- // comment
- } else if ( strlen(front) <= 1 ) {
- // blank line
- } else {
- // star data line
-
- // get name
- end = front;
- while ( end[0] != ',' ) {
- end++;
- }
- end[0] = '\0';
- strcpy(name, front);
- front = end;
- front++;
-
- sscanf(front, "%lf,%lf,%lf\n",
- &right_ascension, &declination, &magnitude);
- starlist[starcount].x = right_ascension;
- starlist[starcount].y = declination;
- starlist[starcount].z = magnitude;
- starcount++;
- }
+ // read in each line of the file
+ while ( ! in.eof() && starcount < FG_MAX_STARS )
+ {
+ in.eat_comments();
+ string name;
+ char c = 0;
+ getline( in.stream(), name, ',' );
+ in.stream() >> starlist[starcount].x >> c;
+ in.stream() >> starlist[starcount].y >> c;
+// in.stream() >> starlist[starcount].x; in.get(c);
+// in.stream() >> starlist[starcount].y; in.get(c);
+ in.stream() >> starlist[starcount].z;
+ ++starcount;
}
+ timer.stop();
+ cerr << "Loaded " << starcount << " stars in "
+ << timer.elapsedSeconds() << " seconds" << endl;
+
min_magnitude[0] = 4.2;
min_magnitude[1] = 3.6;
min_magnitude[2] = 3.0;
/* $Log$
-/* Revision 1.12 1998/08/27 17:02:01 curt
-/* Contributions from Bernie Bright <bbright@c031.aone.net.au>
-/* - use strings for fg_root and airport_id and added methods to return
-/* them as strings,
-/* - inlined all access methods,
-/* - made the parsing functions private methods,
-/* - deleted some unused functions.
-/* - propogated some of these changes out a bit further.
+/* Revision 1.13 1998/09/01 19:03:04 curt
+/* Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+/* - The new classes in libmisc.tgz define a stream interface into zlib.
+/* I've put these in a new directory, Lib/Misc. Feel free to rename it
+/* to something more appropriate. However you'll have to change the
+/* include directives in all the other files. Additionally you'll have
+/* add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+/*
+/* The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+/* test so I've included the required changes in config.tgz.
+/*
+/* There are a fair few changes to Simulator/Objects as I've moved
+/* things around. Loading tiles is quicker but thats not where the delay
+/* is. Tile loading takes a few tenths of a second per file on a P200
+/* but it seems to be the post-processing that leads to a noticeable
+/* blip in framerate. I suppose its time to start profiling to see where
+/* the delays are.
+/*
+/* I've included a brief description of each archives contents.
+/*
+/* Lib/Misc/
+/* zfstream.cxx
+/* zfstream.hxx
+/* C++ stream interface into zlib.
+/* Taken from zlib-1.1.3/contrib/iostream/.
+/* Minor mods for STL compatibility.
+/* There's no copyright associated with these so I assume they're
+/* covered by zlib's.
+/*
+/* fgstream.cxx
+/* fgstream.hxx
+/* FlightGear input stream using gz_ifstream. Tries to open the
+/* given filename. If that fails then filename is examined and a
+/* ".gz" suffix is removed or appended and that file is opened.
/*
+/* stopwatch.hxx
+/* A simple timer for benchmarking. Not used in production code.
+/* Taken from the Blitz++ project. Covered by GPL.
+/*
+/* strutils.cxx
+/* strutils.hxx
+/* Some simple string manipulation routines.
+/*
+/* Simulator/Airports/
+/* Load airports database using fgstream.
+/* Changed fgAIRPORTS to use set<> instead of map<>.
+/* Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+/* Returns true if found.
+/*
+/* Simulator/Astro/
+/* Modified fgStarsInit() to load stars database using fgstream.
+/*
+/* Simulator/Objects/
+/* Modified fgObjLoad() to use fgstream.
+/* Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+/* Many changes to fgMATERIAL.
+/* Some changes to fgFRAGMENT but I forget what!
+/*
+ * Revision 1.12 1998/08/27 17:02:01 curt
+ * Contributions from Bernie Bright <bbright@c031.aone.net.au>
+ * - use strings for fg_root and airport_id and added methods to return
+ * them as strings,
+ * - inlined all access methods,
+ * - made the parsing functions private methods,
+ * - deleted some unused functions.
+ * - propogated some of these changes out a bit further.
+ *
* Revision 1.11 1998/08/25 20:53:29 curt
* Shuffled $FG_ROOT file layout.
*
$(top_builddir)/Lib/Bucket/libBucket.a \
$(top_builddir)/Lib/Debug/libDebug.a \
$(top_builddir)/Lib/PUI/libPUI.a \
- $(top_builddir)/Lib/zlib/libz.a
+ $(top_builddir)/Lib/zlib/libz.a \
+ $(top_builddir)/Lib/Misc/libMisc.a
INCLUDES += \
-I$(top_builddir) \
#include "fragment.hxx"
-// return the sign of a value
-#define FG_SIGN( x ) ((x) < 0 ? -1 : 1)
-
-// return min or max of two values
-#define FG_MIN(A,B) ((A) < (B) ? (A) : (B))
-#define FG_MAX(A,B) ((A) > (B) ? (A) : (B))
-
-
-fgFACE :: fgFACE () :
- n1(0), n2(0), n3(0)
-{
+template <class T>
+inline const int FG_SIGN(const T& x) {
+ return x < T(0) ? -1 : 1;
}
-fgFACE :: ~fgFACE()
-{
-}
-
-fgFACE :: fgFACE( const fgFACE & image ) :
- n1( image.n1), n2( image.n2), n3( image.n3)
-{
+template <class T>
+inline const T& FG_MIN(const T& a, const T& b) {
+ return b < a ? b : a;
}
-bool fgFACE :: operator < (const fgFACE & rhs )
-{
- return ( n1 < rhs.n1 ? true : false);
+template <class T>
+inline const T& FG_MAX(const T& a, const T& b) {
+ return a < b ? b : a;
}
-bool fgFACE :: operator == (const fgFACE & rhs )
+// return the minimum of the three values
+template <class T>
+inline const T& fg_min3( const T& a, const T& b, const T& c)
{
- return ((n1 == rhs.n1) && (n2 == rhs.n2) && ( n3 == rhs.n3));
+ return (a > b ? FG_MIN (b, c) : FG_MIN (a, c));
}
-// Constructor
-fgFRAGMENT::fgFRAGMENT ( void ) {
+// return the maximum of the three values
+template <class T>
+inline const T& fg_max3 (const T& a, const T& b, const T& c)
+{
+ return (a < b ? FG_MAX (b, c) : FG_MAX (a, c));
}
-
+// Add a face to the face list
// Copy constructor
-fgFRAGMENT :: fgFRAGMENT ( const fgFRAGMENT & rhs ) :
+fgFRAGMENT::fgFRAGMENT ( const fgFRAGMENT & rhs ) :
center ( rhs.center ),
bounding_radius( rhs.bounding_radius ),
material_ptr ( rhs.material_ptr ),
{
}
-fgFRAGMENT & fgFRAGMENT :: operator = ( const fgFRAGMENT & rhs )
+fgFRAGMENT & fgFRAGMENT::operator = ( const fgFRAGMENT & rhs )
{
if(!(this == &rhs )) {
center = rhs.center;
}
-// Add a face to the face list
-void fgFRAGMENT::add_face(int n1, int n2, int n3) {
- fgFACE face;
-
- face.n1 = n1;
- face.n2 = n2;
- face.n3 = n3;
-
- faces.push_back(face);
- num_faces++;
-}
-
-
-// return the minimum of the three values
-static double fg_min3 (double a, double b, double c)
-{
- return (a > b ? FG_MIN (b, c) : FG_MIN (a, c));
-}
-
-
-// return the maximum of the three values
-static double fg_max3 (double a, double b, double c)
-{
- return (a < b ? FG_MAX (b, c) : FG_MAX (a, c));
-}
-
-
// test if line intesects with this fragment. p0 and p1 are the two
// line end points of the line. If side_flag is true, check to see
// that end points are on opposite sides of face. Returns 1 if it
// intersection found, 0 otherwise. If it intesects, result is the
// point of intersection
-int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
- fgPoint3d *result)
+int fgFRAGMENT::intersect( const fgPoint3d *end0,
+ const fgPoint3d *end1,
+ int side_flag,
+ fgPoint3d *result) const
{
fgTILE *t;
fgFACE face;
double xmin, xmax, ymin, ymax, zmin, zmax;
double dx, dy, dz, min_dim, x2, y2, x3, y3, rx, ry;
int side1, side2;
- list < fgFACE > :: iterator current;
- list < fgFACE > :: iterator last;
// find the associated tile
t = tile_ptr;
// printf("Intersecting\n");
// traverse the face list for this fragment
- current = faces.begin();
- last = faces.end();
+ const_iterator current = faces.begin();
+ const_iterator last = faces.end();
while ( current != last ) {
face = *current;
current++;
return(0);
}
-
-// Destructor
-fgFRAGMENT::~fgFRAGMENT ( void ) {
- // Step through the face list deleting the items until the list is
- // empty
-
- // printf("destructing a fragment with %d faces\n", faces.size());
-
- while ( faces.size() ) {
- // printf("emptying face list\n");
- faces.pop_front();
- }
-}
-
-
-// equality operator
-bool fgFRAGMENT :: operator == ( const fgFRAGMENT & rhs)
-{
- if(( center.x - rhs.center.x ) < FG_EPSILON) {
- if(( center.y - rhs.center.y) < FG_EPSILON) {
- if(( center.z - rhs.center.z) < FG_EPSILON) {
- return true;
- }
- }
- }
- return false;
-}
-
-// comparison operator
-bool fgFRAGMENT :: operator < ( const fgFRAGMENT &rhs)
-{
- // This is completely arbitrary. It satisfies RW's STL implementation
-
- return bounding_radius < rhs.bounding_radius;
-}
-
-
// $Log$
+// Revision 1.2 1998/09/01 19:03:07 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.1 1998/08/25 16:51:23 curt
// Moved from ../Scenery
//
#include <Bucket/bucketutils.h>
#include <Include/fg_types.h>
+#include "Include/fg_constants.h"
#include <Math/mat3.h>
#ifdef NEEDNAMESPACESTD
public:
int n1, n2, n3;
- fgFACE();
- ~fgFACE();
- fgFACE( const fgFACE & image );
- bool operator < ( const fgFACE & rhs );
- bool operator == ( const fgFACE & rhs );
+ explicit fgFACE( int a = 0, int b =0, int c =0 )
+ : n1(a), n2(b), n3(c) {}
+
+ fgFACE( const fgFACE & image )
+ : n1(image.n1), n2(image.n2), n3(image.n3) {}
+
+ ~fgFACE() {}
+
+ bool operator < ( const fgFACE & rhs ) { return n1 < rhs.n1; }
};
+inline bool
+operator == ( const fgFACE& lhs, const fgFACE & rhs )
+{
+ return (lhs.n1 == rhs.n1) && (lhs.n2 == rhs.n2) && (lhs.n3 == rhs.n3);
+}
// Object fragment data class
class fgFRAGMENT {
GLint display_list;
// face list (this indexes into the master tile vertex list)
- list < fgFACE > faces;
+ typedef list < fgFACE > container;
+ typedef container::iterator iterator;
+ typedef container::const_iterator const_iterator;
+
+ container faces;
// number of faces in this fragment
int num_faces;
// Add a face to the face list
- void add_face(int n1, int n2, int n3);
+ void add_face(int n1, int n2, int n3) {
+ faces.push_back( fgFACE(n1,n2,n3) );
+ num_faces++;
+ }
// test if line intesects with this fragment. p0 and p1 are the
// two line end points of the line. If side_flag is true, check
// to see that end points are on opposite sides of face. Returns
// 1 if it intersection found, 0 otherwise. If it intesects,
// result is the point of intersection
- int intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
- fgPoint3d *result);
+ int intersect( const fgPoint3d *end0,
+ const fgPoint3d *end1,
+ int side_flag,
+ fgPoint3d *result) const;
// Constructors
- fgFRAGMENT ();
+ fgFRAGMENT () {}
fgFRAGMENT ( const fgFRAGMENT &image );
// Destructor
- ~fgFRAGMENT ( );
+ ~fgFRAGMENT() { faces.erase( faces.begin(), faces.end() ); }
// operators
fgFRAGMENT & operator = ( const fgFRAGMENT & rhs );
- bool operator == ( const fgFRAGMENT & rhs );
- bool operator < ( const fgFRAGMENT & rhs );
+
+ bool operator < ( const fgFRAGMENT & rhs ) {
+ // This is completely arbitrary. It satisfies RW's STL implementation
+ return bounding_radius < rhs.bounding_radius;
+ }
+
+ void init() {
+ faces.erase( faces.begin(), faces.end() );
+ num_faces = 0;
+ }
+
+ void deleteDisplayList() {
+ xglDeleteLists( display_list, 1 );
+ }
};
+inline bool
+operator == ( const fgFRAGMENT & lhs, const fgFRAGMENT & rhs ) {
+ return (( lhs.center.x - rhs.center.x ) < FG_EPSILON &&
+ ( lhs.center.y - rhs.center.y ) < FG_EPSILON &&
+ ( lhs.center.z - rhs.center.z ) < FG_EPSILON );
+}
+
#endif // _FRAGMENT_HXX
// $Log$
+// Revision 1.2 1998/09/01 19:03:08 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.1 1998/08/25 16:51:23 curt
// Moved from ../Scenery
//
#include <string.h>
#include <Debug/fg_debug.h>
-#include <Include/fg_zlib.h>
#include <Main/options.hxx>
+#include <Misc/fgstream.hxx>
#include "material.hxx"
#include "texload.h"
// Constructor
fgMATERIAL::fgMATERIAL ( void ) {
+ alpha = 0;
+ ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0;
+ diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0;
+ specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
+ emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0;
}
-// Sorting routines
-void fgMATERIAL::init_sort_list( void ) {
+int fgMATERIAL::append_sort_list( fgFRAGMENT *object ) {
+ if ( list_size < FG_MAX_MATERIAL_FRAGS )
+ {
+ list[ list_size++ ] = object;
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
}
+istream&
+operator >> ( istream& in, fgMATERIAL& m )
+{
+ string token;
+
+ for (;;)
+ {
+ in >> token;
+ if ( token == "texture" )
+ {
+ in >> token >> m.texture_name;
+ }
+ else if ( token == "ambient" )
+ {
+ in >> token >> m.ambient[0] >> m.ambient[1]
+ >> m.ambient[2] >> m.ambient[3];
+ }
+ else if ( token == "diffuse" )
+ {
+ in >> token >> m.diffuse[0] >> m.diffuse[1]
+ >> m.diffuse[2] >> m.diffuse[3];
+ }
+ else if ( token == "specular" )
+ {
+ in >> token >> m.specular[0] >> m.specular[1]
+ >> m.specular[2] >> m.specular[3];
+ }
+ else if ( token == "emissive" )
+ {
+ in >> token >> m.emissive[0] >> m.emissive[1]
+ >> m.emissive[2] >> m.emissive[3];
+ }
+ else if ( token == "alpha" )
+ {
+ in >> token >> token;
+ if ( token == "yes" )
+ m.alpha = 1;
+ else if ( token == "no" )
+ m.alpha = 0;
+ else
+ {
+ fgPrintf( FG_TERRAIN, FG_INFO,
+ "Bad alpha value '%s'\n", token.c_str() );
+ }
+ }
+ else if ( token[0] == '}' )
+ {
+ break;
+ }
+ }
-int fgMATERIAL::append_sort_list( fgFRAGMENT *object ) {
- return(0);
+ return in;
+}
+
+void
+fgMATERIAL::load_texture()
+{
+ if ( current_options.get_textures() )
+ {
+ GLubyte *texbuf;
+ int width, height;
+
+ // create the texture object and bind it
+#ifdef GL_VERSION_1_1
+ xglGenTextures(1, &texture_id );
+ xglBindTexture(GL_TEXTURE_2D, texture_id );
+#elif GL_EXT_texture_object
+ xglGenTexturesEXT(1, &texture_id );
+ xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
+#else
+# error port me
+#endif
+
+ // set the texture parameters for this texture
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR );
+ // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ // GL_NEAREST_MIPMAP_NEAREST );
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ /* GL_LINEAR */
+ /* GL_NEAREST_MIPMAP_LINEAR */
+ GL_LINEAR_MIPMAP_LINEAR ) ;
+
+ /* load in the texture data */
+ string tpath = current_options.get_fg_root() + "/Textures/" +
+ texture_name + ".rgb";
+ string fg_tpath = tpath + ".gz";
+
+ if ( alpha == 0 ) {
+ // load rgb texture
+
+ // Try uncompressed
+ if ( (texbuf =
+ read_rgb_texture(tpath.c_str(), &width, &height)) ==
+ NULL )
+ {
+ // Try compressed
+ if ( (texbuf =
+ read_rgb_texture(fg_tpath.c_str(), &width, &height))
+ == NULL )
+ {
+ fgPrintf( FG_GENERAL, FG_EXIT,
+ "Error in loading texture %s\n",
+ tpath.c_str() );
+ return;
+ }
+ }
+
+ /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
+ GL_RGB, GL_UNSIGNED_BYTE, texbuf );
+ } else if ( alpha == 1 ) {
+ // load rgba (alpha) texture
+
+ // Try uncompressed
+ if ( (texbuf =
+ read_alpha_texture(tpath.c_str(), &width, &height))
+ == NULL )
+ {
+ // Try compressed
+ if ((texbuf =
+ read_alpha_texture(fg_tpath.c_str(), &width, &height))
+ == NULL )
+ {
+ fgPrintf( FG_GENERAL, FG_EXIT,
+ "Error in loading texture %s\n",
+ tpath.c_str() );
+ return;
+ }
+ }
+
+ xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
+ }
+ }
}
// Load a library of material properties
int fgMATERIAL_MGR::load_lib ( void ) {
- fgMATERIAL m;
- char material_name[256];
- string mpath, fg_mpath, tpath, fg_tpath;
- char line[256], *line_ptr, value[256];
- GLubyte *texbuf;
- fgFile f;
- int width, height;
- int alpha;
+ string material_name;
// build the path name to the material db
- mpath = current_options.get_fg_root() + "/materials";
- fg_mpath = mpath + ".gz";
-
- // first try "path.gz"
- if ( (f = fgopen(fg_mpath.c_str(), "rb")) == NULL ) {
- // next try "path"
- if ( (f = fgopen(mpath.c_str(), "rb")) == NULL ) {
- fgPrintf( FG_GENERAL, FG_EXIT, "Cannot open file: %s\n",
- mpath.c_str() );
- }
- }
+ string mpath = current_options.get_fg_root() + "/materials";
+ fg_gzifstream in( mpath );
+ if ( ! in )
+ fgPrintf( FG_GENERAL, FG_EXIT, "Cannot open file: %s\n",
+ mpath.c_str() );
- while ( fggets(f, line, 250) != NULL ) {
+ while ( ! in.eof() ) {
// printf("%s", line);
- // strip leading white space
- line_ptr = line;
- while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ) &&
- (line_ptr[0] != '\n') ) {
- line_ptr++;
-
- }
+ // strip leading white space and comments
+ in.eat_comments();
- if ( line_ptr[0] == '#' ) {
- // ignore lines that start with '#'
- } else if ( line_ptr[0] == '\n' ) {
- // ignore blank lines
- } else if ( strstr(line_ptr, "{") ) {
- // start of record
- alpha = 0;
- m.ambient[0] = m.ambient[1] = m.ambient[2] = m.ambient[3] = 0.0;
- m.diffuse[0] = m.diffuse[1] = m.diffuse[2] = m.diffuse[3] = 0.0;
- m.specular[0] = m.specular[1] = m.specular[2] = m.specular[3] = 0.0;
- m.emissive[0] = m.emissive[1] = m.emissive[2] = m.emissive[3] = 0.0;
-
- material_name[0] = '\0';
- sscanf(line_ptr, "%s", material_name);
- if ( ! strlen(material_name) ) {
- fgPrintf( FG_TERRAIN, FG_INFO, "Bad material name in '%s'\n",
- line );
- }
- printf(" Loading material = %s\n", material_name);
- } else if ( strncmp(line_ptr, "alpha", 5) == 0 ) {
- line_ptr += 5;
- while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
- (line_ptr[0] == '=') ) &&
- (line_ptr[0] != '\n') ) {
- line_ptr++;
- }
- sscanf(line_ptr, "%s\n", value);
- if ( strcmp(value, "no") == 0 ) {
- alpha = 0;
- } else if ( strcmp(value, "yes") == 0 ) {
- alpha = 1;
- } else {
- fgPrintf( FG_TERRAIN, FG_INFO, "Bad alpha value '%s'\n", line );
- }
- } else if ( (strncmp(line_ptr, "texture", 7) == 0) &&
- !current_options.get_textures() ) {
- // do nothing
- } else if ( strncmp(line_ptr, "texture", 7) == 0 ) {
- line_ptr += 7;
- while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
- (line_ptr[0] == '=') ) &&
- (line_ptr[0] != '\n') ) {
- line_ptr++;
- }
- // printf("texture name = %s\n", line_ptr);
- sscanf(line_ptr, "%s\n", m.texture_name);
+ // set to zero to prevent its value accidently being '{'
+ // after a failed >> operation.
+ char token = 0;
- // create the texture object and bind it
-#ifdef GL_VERSION_1_1
- xglGenTextures(1, &m.texture_id);
- xglBindTexture(GL_TEXTURE_2D, m.texture_id);
-#elif GL_EXT_texture_object
- xglGenTexturesEXT(1, &m.texture_id);
- xglBindTextureEXT(GL_TEXTURE_2D, m.texture_id);
-#else
-# error port me
-#endif
-
- // set the texture parameters for this texture
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- GL_LINEAR );
- // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- // GL_NEAREST_MIPMAP_NEAREST );
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- /* GL_LINEAR */
- /* GL_NEAREST_MIPMAP_LINEAR */
- GL_LINEAR_MIPMAP_LINEAR ) ;
-
- /* load in the texture data */
- tpath = current_options.get_fg_root() + "/Textures/" +
- m.texture_name + ".rgb";
- fg_tpath = tpath + ".gz";
-
- if ( alpha == 0 ) {
- // load rgb texture
-
- // Try uncompressed
- if ( (texbuf =
- read_rgb_texture(tpath.c_str(), &width, &height)) ==
- NULL )
- {
- // Try compressed
- if ( (texbuf =
- read_rgb_texture(fg_tpath.c_str(), &width, &height))
- == NULL )
- {
- fgPrintf( FG_GENERAL, FG_EXIT,
- "Error in loading texture %s\n",
- tpath.c_str() );
- return(0);
- }
- }
-
- /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
- GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
-
- gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
- GL_RGB, GL_UNSIGNED_BYTE, texbuf );
- } else if ( alpha == 1 ) {
- // load rgba (alpha) texture
+ in.stream() >> material_name >> token;
- // Try uncompressed
- if ( (texbuf =
- read_alpha_texture(tpath.c_str(), &width, &height))
- == NULL )
- {
- // Try compressed
- if ((texbuf =
- read_alpha_texture(fg_tpath.c_str(), &width, &height))
- == NULL )
- {
- fgPrintf( FG_GENERAL, FG_EXIT,
- "Error in loading texture %s\n",
- tpath.c_str() );
- return(0);
- }
- }
-
- xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
- }
-
- } else if ( strncmp(line_ptr, "ambient", 7) == 0 ) {
- line_ptr += 7;
- while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
- (line_ptr[0] == '=') ) &&
- (line_ptr[0] != '\n') ) {
- line_ptr++;
- }
- sscanf( line_ptr, "%f %f %f %f",
- &m.ambient[0], &m.ambient[1], &m.ambient[2], &m.ambient[3]);
- } else if ( strncmp(line_ptr, "diffuse", 7) == 0 ) {
- line_ptr += 7;
- while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
- (line_ptr[0] == '=') ) &&
- (line_ptr[0] != '\n') ) {
- line_ptr++;
- }
- sscanf( line_ptr, "%f %f %f %f",
- &m.diffuse[0], &m.diffuse[1], &m.diffuse[2], &m.diffuse[3]);
- } else if ( strncmp(line_ptr, "specular", 8) == 0 ) {
- line_ptr += 8;
- while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
- (line_ptr[0] == '=') ) &&
- (line_ptr[0] != '\n') ) {
- line_ptr++;
- }
- sscanf( line_ptr, "%f %f %f %f",
- &m.specular[0], &m.specular[1],
- &m.specular[2], &m.specular[3]);
- } else if ( strncmp(line_ptr, "emissive", 8) == 0 ) {
- line_ptr += 8;
- while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
- (line_ptr[0] == '=') ) &&
- (line_ptr[0] != '\n') ) {
- line_ptr++;
- }
- sscanf( line_ptr, "%f %f %f %f",
- &m.emissive[0], &m.emissive[1],
- &m.emissive[2], &m.emissive[3]);
- } else if ( line_ptr[0] == '}' ) {
- // end of record, lets add this one to the list
+ if ( token == '{' ) {
+ cout << "Loading material " << material_name << endl;
+ fgMATERIAL m;
+ in.stream() >> m;
material_mgr.material_map[material_name] = m;
- } else {
- fgPrintf(FG_TERRAIN, FG_INFO,
- "Unknown line in material properties file\n");
}
}
- fgclose(f);
+ for ( iterator it = material_map.begin();
+ it != material_map.end(); ++it )
+ {
+ it->second.load_texture();
+ }
return(1);
}
// Initialize the transient list of fragments for each material property
void fgMATERIAL_MGR::init_transient_material_lists( void ) {
- map < string, fgMATERIAL, less<string> > :: iterator mapcurrent =
- material_mgr.material_map.begin();
- map < string, fgMATERIAL, less<string> > :: iterator maplast =
- material_mgr.material_map.end();
-
- while ( mapcurrent != maplast ) {
- // (char *)key = (*mapcurrent).first;
- // (fgMATERIAL)value = (*mapcurrent).second;
- (*mapcurrent).second.list_size = 0;
+ for ( iterator it = material_map.begin();
+ it != material_map.end(); ++it )
+ {
+ it->second.init_sort_list();
+ }
+}
- *mapcurrent++;
+bool
+fgMATERIAL_MGR::find( const string& material, fgMATERIAL*& mtl_ptr )
+{
+ iterator it = material_map.find( material );
+ if ( it != material_map.end() )
+ {
+ mtl_ptr = &(it->second);
+ return true;
}
+
+ return false;
}
// $Log$
+// Revision 1.4 1998/09/01 19:03:08 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.3 1998/08/27 17:02:09 curt
// Contributions from Bernie Bright <bbright@c031.aone.net.au>
// - use strings for fg_root and airport_id and added methods to return
using namespace std;
#endif
-#include "fragment.hxx"
+// forward decl.
+class fgFRAGMENT;
#define FG_MAX_MATERIAL_FRAGS 800
GLuint texture_id;
// file name of texture
- char texture_name[256];
+ string texture_name;
+
+ // alpha texture?
+ int alpha;
// material properties
GLfloat ambient[4], diffuse[4], specular[4], emissive[4];
fgMATERIAL ( void );
// Sorting routines
- void init_sort_list( void );
+ void init_sort_list( void ) {
+ list_size = 0;
+ }
+
int append_sort_list( fgFRAGMENT *object );
+ void load_texture();
+
// Destructor
~fgMATERIAL ( void );
};
+istream& operator >> ( istream& in, fgMATERIAL& m );
// Material management class
class fgMATERIAL_MGR {
public:
// associative array of materials
- map < string, fgMATERIAL, less<string> > material_map;
+ typedef map < string, fgMATERIAL, less<string> > container;
+ typedef container::iterator iterator;
+ typedef container::const_iterator const_iterator;
+
+ container material_map;
// Constructor
fgMATERIAL_MGR ( void );
// Initialize the transient list of fragments for each material property
void init_transient_material_lists( void );
+ bool find( const string& material, fgMATERIAL*& mtl_ptr );
+
// Destructor
~fgMATERIAL_MGR ( void );
};
// $Log$
+// Revision 1.2 1998/09/01 19:03:09 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.1 1998/08/25 16:51:24 curt
// Moved from ../Scenery
//
#include <string> // Standard C++ library
#include <map> // STL
+#include <ctype.h> // isdigit()
#ifdef NEEDNAMESPACESTD
using namespace std;
#include <Math/mat3.h>
#include <Math/fg_random.h>
#include <Math/polar3d.hxx>
+#include <Misc/stopwatch.hxx>
+#include <Misc/fgstream.hxx>
#include <Scenery/tile.hxx>
#include "material.hxx"
// Load a .obj file and build the GL fragment list
-int fgObjLoad(char *path, fgTILE *t) {
+int fgObjLoad( const string& path, fgTILE *t) {
fgFRAGMENT fragment;
fgPoint3d pp;
- char fgpath[256], line[256], material[256];
double approx_normal[3], normal[3], scale;
// double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin;
// GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
GLint display_list;
- fgFile f;
int shading;
int in_fragment, in_faces, vncount, n1, n2, n3, n4;
int last1, last2, odd;
double (*nodes)[3];
fgPoint3d *center;
- // First try "path.gz" (compressed format)
- strcpy(fgpath, path);
- strcat(fgpath, ".gz");
- if ( (f = fgopen(fgpath, "rb")) == NULL ) {
- // Next try "path" (uncompressed format)
- strcpy(fgpath, path);
- if ( (f = fgopen(fgpath, "rb")) == NULL ) {
- // Next try "path.obj" (uncompressed format)
- strcat(fgpath, ".gz");
- if ( (f = fgopen(fgpath, "rb")) == NULL ) {
- strcpy(fgpath, path);
- fgPrintf( FG_TERRAIN, FG_ALERT,
- "Cannot open file: %s\n", fgpath );
- return(0);
- }
+ // Attempt to open "path.gz" or "path"
+ fg_gzifstream in( path );
+ if ( ! in )
+ {
+ // Attempt to open "path.obj" or "path.obj.gz"
+ in.open( path + ".obj" );
+ if ( ! in )
+ {
+ fgPrintf( FG_TERRAIN, FG_ALERT,
+ "Cannot open file: %s\n", path.c_str() );
+ return 0;
}
}
nodes = t->nodes;
center = &t->center;
- while ( fggets(f, line, 250) != NULL ) {
- if ( line[0] == '#' ) {
- // comment -- ignore
- } else if ( line[0] == '\n' ) {
- // empty line -- ignore
- } else if ( strncmp(line, "gbs ", 4) == 0 ) {
+ StopWatch stopwatch;
+ stopwatch.start();
+ while ( ! in.eof() )
+ {
+ // ignore comments and blank lines.
+ in.eat_comments();
+
+ string token;
+ in.stream() >> token;
+ if ( token == "gbs" )
+ {
// reference point (center offset)
- sscanf(line, "gbs %lf %lf %lf %lf\n",
- &t->center.x, &t->center.y, &t->center.z,
- &t->bounding_radius);
- } else if ( strncmp(line, "bs ", 3) == 0 ) {
+ in.stream() >> t->center.x
+ >> t->center.y
+ >> t->center.z
+ >> t->bounding_radius;
+ }
+ else if ( token == "bs" )
+ {
// reference point (center offset)
- sscanf(line, "bs %lf %lf %lf %lf\n",
- &fragment.center.x, &fragment.center.y, &fragment.center.z,
- &fragment.bounding_radius);
- } else if ( strncmp(line, "v ", 2) == 0 ) {
- // node (vertex)
- if ( t->ncount < MAX_NODES ) {
- // fgPrintf( FG_TERRAIN, FG_DEBUG, "vertex = %s", line);
- sscanf(line, "v %lf %lf %lf\n",
- &(t->nodes[t->ncount][0]), &(t->nodes[t->ncount][1]),
- &(t->nodes[t->ncount][2]));
-
- t->ncount++;
-
- } else {
- fgPrintf( FG_TERRAIN, FG_EXIT,
- "Read too many nodes ... dying :-(\n");
- }
- } else if ( strncmp(line, "vn ", 3) == 0 ) {
+ in.stream() >> fragment.center.x
+ >> fragment.center.y
+ >> fragment.center.z
+ >> fragment.bounding_radius;
+ }
+ else if ( token == "vn" )
+ {
// vertex normal
if ( vncount < MAX_NODES ) {
- // fgPrintf( FG_TERRAIN, FG_DEBUG, "vertex normal = %s", line);
- sscanf(line, "vn %lf %lf %lf\n",
- &normals[vncount][0], &normals[vncount][1],
- &normals[vncount][2]);
+ in.stream() >> normals[vncount][0]
+ >> normals[vncount][1]
+ >> normals[vncount][2];
vncount++;
} else {
fgPrintf( FG_TERRAIN, FG_EXIT,
"Read too many vertex normals ... dying :-(\n");
}
- } else if ( strncmp(line, "usemtl ", 7) == 0 ) {
+ }
+ else if ( token[0] == 'v' )
+ {
+ // node (vertex)
+ if ( t->ncount < MAX_NODES ) {
+ in.stream() >> t->nodes[t->ncount][0]
+ >> t->nodes[t->ncount][1]
+ >> t->nodes[t->ncount][2];
+ t->ncount++;
+ } else {
+ fgPrintf( FG_TERRAIN, FG_EXIT,
+ "Read too many nodes ... dying :-(\n");
+ }
+ }
+ else if ( token == "usemtl" )
+ {
// material property specification
// this also signals the start of a new fragment
// reset the existing face list
// printf("cleaning a fragment with %d faces\n",
// fragment.faces.size());
- while ( fragment.faces.size() ) {
- // printf("emptying face list\n");
- fragment.faces.pop_front();
- }
+ fragment.init();
// scan the material line
- sscanf(line, "usemtl %s\n", material);
-
- // give the fragment a pointer back to the tile
+ string material;
+ in.stream() >> material;
fragment.tile_ptr = t;
// find this material in the properties list
- map < string, fgMATERIAL, less<string> > :: iterator myfind =
- material_mgr.material_map.find(material);
- if ( myfind == material_mgr.material_map.end() ) {
+ if ( ! material_mgr.find( material, fragment.material_ptr )) {
fgPrintf( FG_TERRAIN, FG_ALERT,
"Ack! unknown usemtl name = %s in %s\n",
- material, path);
- } else {
- fragment.material_ptr = &((*myfind).second);
+ material.c_str(), path.c_str() );
}
// initialize the fragment transformation matrix
fragment.matrix[0] = fragment.matrix[5] =
fragment.matrix[10] = fragment.matrix[15] = 1.0;
*/
-
- // initialize fragment face counter
- fragment.num_faces = 0;
-
- } else if ( line[0] == 't' ) {
+ } else if ( token[0] == 't' ) {
// start a new triangle strip
n1 = n2 = n3 = n4 = 0;
// fgPrintf( FG_TERRAIN, FG_DEBUG, " new tri strip = %s", line);
- sscanf(line, "t %d %d %d %d\n", &n1, &n2, &n3, &n4);
-
+ in.stream() >> n1 >> n2 >> n3;
fragment.add_face(n1, n2, n3);
// fgPrintf( FG_TERRAIN, FG_DEBUG, "(t) = ");
last1 = n3;
last2 = n4;
}
- } else if ( line[0] == 'f' ) {
+ } else if ( token[0] == 'f' ) {
// unoptimized face
if ( !in_faces ) {
}
// fgPrintf( FG_TERRAIN, FG_DEBUG, "new triangle = %s", line);*/
- sscanf(line, "f %d %d %d\n", &n1, &n2, &n3);
-
+ in.stream() >> n1 >> n2 >> n3;
fragment.add_face(n1, n2, n3);
// xglNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
xglTexCoord2f(pp.lon, pp.lat);
// xglVertex3d(t->nodes[n3][0], t->nodes[n3][1], t->nodes[n3][2]);
xglVertex3dv(nodes[n3]);
- } else if ( line[0] == 'q' ) {
+ } else if ( token[0] == 'q' ) {
// continue a triangle strip
n1 = n2 = 0;
// fgPrintf( FG_TERRAIN, FG_DEBUG, "continued tri strip = %s ",
// line);
- sscanf(line, "q %d %d\n", &n1, &n2);
+ in.stream() >> n1;
+
+ // There can be one or two values
+ char c;
+ while ( in.get(c) )
+ {
+ if ( c == '\n' )
+ break; // only the one
+
+ if ( isdigit(c) )
+ {
+ in.putback(c);
+ in.stream() >> n2;
+ break;
+ }
+ }
// fgPrintf( FG_TERRAIN, FG_DEBUG, "read %d %d\n", n1, n2);
if ( odd ) {
last2 = n2;
}
} else {
- fgPrintf( FG_TERRAIN, FG_WARN, "Unknown line in %s = %s\n",
- path, line);
+ fgPrintf( FG_TERRAIN, FG_WARN, "Unknown token in %s = %s\n",
+ path.c_str(), token.c_str() );
}
}
+ stopwatch.stop();
+ fgPrintf( FG_TERRAIN, FG_INFO, "Loaded %s in %f seconds\n",
+ path.c_str(), stopwatch.elapsedSeconds() );
if ( in_fragment ) {
// close out the previous structure and start the next
xglEnd();
*/
- fgclose(f);
-
return(1);
}
// $Log$
+// Revision 1.2 1998/09/01 19:03:09 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.1 1998/08/25 16:51:25 curt
// Moved from ../Scenery
//
#include <GL/glut.h>
+#include <string>
+
#include <Include/fg_types.h>
#include <Scenery/tile.hxx>
// Load a .obj file and build the GL fragment list
-int fgObjLoad(char *path, fgTILE *tile);
+int fgObjLoad(const string& path, fgTILE *tile);
#endif // _OBJ_HXX
// $Log$
+// Revision 1.2 1998/09/01 19:03:10 curt
+// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
+// - The new classes in libmisc.tgz define a stream interface into zlib.
+// I've put these in a new directory, Lib/Misc. Feel free to rename it
+// to something more appropriate. However you'll have to change the
+// include directives in all the other files. Additionally you'll have
+// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
+//
+// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
+// test so I've included the required changes in config.tgz.
+//
+// There are a fair few changes to Simulator/Objects as I've moved
+// things around. Loading tiles is quicker but thats not where the delay
+// is. Tile loading takes a few tenths of a second per file on a P200
+// but it seems to be the post-processing that leads to a noticeable
+// blip in framerate. I suppose its time to start profiling to see where
+// the delays are.
+//
+// I've included a brief description of each archives contents.
+//
+// Lib/Misc/
+// zfstream.cxx
+// zfstream.hxx
+// C++ stream interface into zlib.
+// Taken from zlib-1.1.3/contrib/iostream/.
+// Minor mods for STL compatibility.
+// There's no copyright associated with these so I assume they're
+// covered by zlib's.
+//
+// fgstream.cxx
+// fgstream.hxx
+// FlightGear input stream using gz_ifstream. Tries to open the
+// given filename. If that fails then filename is examined and a
+// ".gz" suffix is removed or appended and that file is opened.
+//
+// stopwatch.hxx
+// A simple timer for benchmarking. Not used in production code.
+// Taken from the Blitz++ project. Covered by GPL.
+//
+// strutils.cxx
+// strutils.hxx
+// Some simple string manipulation routines.
+//
+// Simulator/Airports/
+// Load airports database using fgstream.
+// Changed fgAIRPORTS to use set<> instead of map<>.
+// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
+// Returns true if found.
+//
+// Simulator/Astro/
+// Modified fgStarsInit() to load stars database using fgstream.
+//
+// Simulator/Objects/
+// Modified fgObjLoad() to use fgstream.
+// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
+// Many changes to fgMATERIAL.
+// Some changes to fgFRAGMENT but I forget what!
+//
// Revision 1.1 1998/08/25 16:51:26 curt
// Moved from ../Scenery
//