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 */
|
|
Documentation generated by
|