Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

GlobeTile.cpp

Go to the documentation of this file.
00001 /*
00002  * GlobeTile.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  *
00023  * Implementation of class CGlobeTile, the first level of terrain tile division
00024  *
00025  */
00026 
00032 #include "../Include/Globals.h"
00033 #include "../Include/Terrain.h"
00034 #include "../Include/Utility.h"
00035 #include "../Include/Ui.h"
00036 
00037 /*
00038 //
00039 // CGlobeTile
00040 //
00041 
00042 CGlobeTile::CGlobeTile (unsigned int x, unsigned int z)
00043 {
00044   int i, j;
00045 
00046   globals->terrainmgr->Log ("Instantiating Globe Tile %d,%d", x, z);
00047 
00048   // Range check parameters
00049   if ((x < 0) || (x > 255) || (z < 0) || (z > 255)) {
00050     gtfo ("CGlobeTile : Illegal indices %d,%d", x, z);
00051   }
00052   this->x = x;
00053   this->z = z;
00054 
00055   level = TERRAIN_SUBDIVISION_GLOBE_TILE;
00056   navaidList = NULL;
00057 
00058   // Initialize quarter globe tile array.
00059   for (i=0; i<2; i++) {
00060     for (j=0; j<2; j++) {
00061       qtArray[i][j] = NULL;
00062     }
00063   }
00064 
00065   // Construct scenery folder base name for this globe tile
00066   sprintf (dataFolder, "DATA\\D%03d%03d", x, z);
00067 
00068   //
00069   // Compute lat/lon boundaries for the globe tile
00070   //
00071 
00072   // Get SW and NE lat/lon boundaries for the globe tile
00073   double sw_lat, sw_lon, ne_lat, ne_lon;
00074   globe_tile_lon_bounds (x, sw_lon, ne_lon);
00075   globe_tile_lat_bounds (z, sw_lat, ne_lat);
00076 
00077   // Convert degrees to arcseconds
00078   sw_lat *= 3600;
00079   sw_lon *= 3600;
00080   ne_lat *= 3600;
00081   ne_lon *= 3600;
00082 
00083   // Create SPosition structs for all corners
00084   SetCorners (sw_lat, sw_lon, ne_lat, ne_lon);
00085 
00086   //
00087   // In order to reduce the floating point roundoff error for tile vertices,
00088   //   each globe tile has its own local coordinate system, with origin at
00089   //   the center of the globe tile.  The appropriate transform is applied to
00090   //   the top-level ssgTransform for the globe tile, and all sub-tile vertices
00091   //   are relative to this local center.
00092   //
00093 
00094   // Top-level SSG entity is controlled by Create()/Destroy()
00095   top = NULL;
00096 }
00097 
00098 CGlobeTile::~CGlobeTile (void)
00099 {
00100   // Ensure globe tile contents are destroyed
00101   if (IsCreated()) Destroy ();
00102 }
00103 
00104 int CGlobeTile::GetX (void)
00105 {
00106   return x;
00107 }
00108 
00109 int CGlobeTile::GetZ (void)
00110 {
00111   return z;
00112 }
00113 */
00114 
00115 /*
00116 void CGlobeTile::Create (void)
00117 {
00118   globals->terrainmgr->Log ("Creating Globe Tile %d,%d", x, z);
00119 
00120   // Instantiate top-level SSG entity for the globe tile
00121   top = new ssgTransform;
00122   char name[64];
00123   sprintf (name, "GT %d,%d", x, z);
00124   top->setName (name);
00125 
00126   if (globals->terrainmgr->debugLevel == GLOBE_TILES) {
00127     // Debug mode that creates globe tiles only
00128     DEBUGLOG ("GT %d,%d : Creating debug tile");
00129 
00130     // Calculate cartesian coordinates for tile corners
00131     SVector vsw, vnw, vse, vne;
00132     vsw = PosToFlatCartesian (sw, x, z);
00133     vnw = PosToFlatCartesian (nw, x, z);
00134     vse = PosToFlatCartesian (se, x, z);
00135     vne = PosToFlatCartesian (ne, x, z);
00136 
00137     // Load default globe tile debugging texture 
00138     SSurface *surface = CreateSurface (64, 64);
00139     unsigned int bg = MakeRGB (128, 128, 128);    // Medium grey
00140     unsigned int fg = MakeRGB (255, 255, 255);    // White
00141     surface->xScreen = surface->yScreen = 0;
00142     EraseSurfaceRGB (surface, bg);
00143     DrawLine (surface, 0, 0, 63, 0, fg);
00144     DrawLine (surface, 63, 0, 63, 63, fg);
00145     DrawLine (surface, 63, 63, 0, 63, fg);
00146     DrawLine (surface, 63, 0, 0, 0, fg);
00147     char label[16];
00148     sprintf (label, "%03d,%03d", x, z);
00149     DrawTextC (surface, &globals->fonts.ftthin24, 32, 20, fg, label);
00150     texid = TextureFromSurface (surface, true);
00151     FreeSurface (surface);
00152 
00153     // Initialize state information for the detail tile
00154     ssgSimpleState *state = new ssgSimpleState ();
00155     state->setShadeModel (GL_SMOOTH);
00156     state->disable (GL_LIGHTING);
00157     state->enable (GL_CULL_FACE);
00158     state->enable (GL_BLEND);
00159     state->disable (GL_ALPHA_TEST);
00160     state->setColourMaterial (GL_AMBIENT_AND_DIFFUSE);
00161     state->setMaterial (GL_EMISSION, 0, 0, 0, 1);
00162     state->setMaterial (GL_SPECULAR, 0, 0, 0, 1);
00163 
00164     // Terrain is textured with globe tile default debug texture
00165     state->enable (GL_TEXTURE_2D);
00166     state->setTexture (texid);
00167     state->disable (GL_COLOR_MATERIAL);
00168 
00169     // Set vertices
00170     sgVec3 v1, v2, v3, v4;
00171     sgSetVec3 (v1, vnw.x, vnw.y, vnw.z);
00172     sgSetVec3 (v2, vsw.x, vsw.y, vsw.z);
00173     sgSetVec3 (v3, vne.x, vne.y, vne.z);
00174     sgSetVec3 (v4, vse.x, vse.y, vse.z);
00175 
00176     // Define arrays for face data
00177     ssgVertexArray *va = new ssgVertexArray(4);
00178     va->add (v1);
00179     va->add (v2);
00180     va->add (v3);
00181     va->add (v4);
00182 
00183     // Allocate texture coordinates
00184     sgVec2 t1, t2, t3, t4;
00185     sgSetVec2 (t1, 0.0, 1.0);   // Upper-left  NW
00186     sgSetVec2 (t2, 0.0, 0.0);   // Lower-left  SW
00187     sgSetVec2 (t3, 1.0, 1.0);   // Upper-right NE
00188     sgSetVec2 (t4, 1.0, 0.0);   // Lower-right SE
00189 
00190     ssgTexCoordArray *ta = new ssgTexCoordArray(4);
00191     ta->add (t1);
00192     ta->add (t2);
00193     ta->add (t3);
00194     ta->add (t4);
00195 
00196     ssgVtxTable *vtab = new ssgVtxTable (GL_TRIANGLE_STRIP, va, NULL, ta, NULL);
00197     vtab->setState (state);
00198     vtab->setName ("TriStrip");
00199 
00200     top->addKid (vtab);
00201 
00202   } else {
00203 
00204     DEBUGLOG ("GT %d,%d : Creating quarter globe tiles");
00205 
00206     // Register the globe tile corner positions with the sliced scenery database
00207     //   This ensures that pods containing relevant .SCF scenery areas are 
00208     //   loaded prior to creating the quarter globe tiles
00209     ssdb->Register (nw);
00210     ssdb->Register (ne);
00211     ssdb->Register (sw);
00212     ssdb->Register (se);
00213 
00214     // Instantiate each of the four quarter globe tiles
00215     for (int i=0; i<2; i++) {
00216       for (int j=0; j<2; j++) {
00217         // Calculate quarter globe tile indices
00218         int qx = (x * 2) + i;
00219         int qz = (z * 2) + j;
00220 
00221         // Construct TRN filename for this quarter globe tile
00222         char trnFilename[64];
00223         sprintf (trnFilename, "G%1d%1d.TRN", i, j);
00224 
00225         char trnFullname[64];
00226         strcpy (trnFullname, dataFolder);
00227         strcat (trnFullname, "\\");
00228         strcat (trnFullname, trnFilename);
00229 
00230         // Attempt to open TRN stream file
00231         SStream s;
00232         strcpy (s.filename, trnFullname);
00233         strcpy (s.mode, "r");
00234         if (OpenStream (&s)) {
00235           // TRN file could be opened, create a sliced quarter globe tile
00236           CSlicedQuarterGlobeTile *q = new CSlicedQuarterGlobeTile (qx, qz, dataFolder);
00237           ReadFrom (q, &s);
00238           CloseStream (&s);
00239           qtArray[i][j] = q;
00240         } else {
00241           // TRN file could not be opened, create a generic quarter globe tile
00242           CDefaultQuarterGlobeTile *q = new CDefaultQuarterGlobeTile (qx, qz);
00243           qtArray[i][j] = q;
00244         }
00245       }
00246     }
00247   }
00248 */
00254 /*
00255   // Search for navaids in this globe tile
00256   SearchNavaidsByGlobeTile (x, z, &navaidList);
00257 
00258   // Instantiate VOR model and add to globe tile
00259   if (smdb != NULL) {
00260     ssgEntity *vor = smdb->GetSceneryModel ("Models\\Vor.smf");
00261 
00262     if (vor) {
00263       SNavaid *next = navaidList;
00264       while (next != NULL) {
00265         if (next->type & NAVAID_TYPE_VOR) {
00266           // Create a transform for the VOR model instance
00267           ssgTransform *transform = new ssgTransform;
00268           char name[64];
00269           sprintf (name, "VOR %s %s", next->id, next->name);
00270           transform->setName (name);
00271           transform->addKid (vor);
00272 
00274           next->pos.alt = 100.0;
00275 
00276           // Set model translation relative to globe tile center
00277           SVector v = PosToFlatCartesian (next->pos, x, z);
00278           sgVec3 t;
00279           sgSetVec3 (t, v.x, v.y, v.z);
00280           sgMat4 T;
00281           sgMakeTransMat4 (T, t);
00282           transform->setTransform (T);
00283           
00284           // Add the transformed VOR model to the globe tile SSG tree
00286           top->addKid (transform);
00287         }
00288 
00289         // Go to next navaid in the list
00290         next = next->next;
00291       }
00292     } else {
00293       globals->terrainmgr->Log ("CGlobeTile : Could not load model Vor.smf");
00294     }
00295   }
00296 */
00297 /*
00298   // DEBUG : Dump navaid list to file
00299 //  FILE *f = fopen ("gtnavaid.txt", "w");
00300 //  if (f) {
00301 //    SNavaid *next = navaidList;
00302 //    while (next != NULL) {
00303 //      char pos[64];
00304 //      FormatPosition (next->pos, pos);
00305 //      fprintf (f, "%5s %s\n", next->id, pos);
00306 //      next = next->next;
00307 //    }
00308 //    fclose (f);
00309 //  }
00310 
00311   CTerrainTile::Create ();
00312 }
00313 */
00314 /*
00315 void CGlobeTile::Destroy (void)
00316 {
00317   globals->terrainmgr->Log ("Destroying Globe Tile %d,%d", x, z);
00318 
00319   int i, j;
00320 
00321   // Destroy and delete child quarter globe tiles
00322   for (i=0; i<2; i++) {
00323     for (j=0; j<2; j++) {
00324       CQuarterGlobeTile *q = qtArray[i][j];
00325       if (q != NULL) {
00326         if (q->IsCreated()) {
00327           q->Destroy();
00328           top->removeKid (q->GetSSGEntity());
00329         }
00330         delete q;
00331         qtArray[i][j] = NULL;
00332       }
00333     }
00334   }
00335 
00336   // Free navaids
00337   FreeNavaid (navaidList);
00338 
00339   // De-register this globe tile with the sliced scenery database
00340   ssdb->Deregister (nw);
00341   ssdb->Deregister (ne);
00342   ssdb->Deregister (sw);
00343   ssdb->Deregister (se);
00344 
00345   CTerrainTile::Destroy ();
00346 }
00347 
00348 void CGlobeTile::TranslateFrom (int xbase, int zbase)
00349 {
00350   float distance = GlobeTileDistance();
00351   int xtiles = x - xbase;
00352   int ztiles = z - zbase;
00353   float dx = xtiles * distance;
00354   float dy = ztiles * distance;
00355   sgVec3 t;
00356   sgSetVec3 (t, dx, dy, 0);
00357 
00358   sgMat4 T;
00359   sgMakeTransMat4 (T, t);
00360   top->setTransform (T);
00361 }
00362 
00363 void CGlobeTile::UpdatePosition (SPosition pos, float vis)
00364 {
00365   // Get lat/lon and cartesian coords for base position
00366   int xBase, zBase;
00367   lat_lon_to_globe_tile (pos.lat / 3600.0, pos.lon / 3600.0, xBase, zBase);
00368 
00369   // Calculate globe tile difference between this GT and base position
00370   int xTiles = x - xBase;
00371   int zTiles = z - zBase;
00372 
00373   float dx, dy;
00374   if ((xTiles == 0) && (zTiles == 0)) {
00375     // Same globe tile, no offset
00376     dx = 0;
00377     dy = 0;
00378   } else {
00379     // Check for wrap around Prime Meridian
00380     if (xTiles < -128) {
00381       // Base is W, target is E
00382       xTiles += 256;
00383     } else if (xTiles > 128) {
00384       // Base is E, target is W
00385       xTiles -= 256;
00386     }
00387     float distance = GlobeTileDistance();
00388     dx = (xTiles * distance);
00389     dy = (zTiles * distance);
00390   }
00391 
00392   // Make transform matrix and apply it to globe tile top-level transform
00393   sgVec3 t;
00394   sgSetVec3 (t, dx, dy, 0);
00395 
00396   sgMat4 T;
00397   sgMakeTransMat4 (T, t);
00398   top->setTransform (T);
00399 
00400   CheckQuarterTileVisibility (pos, vis);
00401 }
00402 
00403 //
00404 // Check visibility of all quarter globe tiles in this globe tile.
00405 //
00406 void CGlobeTile::CheckQuarterTileVisibility (SPosition pos, float vis)
00407 {
00408   // Check visibility of all quarter tiles
00409   for (int i=0; i<2; i++) {
00410     for (int j=0; j<2; j++) {
00411       CQuarterGlobeTile *q = qtArray[i][j];
00412       if (q != NULL) {
00413         if (q->CheckVisibility(pos, vis)) {
00414           // Ensure quarter globe tile is created
00415           if (!q->IsCreated()) {
00416             q->Create ();
00417             top->addKid (q->GetSSGEntity());
00418           }
00419         } else {
00420           // Ensure quarter globe tile is destroyed
00421           if (q->IsCreated()) {
00422             q->Destroy ();
00423             top->removeKid (q->GetSSGEntity());
00424           }
00425         }
00426       }
00427     }
00428   }
00429 }
00430 
00431 ssgEntity* CGlobeTile::GetSSGEntity (void)
00432 {
00433   return top;
00434 }
00435 
00436 void CGlobeTile::Print (FILE *f)
00437 {
00438 }
00439 
00440 */
SourceForge.net Logo Documentation generated by doxygen