obj.cxx obj.hxx \
scenery.cxx scenery.hxx \
texload.c texload.h \
+ tile.cxx tile.hxx \
tilecache.cxx tilecache.hxx \
tilemgr.cxx tilemgr.hxx
obj.cxx obj.hxx \
scenery.cxx scenery.hxx \
texload.c texload.h \
+ tile.cxx tile.hxx \
tilecache.cxx tilecache.hxx \
tilemgr.cxx tilemgr.hxx
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
X_PRE_LIBS = @X_PRE_LIBS@
libScenery_la_LDFLAGS =
libScenery_la_LIBADD =
-libScenery_la_OBJECTS = obj.lo scenery.lo texload.lo tilecache.lo \
-tilemgr.lo
+libScenery_la_OBJECTS = obj.lo scenery.lo texload.lo tile.lo \
+tilecache.lo tilemgr.lo
CXXFLAGS = @CXXFLAGS@
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS)
TAR = tar
GZIP = --best
-DEP_FILES = .deps/obj.P .deps/scenery.P .deps/texload.P \
+DEP_FILES = .deps/obj.P .deps/scenery.P .deps/texload.P .deps/tile.P \
.deps/tilecache.P .deps/tilemgr.P
CXXMKDEP = $(CXX) -M $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS)
SOURCES = $(libScenery_la_SOURCES)
#include "obj.hxx"
#include "scenery.hxx"
+#include "tile.hxx"
#define MAXNODES 100000
}
-// Calculate distance between (0,0,0) and the specified point
-static double calc_dist(double *p) {
- return ( sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]) );
-}
-
-
-/* Load a .obj file and generate the GL call list */
-GLint fgObjLoad(char *path, fgCartesianPoint3d *ref, double *radius) {
+/* Load a .obj file and build the GL fragment list */
+int fgObjLoad(char *path, fgTILE *tile) {
fgOPTIONS *o;
+ fgFRAGMENT fragment;
fgPolarPoint3d 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 tile;
+ GLint display_list;
fgFile f;
int first, ncount, vncount, n1, n2, n3, n4;
int last1, last2, odd;
strcat(fgpath, ".obj");
fgPrintf( FG_TERRAIN, FG_ALERT,
"Cannot open file: %s\n", fgpath );
- return(-1);
+ return(0);
}
}
}
- tile = xglGenLists(1);
- xglNewList(tile, GL_COMPILE);
+ display_list = xglGenLists(1);
+ xglNewList(display_list, GL_COMPILE);
first = 1;
ncount = 1;
vncount = 1;
- *radius = 0.0;
+ tile->bounding_radius = 0.0;
while ( fggets(f, line, 250) != NULL ) {
if ( line[0] == '#' ) {
/* empty line -- ignore */
} else if ( strncmp(line, "gb ", 3) == 0 ) {
/* reference point (center offset) */
- sscanf(line, "gb %lf %lf %lf %lf\n", &ref->x, &ref->y, &ref->z,
- radius);
+ sscanf(line, "gb %lf %lf %lf %lf\n",
+ &tile->center.x, &tile->center.y, &tile->center.z,
+ &tile->bounding_radius);
} else if ( strncmp(line, "v ", 2) == 0 ) {
/* node (vertex) */
if ( ncount < MAXNODES ) {
// (averaged) normals
MAT3_SCALE_VEC(normal, normals[n1], scale);
xglNormal3dv(normal);
- pp = calc_tex_coords(nodes[n1], ref);
+ pp = calc_tex_coords(nodes[n1], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
MAT3_SCALE_VEC(normal, normals[n2], scale);
xglNormal3dv(normal);
- pp = calc_tex_coords(nodes[n2], ref);
+ pp = calc_tex_coords(nodes[n2], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
MAT3_SCALE_VEC(normal, normals[n3], scale);
xglNormal3dv(normal);
- pp = calc_tex_coords(nodes[n3], ref);
+ pp = calc_tex_coords(nodes[n3], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n3][0], nodes[n3][1], nodes[n3][2]);
} else {
MAT3_SCALE_VEC(normal, approx_normal, scale);
xglNormal3dv(normal);
- pp = calc_tex_coords(nodes[n1], ref);
+ pp = calc_tex_coords(nodes[n1], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
- pp = calc_tex_coords(nodes[n2], ref);
+ pp = calc_tex_coords(nodes[n2], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
- pp = calc_tex_coords(nodes[n3], ref);
+ pp = calc_tex_coords(nodes[n3], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n3][0], nodes[n3][1], nodes[n3][2]);
}
MAT3_SCALE_VEC(normal, approx_normal, scale);
}
xglNormal3dv(normal);
- pp = calc_tex_coords(nodes[n4], ref);
+ pp = calc_tex_coords(nodes[n4], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n4][0], nodes[n4][1], nodes[n4][2]);
sscanf(line, "f %d %d %d\n", &n1, &n2, &n3);
xglNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
- pp = calc_tex_coords(nodes[n1], ref);
+ pp = calc_tex_coords(nodes[n1], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
xglNormal3d(normals[n2][0], normals[n2][1], normals[n2][2]);
- pp = calc_tex_coords(nodes[n2], ref);
+ pp = calc_tex_coords(nodes[n2], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
xglNormal3d(normals[n3][0], normals[n3][1], normals[n3][2]);
- pp = calc_tex_coords(nodes[n3], ref);
+ pp = calc_tex_coords(nodes[n3], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n3][0], nodes[n3][1], nodes[n3][2]);
} else if ( line[0] == 'q' ) {
xglNormal3dv(normal);
}
- pp = calc_tex_coords(nodes[n1], ref);
+ pp = calc_tex_coords(nodes[n1], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
xglNormal3dv(normal);
}
- pp = calc_tex_coords(nodes[n2], ref);
+ pp = calc_tex_coords(nodes[n2], &tile->center);
xglTexCoord2f(pp.lon, pp.lat);
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
fgclose(f);
- /* reference point is the "center" (now included in input file) */
- /*
- ref->x = (xmin + xmax) / 2.0;
- ref->y = (ymin + ymax) / 2.0;
- ref->z = (zmin + zmax) / 2.0;
- */
+ // temporary: create a fragment
+ fragment.center = tile->center;
+ fragment.bounding_radius = tile->bounding_radius;
+ fragment.display_list = display_list;
+
+ // temporary: push this fragment onto the tile's object list
+ tile->fragment_list.push_back(fragment);
- return(tile);
+ return(1);
}
/* $Log$
-/* Revision 1.5 1998/05/20 20:53:53 curt
-/* Moved global ref point and radius (bounding sphere info, and offset) to
-/* data file rather than calculating it on the fly.
-/* Fixed polygon winding problem in scenery generation stage rather than
-/* compensating for it on the fly.
-/* Made a fgTILECACHE class.
+/* Revision 1.6 1998/05/23 14:09:20 curt
+/* Added tile.cxx and tile.hxx.
+/* Working on rewriting the tile management system so a tile is just a list
+/* fragments, and the fragment record contains the display list for that fragment.
/*
+ * Revision 1.5 1998/05/20 20:53:53 curt
+ * Moved global ref point and radius (bounding sphere info, and offset) to
+ * data file rather than calculating it on the fly.
+ * Fixed polygon winding problem in scenery generation stage rather than
+ * compensating for it on the fly.
+ * Made a fgTILECACHE class.
+ *
* Revision 1.4 1998/05/16 13:09:57 curt
* Beginning to add support for view frustum culling.
* Added some temporary code to calculate bouding radius, until the
#include <Include/fg_types.h>
+#include "tile.hxx"
-/* Load a .obj file and generate the GL call list */
-GLint fgObjLoad(char *path, fgCartesianPoint3d *ref, double *radius);
+
+/* Load a .obj file and build the GL fragment list */
+int fgObjLoad(char *path, fgTILE *tile);
+// GLint fgObjLoad(char *path, fgCartesianPoint3d *ref, double *radius) {
#endif /* _OBJ_HXX */
/* $Log$
-/* Revision 1.2 1998/05/02 01:52:15 curt
-/* Playing around with texture coordinates.
+/* Revision 1.3 1998/05/23 14:09:21 curt
+/* Added tile.cxx and tile.hxx.
+/* Working on rewriting the tile management system so a tile is just a list
+/* fragments, and the fragment record contains the display list for that fragment.
/*
+ * Revision 1.2 1998/05/02 01:52:15 curt
+ * Playing around with texture coordinates.
+ *
* Revision 1.1 1998/04/30 12:35:29 curt
* Added a command line rendering option specify smooth/flat shading.
*
--- /dev/null
+// tile.cxx -- routines to handle a scenery tile
+//
+// Written by Curtis Olson, started May 1998.
+//
+// Copyright (C) 1998 Curtis L. Olson - curt@infoplane.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.
+//
+// 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$
+// (Log is kept at end of this file)
+
+
+#include "tile.hxx"
+
+
+// Constructor
+fgFRAGMENT::fgFRAGMENT ( void ) {
+}
+
+
+// Destructor
+fgFRAGMENT::~fgFRAGMENT ( void ) {
+}
+
+
+// Constructor
+fgTILE::fgTILE ( void ) {
+}
+
+
+// Destructor
+fgTILE::~fgTILE ( void ) {
+}
+
+
+// $Log$
+// Revision 1.1 1998/05/23 14:09:21 curt
+// Added tile.cxx and tile.hxx.
+// Working on rewriting the tile management system so a tile is just a list
+// fragments, and the fragment record contains the display list for that fragment.
+//
--- /dev/null
+// tile.hxx -- routines to handle a scenery tile
+//
+// Written by Curtis Olson, started May 1998.
+//
+// Copyright (C) 1998 Curtis L. Olson - curt@infoplane.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.
+//
+// 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$
+// (Log is kept at end of this file)
+
+
+#ifndef _TILE_HXX
+#define _TILE_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 <GL/glut.h>
+#include <XGL/xgl.h>
+
+#include <list.h> // STL list
+
+#include <Bucket/bucketutils.h>
+#include <Include/fg_types.h>
+
+
+// Object fragment data class
+class fgFRAGMENT {
+
+public:
+
+ // culling data for this object fragment (fine grain culling)
+ fgCartesianPoint3d center;
+ double bounding_radius;
+
+ // material property pointer
+ int material_ptr;
+
+ // OpenGL display list for fragment data
+ GLint display_list;
+
+ // Constructor
+ fgFRAGMENT ( void );
+
+ // Destructor
+ ~fgFRAGMENT ( void );
+};
+
+
+// Scenery tile class
+class fgTILE {
+
+public:
+
+ // culling data for whole tile (course grain culling)
+ fgCartesianPoint3d center;
+ double bounding_radius;
+
+ // this tile's official location in the world
+ struct fgBUCKET tile_bucket;
+
+ // the tile cache will mark here if the tile is being used
+ int used;
+
+ list < fgFRAGMENT > fragment_list;
+
+ // Constructor
+ fgTILE ( void );
+
+ // Destructor
+ ~fgTILE ( void );
+};
+
+
+#endif // _TILE_HXX
+
+
+// $Log$
+// Revision 1.1 1998/05/23 14:09:21 curt
+// Added tile.cxx and tile.hxx.
+// Working on rewriting the tile management system so a tile is just a list
+// fragments, and the fragment record contains the display list for that fragment.
+//
tile_cache[index].tile_bucket.x = p->x;
tile_cache[index].tile_bucket.y = p->y;
- // Load the appropriate area and get the display list pointer
+ // Load the appropriate data file and built tile fragment list
fgBucketGenBasePath(p, base_path);
sprintf(file_name, "%s/Scenery/%s/%ld", o->fg_root,
base_path, fgBucketGenIndex(p));
+ fgObjLoad(file_name, &tile_cache[index]);
+ /*
tile_cache[index].display_list =
fgObjLoad(file_name, &tile_cache[index].local_ref,
&tile_cache[index].bounding_radius);
+ */
}
// Free a tile cache entry
void fgTILECACHE::EntryFree( int index ) {
+ fgFRAGMENT fragment;
+
// Mark this cache entry as un-used
tile_cache[index].used = 0;
tile_cache[index].tile_bucket.x,
tile_cache[index].tile_bucket.y );
- // Load the appropriate area and get the display list pointer
- if ( tile_cache[index].display_list >= 0 ) {
- xglDeleteLists( tile_cache[index].display_list, 1 );
+ // Step through the fragment list, deleting the display list, then
+ // the fragment, until the list is empty.
+ while ( tile_cache[index].fragment_list.size() ) {
+ fragment = tile_cache[index].fragment_list.front();
+ xglDeleteLists( fragment.display_list, 1 );
+ tile_cache[index].fragment_list.pop_front();
}
}
-// Return info for a tile cache entry
-void fgTILECACHE::EntryInfo( int index, GLint *display_list,
- fgCartesianPoint3d *local_ref,
- double *radius ) {
- *display_list = tile_cache[index].display_list;
- // fgPrintf(FG_TERRAIN, FG_DEBUG, "Display list = %d\n", *display_list);
-
- local_ref->x = tile_cache[index].local_ref.x;
- local_ref->y = tile_cache[index].local_ref.y;
- local_ref->z = tile_cache[index].local_ref.z;
-
- *radius = tile_cache[index].bounding_radius;
+// Return the specified tile cache entry
+fgTILE *fgTILECACHE::GetTile( int index ) {
+ return ( &tile_cache[index] );
}
v->abs_view_pos.x, v->abs_view_pos.y, v->abs_view_pos.z );
fgPrintf( FG_TERRAIN, FG_DEBUG,
" ref point = %.4f, %.4f, %.4f\n",
- tile_cache[i].local_ref.x, tile_cache[i].local_ref.y,
- tile_cache[i].local_ref.z);
+ tile_cache[i].center.x, tile_cache[i].center.y,
+ tile_cache[i].center.z);
- dx = fabs(tile_cache[i].local_ref.x - v->abs_view_pos.x);
- dy = fabs(tile_cache[i].local_ref.y - v->abs_view_pos.y);
- dz = fabs(tile_cache[i].local_ref.z - v->abs_view_pos.z);
+ dx = fabs(tile_cache[i].center.x - v->abs_view_pos.x);
+ dy = fabs(tile_cache[i].center.y - v->abs_view_pos.y);
+ dz = fabs(tile_cache[i].center.z - v->abs_view_pos.z);
max = dx; med = dy; min = dz;
if ( max < med ) {
// $Log$
+// Revision 1.10 1998/05/23 14:09:22 curt
+// Added tile.cxx and tile.hxx.
+// Working on rewriting the tile management system so a tile is just a list
+// fragments, and the fragment record contains the display list for that fragment.
+//
// Revision 1.9 1998/05/20 20:53:54 curt
// Moved global ref point and radius (bounding sphere info, and offset) to
// data file rather than calculating it on the fly.
#include <Bucket/bucketutils.h>
#include <Include/fg_types.h>
+#include "tile.hxx"
+
+
// For best results ... i.e. to avoid tile load problems and blank areas
//
// FG_TILE_CACHE_SIZE >= (o->tile_diameter + 1) ** 2
#define FG_TILE_CACHE_SIZE 121
+/*
// Tile cache record
typedef struct {
struct fgBUCKET tile_bucket;
int used;
int priority;
} fgTILE;
+*/
// A class to store and manage a pile of tiles
int NextAvail( void );
// Free a tile cache entry
- void fgTILECACHE::EntryFree( int index );
+ void EntryFree( int index );
// Fill in a tile cache entry with real data for the specified bucket
void EntryFillIn( int index, struct fgBUCKET *p );
- // Return info for a tile cache entry
- void EntryInfo( int index, GLint *display_list,
- fgCartesianPoint3d *local_ref, double *radius );
+ // Return a pointer to the specified tile cache entry
+ fgTILE *GetTile( int index );
// Destructor
~fgTILECACHE( void );
// $Log$
+// Revision 1.9 1998/05/23 14:09:22 curt
+// Added tile.cxx and tile.hxx.
+// Working on rewriting the tile management system so a tile is just a list
+// fragments, and the fragment record contains the display list for that fragment.
+//
// Revision 1.8 1998/05/20 20:53:54 curt
// Moved global ref point and radius (bounding sphere info, and offset) to
// data file rather than calculating it on the fly.
#include <GL/glut.h>
#include <XGL/xgl.h>
+#include <Aircraft/aircraft.h>
+
#include <Scenery/obj.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilecache.hxx>
-#include <Aircraft/aircraft.h>
#include <Bucket/bucketutils.h>
#include <Debug/fg_debug.h>
#include <Include/fg_constants.h>
fgTILECACHE *c;
fgFLIGHT *f;
fgOPTIONS *o;
+ fgTILE *t;
fgVIEW *v;
struct fgBUCKET p;
- fgCartesianPoint3d local_ref, offset;
- GLint display_list;
- double radius;
+ fgCartesianPoint3d offset;
+ fgFRAGMENT fragment;
+ list < fgFRAGMENT > :: iterator current;
+ list < fgFRAGMENT > :: iterator last;
int i;
int index;
int culled = 0;
// Find current translation offset
fgBucketFind(FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG, &p);
index = c->Exists(&p);
- c->EntryInfo(index, &display_list, &scenery.next_center, &radius );
+ t = c->GetTile(index);
fgPrintf( FG_TERRAIN, FG_DEBUG,
"Pos = (%.2f, %.2f) Current bucket = %d %d %d %d Index = %ld\n",
for ( i = 0; i < (o->tile_diameter * o->tile_diameter); i++ ) {
index = tiles[i];
// fgPrintf( FG_TERRAIN, FG_DEBUG, "Index = %d\n", index);
- c->EntryInfo(index, &display_list, &local_ref, &radius );
-
- if ( display_list >= 0 ) {
-
- offset.x = local_ref.x - scenery.center.x;
- offset.y = local_ref.y - scenery.center.y;
- offset.z = local_ref.z - scenery.center.z;
-
- if ( viewable(&offset, radius) ) {
- drawn++;
- xglPushMatrix();
- xglTranslatef(offset.x, offset.y, offset.z);
- xglCallList(display_list);
- xglPopMatrix();
- } else {
- culled++;
+ t = c->GetTile(index);
+
+ // calculate tile offset
+ offset.x = t->center.x - scenery.center.x;
+ offset.y = t->center.y - scenery.center.y;
+ offset.z = t->center.z - scenery.center.z;
+
+ if ( viewable(&offset, t->bounding_radius) ) {
+ // at least a portion of this tile is viewable
+
+ xglPushMatrix();
+ xglTranslatef(offset.x, offset.y, offset.z);
+
+ // traverse fragment list for tile
+ current = t->fragment_list.begin();
+ last = t->fragment_list.end();
+
+ while ( current != last ) {
+ fragment = *current++;
+
+ if ( fragment.display_list >= 0 ) {
+ xglCallList(fragment.display_list);
+ }
}
+
+ xglPopMatrix();
}
}
- v->vfc_ratio = (double)culled / (double)(drawn + culled);
+ // v->vfc_ratio = (double)culled / (double)(drawn + culled);
+ v->vfc_ratio = 0.0;
// printf("drawn = %d culled = %d saved = %.2f\n", drawn, culled,
// v->vfc_ratio);
}
// $Log$
+// Revision 1.12 1998/05/23 14:09:23 curt
+// Added tile.cxx and tile.hxx.
+// Working on rewriting the tile management system so a tile is just a list
+// fragments, and the fragment record contains the display list for that fragment.
+//
// Revision 1.11 1998/05/20 20:53:55 curt
// Moved global ref point and radius (bounding sphere info, and offset) to
// data file rather than calculating it on the fly.