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

SuperTile.cpp

Go to the documentation of this file.
00001 /*
00002  * SuperTile.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003-2004 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 
00036 #include "../Include/Globals.h"
00037 #include "../Include/Terrain.h"
00038 #include "../Include/Utility.h"
00039 #include "../Include/Ui.h"
00040 
00041 //
00042 // CSuperTile
00043 //
00044 
00045 CSuperTile::CSuperTile (unsigned int x, unsigned int z)
00046 {
00047   level = TERRAIN_SUBDIVISION_SUPER_TILE;
00048 
00049   this->x = x;
00050   this->z = z;
00051   dimn = 0;
00052 
00053   //
00054   // Compute lat/lon boundaries for the tile
00055   //
00056 
00057   // First calculate parent globe tile indices
00058   int n = 16;   // Dimension of these tiles per globe tile
00059   globe_x = x / n;
00060   globe_z = z / n;
00061 
00062   // Get lat/lon boundaries for the globe tile, and convert to arcsec
00063   double globe_sw_lon, globe_ne_lon, globe_sw_lat, globe_ne_lat;
00064   globe_tile_lon_bounds (globe_x, globe_sw_lon, globe_ne_lon);
00065   globe_tile_lat_bounds (globe_z, globe_sw_lat, globe_ne_lat);
00066   globe_sw_lon *= 3600;
00067   globe_sw_lat *= 3600;
00068   globe_ne_lon *= 3600;
00069   globe_ne_lat *= 3600;
00070 
00071   // Calculate per-tile offset
00072   double dLat = (globe_ne_lat - globe_sw_lat) / n;
00073   double dLon = (globe_ne_lon - globe_sw_lon) / n;
00074 
00075   // Calculate tile corners
00076   double swLat = globe_sw_lat + (dLat * (z % n));
00077   double swLon = globe_sw_lon + (dLon * (x % n));
00078   double neLat = swLat + dLat;
00079   double neLon = swLon + dLon;
00080   SetCorners (swLat, swLon, neLat, neLon);
00081 
00082   top = NULL;
00083 }
00084 
00085 
00086 CSuperTile::~CSuperTile (void)
00087 {
00088 }
00089 
00090 ssgEntity* CSuperTile::GetSSGEntity (void)
00091 {
00092   return top;
00093 }
00094 
00095 void CSuperTile::Print (FILE *f)
00096 {
00097 }
00098 
00099 
00100 //
00101 // CDefaultSuperTile
00102 //
00103 
00104 CDefaultSuperTile::CDefaultSuperTile (unsigned int x, unsigned int z)
00105 : CSuperTile (x, z)
00106 {
00107   int i, j;
00108 
00109   // Check for ST debug mode
00110   if (globals->terrainmgr->debugLevel == SUPER_TILES) {
00111 
00112     // Calculate cartesian coordinates for tile corners
00113     SVector vsw, vnw, vse, vne;
00114     vsw = PosToFlatCartesian (sw, globe_x, globe_z);
00115     vnw = PosToFlatCartesian (nw, globe_x, globe_z);
00116     vse = PosToFlatCartesian (se, globe_x, globe_z);
00117     vne = PosToFlatCartesian (ne, globe_x, globe_z);
00118 
00119     // Create default tile debugging texture 
00120     SSurface *surface = CreateSurface (64, 64);
00121     unsigned int bg = MakeRGB (128, 128, 128);    // Medium grey
00122     unsigned int fg = MakeRGB (255, 255, 255);    // White
00123     surface->xScreen = surface->yScreen = 0;
00124     EraseSurfaceRGB (surface, bg);
00125     DrawLine (surface, 0, 0, 63, 0, fg);
00126     DrawLine (surface, 63, 0, 63, 63, fg);
00127     DrawLine (surface, 63, 63, 0, 63, fg);
00128     DrawLine (surface, 63, 0, 0, 0, fg);
00129     char label[16];
00130     sprintf (label, "%03d,%03d", globe_x, globe_z);
00131     DrawTextC (surface, &globals->fonts.ftmono12, 32, 16, fg, label);
00132     int xmod = (x / 8) % 2;
00133     int zmod = (z / 8) % 2;
00134     sprintf (label, "Q%1d%1d", xmod, zmod);
00135     DrawTextC (surface, &globals->fonts.ftmono12, 32, 36, fg, label);
00136     sprintf (label, "S%1d%1d", x % 8, z % 8);
00137     DrawTextC (surface, &globals->fonts.ftmono12, 32, 50, fg, label);
00138     texid = TextureFromSurface (surface, true);
00139     FreeSurface (surface);
00140 
00141     // Initialize state information for the tile
00142     ssgSimpleState *state = new ssgSimpleState ();
00143     state->setShadeModel (GL_SMOOTH);
00144     state->disable (GL_LIGHTING);
00145     state->enable (GL_CULL_FACE);
00146     state->enable (GL_BLEND);
00147     state->disable (GL_ALPHA_TEST);
00148     state->setColourMaterial (GL_AMBIENT_AND_DIFFUSE);
00149     state->setMaterial (GL_EMISSION, 0, 0, 0, 1);
00150     state->setMaterial (GL_SPECULAR, 0, 0, 0, 1);
00151 
00152     // Tile is textured with constructed debug texture
00153     state->enable (GL_TEXTURE_2D);
00154     state->setTexture (texid);
00155     state->disable (GL_COLOR_MATERIAL);
00156 
00157     // Set vertices
00158     sgVec3 v1, v2, v3, v4;
00159     sgSetVec3 (v1, vnw.x, vnw.y, vnw.z);
00160     sgSetVec3 (v2, vsw.x, vsw.y, vsw.z);
00161     sgSetVec3 (v3, vne.x, vne.y, vne.z);
00162     sgSetVec3 (v4, vse.x, vse.y, vse.z);
00163 
00164     // Define arrays for face data
00165     ssgVertexArray *va = new ssgVertexArray(4);
00166     va->add (v1);
00167     va->add (v2);
00168     va->add (v3);
00169     va->add (v4);
00170 
00171     // Allocate texture coordinates
00172     sgVec2 t1, t2, t3, t4;
00173     sgSetVec2 (t1, 0.0, 1.0);   // NW = Upper-left
00174     sgSetVec2 (t2, 0.0, 0.0);   // SW = Lower-left
00175     sgSetVec2 (t3, 1.0, 1.0);   // NE = Upper-right
00176     sgSetVec2 (t4, 1.0, 0.0);   // SE = Lower-right SE
00177 
00178     ssgTexCoordArray *ta = new ssgTexCoordArray(4);
00179     ta->add (t1);
00180     ta->add (t2);
00181     ta->add (t3);
00182     ta->add (t4);
00183 
00184     ssgVtxTable *vtab = new ssgVtxTable (GL_TRIANGLE_STRIP, va, NULL, ta, NULL);
00185     vtab->setState (state);
00186     vtab->setName ("TriStrip");
00187 
00188     top->addKid (vtab);
00189   } else {
00190     // Debug mode is not active; allocate detail tile array and instantiate
00191     dimn = 4;
00192     dtArray = new CDetailTile**[dimn];
00193     for (i=0; i < dimn; i++) {
00194       dtArray[i] = new CDetailTile*[dimn];
00195       for (j=0; j < dimn; j++) {
00196         // Calculate absolute detail tile index
00197         int dx = (x * dimn) + i;
00198         int dz = (z * dimn) + j;
00199 
00200         CDetailTile *dt = new CDetailTile (dx, dz);
00201         dtArray[i][j] = dt;
00202       }
00203     }
00204   }
00205 }
00206 
00207 CDefaultSuperTile::~CDefaultSuperTile (void)
00208 {
00209   if (IsCreated()) Destroy();
00210 
00211   int i, j;
00212 
00213   // Delete detail tiles and deallocate storage
00214   if (dtArray != NULL) {
00215     for (i=0; i < dimn; i++) {
00216       for (j=0; j < dimn; j++) {
00217         CDetailTile *dt = dtArray[i][j];
00218         delete dt;
00219       }
00220       delete[] dtArray[i];
00221     }
00222     delete[] dtArray;
00223   }
00224 }
00225 
00226 void CDefaultSuperTile::Create (void)
00227 {
00228   // Set default terrain tile detail level
00229   ETileDetail detail = TILE_DETAIL_LOW;
00230 
00231   // Create top-level transform for the super tile
00232   top = new ssgBranch;
00233   char name[64];
00234   sprintf (name, "ST %d,%d", x, z);
00235   top->setName (name);
00236 
00237   // Create all detail tiles
00238   int i, j;
00239   for (i=0; i<dimn; i++) {
00240     for (j=0; j<dimn; j++) {
00241       CDetailTile *dt = dtArray[i][j];
00242       dt->Create ();
00243       dt->SetDetail (detail);
00244       top->addKid (dt->GetSSGEntity());
00245     }
00246   }
00247 }
00248 
00249 void CDefaultSuperTile::Destroy (void)
00250 {
00251   // Destroy all detail tiles
00252   int i, j;
00253   for (i=0; i<dimn; i++) {
00254     for (j=0; j<dimn; j++) {
00255       CDetailTile *dt = dtArray[i][j];
00256       dt->Destroy ();
00257     }
00258   }
00259 }
00260 
00261 void CDefaultSuperTile::Print (FILE *f)
00262 {
00264 }
00265 
00266 //
00267 // CHighDetailElevations
00268 //
00269 CHighDetailElevations::CHighDetailElevations (int base_x, int base_z,
00270                                               CElevationTRNSuperTile *stElev)
00271 {
00272   this->base_x = base_x;
00273   this->base_z = base_z;
00274   this->stElev = stElev;
00275   block = NULL;
00276   dimn = 0;
00277 }
00278 
00279 CHighDetailElevations::~CHighDetailElevations (void)
00280 {
00281 /*
00282   // Remove elevation grid from database and delete
00283   if (block != NULL) {
00284     if (tedb->RemoveTRNBlock (block)) {
00285       delete block;
00286     } else {
00287       globals->logWarning->Write ("CHighDetailElevations : Could not remove elevation block");
00288     }
00289   }
00290 */
00291 }
00292 
00293 int CHighDetailElevations::Read (SStream *stream, Tag tag)
00294 {
00295   int i, j;
00296 
00297   int rc = TAG_IGNORED;
00298 
00299   switch (tag) {
00300   case 'dimn':
00301     // Dimension of sub-tile array
00302     ReadInt (&dimn, stream);
00303 
00304     // High-detail elevations are only valid for 4x4 or 8x8 subdivisions.
00305     if ((dimn != 2) && (dimn != 4) && (dimn != 8)) {
00306       gtfo ("CHighDetailElevations : <dimn>=%d, must be 2, 4 or 8", dimn);
00307     }
00308     rc = TAG_READ;
00309     break;
00310 
00311   case 'type':
00312     // Terrain type ??
00313     ReadInt (&type, stream);
00314     rc = TAG_READ;
00315     break;
00316 
00317   case 'prta':
00318     // Indices of this super tile in the parent; discarded
00319     ReadInt (&prta_x, stream);
00320     ReadInt (&prta_z, stream);
00321     rc = TAG_READ;
00322     break;
00323 
00324   case 'elev':
00325     if (dimn != 0) {
00326       // Allocate memory for elevation grid, read and add to database
00327       float **elev = new float*[dimn+1];
00328       for (i=0; i<dimn+1; i++) {
00329         elev[i] = new float[dimn+1];
00330         for (j=0; j<dimn+1; j++) {
00331           ReadFloat (&elev[i][j], stream);
00332         }
00333       }
00334 
00335       block = new CElevationBlockGrid (base_x + prta_x, base_z + prta_z, 1, dimn, elev);
00336       stElev->dtArray[prta_x][prta_z] = block;
00337     } else {
00338       gtfo ("CHighDetailElevation : <dimn> tag must precede <elev> tag");
00339     }
00340     rc = TAG_READ;
00341     break;
00342   }
00343 
00344   return rc;
00345 }
00346 
00347 
00348 //
00349 // CSlicedSuperTile
00350 //
00351 
00352 CSlicedSuperTile::CSlicedSuperTile (unsigned int x, unsigned int z,
00353                                     CElevationTRNQuarterGlobeTile *trn)
00354 : CSuperTile (x, z)
00355 {
00356   this->trn = trn;
00357 
00358   // Initialize pointer members
00359   tref = NULL;
00360   dtArray = NULL;
00361   textureList = NULL;
00362 
00363   // Initialize elevation information
00364   block = NULL;
00365 
00366   // Initialize texture info
00367   STileTextureInfo info;
00368   info.texid = 0;
00369   info.lls = info.llt = 0.0f;
00370   info.urs = info.urt = 1.0f;
00371   memcpy (&texinfo[TILE_DETAIL_LOW], &info, sizeof(STileTextureInfo));
00372   memcpy (&texinfo[TILE_DETAIL_MEDIUM], &info, sizeof(STileTextureInfo));
00373   memcpy (&texinfo[TILE_DETAIL_HIGH], &info, sizeof(STileTextureInfo));
00374 
00375   // Set default terrain tile detail level
00376   detail = TILE_DETAIL_LOW;
00377 }
00378 
00379 CSlicedSuperTile::~CSlicedSuperTile (void)
00380 {
00381   if (IsCreated()) Destroy();
00382 
00383   int i;
00384 
00385   // Delete texture and elevation data allocated in Read()
00386   if (textureList != NULL) delete textureList;
00387 
00388   if (tref != NULL) {
00389     for (i=0; i<dimn; i++) {
00390       delete[] tref[i];
00391     }
00392   }
00393   delete[] tref;
00394 
00395 /*
00396   // Delete base-resolution elevation grid
00397   if (block != NULL) {
00398     if (tedb->RemoveTRNBlock (block)) {
00399       delete block;
00400     } else {
00401       globals->logWarning->Write ("CSlicedSuperTile : Could not remove elevation block");
00402     }
00403   }
00404 
00405   // Delete high-detail elevations
00406   if (hdtl != NULL) {
00407     n = hdtl->getNumEntities();
00408     for (i=0; i<n; i++) {
00409       CHighDetailElevations *h = (CHighDetailElevations *)hdtl->getEntity(i);
00410       delete h;
00411     }
00412     delete hdtl;
00413   }
00414 */
00415 }
00416 
00417 int CSlicedSuperTile::Read (SStream *stream, Tag tag)
00418 {
00419   int i, j;
00420 
00421   int rc = TAG_IGNORED;
00422 
00423   switch (tag) {
00424   case 'dimn':
00425     // Dimension of sub-tile array
00426     ReadInt (&dimn, stream);
00427 
00428     // Currently, all super tiles must be subdivided into a 4x4 grid of detail tiles
00429     //   I think that all Fly! II compatible TRN files comply with this restriction.
00430     //   Future development may make this more flexible
00431     if (dimn != 4) {
00432       gtfo ("CSlicedSuperTile::Read : <dimn>=%d, must be 4", dimn);
00433     }
00434 
00435     // Allocate array for texture references
00436     tref = new int*[dimn];
00437 
00438     rc = TAG_READ;
00439     break;
00440 
00441   case 'type':
00442     // Terrain type ??
00443     ReadInt (&type, stream);
00444     rc = TAG_READ;
00445     break;
00446 
00447   case 'prta':
00448     // Indices of this super tile in the parent
00449     ReadInt (&prta_x, stream);
00450     ReadInt (&prta_z, stream);
00451 
00452     // Instantiate TEDB object for this super tile
00453     trn->stArray[prta_x][prta_z] = new CElevationTRNSuperTile (x, z, dimn);
00454 
00455     rc = TAG_READ;
00456     break;
00457 
00458   case 'txtl':
00459     textureList = new CSlicedTextureList;
00460     ReadFrom (textureList, stream);
00461     rc = TAG_READ;
00462     break;
00463 
00464   case 'tref':
00465     // Read <dimn> * <dimn> references into <txtl> list
00466     if (tref != NULL) {
00467       for (i=0; i<dimn; i++) {
00468         tref[i] = new int[dimn];
00469         for (j=0; j<dimn; j++) {
00470           ReadInt (&tref[i][j], stream);
00471         }
00472       }
00473     } else {
00474       // <tref> tag found before <dimn>
00475       gtfo ("CSuperTile : <dimn> tag must precede <tref> data");
00476     }
00477     rc = TAG_READ;
00478     break;
00479 
00480   case 'elev':
00481     if (dimn != 0) {
00482       int dx = x * dimn;
00483       int dz = z * dimn;
00484 
00485       // Instantiate elevation block and add it to the database
00486       float **elev;
00487       elev = new float*[dimn+1];
00488       for (i=0; i<dimn+1; i++) {
00489         elev[i] = new float[dimn+1];
00490         for (j=0; j<dimn+1; j++) {
00491           ReadFloat (&elev[i][j], stream);
00492         }
00493       }
00494       block = new CElevationBlockGrid (dx, dz, dimn, 1, elev);
00495 
00496       CElevationTRNSuperTile *stElev = trn->stArray[prta_x][prta_z];
00497       if (stElev != NULL) stElev->elev = block;
00498     } else {
00499       // <elev> tag found before <dimn>
00500       gtfo ("CSuperTile : <dimn> tag must precede <elev> data");
00501     }
00502     rc = TAG_READ;
00503     break;
00504 
00505   case 'hdtl':
00506     // High-detail elevations
00507     if (dimn != 0) {
00508       int dx = x * dimn;
00509       int dz = z * dimn;
00510 
00511       // Process <hdtl> sub-object.  The only purpose here is to insert
00512       //   the detail tile elevations into the TEDB, which is done
00513       //   within CHighDetailElevations::Read().
00514       CElevationTRNSuperTile *stElev = trn->stArray[prta_x][prta_z];
00515       CHighDetailElevations *h = new CHighDetailElevations (dx, dz, stElev);
00516       ReadFrom (h, stream);
00517       delete h;
00518     } else {
00519       // <hdtl> tag found before <dimn>
00520       gtfo ("CSuperTile : <dimn> tag must precede <hdtl> data");
00521     }
00522     rc = TAG_READ;
00523     break;
00524   }
00525 
00526   return rc;
00527 }
00528 
00529 void CSlicedSuperTile::ReadFinished (void)
00530 {
00531   int i, j;
00532 
00533   // Verify that all mandatory data was present in the super tile specification
00534 
00535   if (dimn == 0) {
00536     gtfo ("CSlicedSuperTile : No <dimn> tag specified");
00537   }
00538 
00539   if (tref == NULL) {
00540     gtfo ("CSlicedSuperTile : No texture references specified");
00541   }
00542 
00543   if (textureList == NULL) {
00544     gtfo ("CSlicedSuperTile : No texture list object specified");
00545   }
00546 
00547   // Allocate array for sliced detail tiles
00548   dtArray = new CDetailTile**[dimn];
00549   for (i=0; i<dimn; i++) {
00550     dtArray[i] = new CDetailTile*[dimn];
00551     for (j=0; j<dimn; j++) {
00552       dtArray[i][j] = NULL;
00553     }
00554   }
00555 }
00556 
00557 void CSlicedSuperTile::AssignTexture (ETileDetail detail, STileTextureInfo &info)
00558 {
00559   int i, j;
00560 
00561   // Store texturing information
00562   memcpy (&texinfo[detail], &info, sizeof(STileTextureInfo));
00563   float sDelta = (info.urs - info.lls) / dimn;
00564   float tDelta = (info.urt - info.llt) / dimn;
00565 
00566   // Update detail tiles
00567   if (IsCreated()) {
00568     for (i=0; i<dimn; i++) {
00569       for (j=0; j<dimn; j++) {
00570         CDetailTile *dt = dtArray[i][j];
00571         STileTextureInfo dtinfo;
00572         dtinfo.texid = info.texid;
00573         dtinfo.lls = info.lls + (i * sDelta);
00574         dtinfo.urs = dtinfo.lls + sDelta;
00575         dtinfo.llt = info.llt + ((dimn - j - 1) * tDelta);
00576         dtinfo.urt = dtinfo.llt + tDelta;
00577         dt->AssignTexture (detail, dtinfo);
00578       }
00579     }
00580   }
00581 }
00582 
00583 void CSlicedSuperTile::Create (void)
00584 {
00585   int i, j;
00586 
00587   // Create top-level transform for the super tile
00588   top = new ssgBranch;
00589   char name[64];
00590   sprintf (name, "ST %d,%d", x, z);
00591   top->setName (name);
00592 
00593   if (globals->terrainmgr->debugLevel == SLICED_SUPER_TILES) {
00594 
00595     STileTextureInfo &info = texinfo[detail];
00596 
00597     // Calculate cartesian coordinates for subtile corners
00598     SVector vsw, vnw, vse, vne;
00599     vsw = PosToFlatCartesian (sw, globe_x, globe_z);
00600     vnw = PosToFlatCartesian (nw, globe_x, globe_z);
00601     vse = PosToFlatCartesian (se, globe_x, globe_z);
00602     vne = PosToFlatCartesian (ne, globe_x, globe_z);
00603 
00604     // Initialize state information for the detail tile
00605     ssgSimpleState *state = new ssgSimpleState ();
00606     state->setShadeModel (GL_SMOOTH);
00607     state->disable (GL_LIGHTING);
00608     state->enable (GL_CULL_FACE);
00609     state->enable (GL_BLEND);
00610     state->disable (GL_ALPHA_TEST);
00611     state->setColourMaterial (GL_AMBIENT_AND_DIFFUSE);
00612     state->setMaterial (GL_EMISSION, 0, 0, 0, 1);
00613     state->setMaterial (GL_SPECULAR, 0, 0, 0, 1);
00614 
00615     // Terrain is textured with quarter globe tile default debug texture
00616     state->enable (GL_TEXTURE_2D);
00617     state->setTexture (info.texid);
00618     state->disable (GL_COLOR_MATERIAL);
00619 
00620     // Set vertices for triangle strip in order NW, SW, NE, SE
00621     sgVec3 v1, v2, v3, v4;
00622     sgSetVec3 (v1, vnw.x, vnw.y, 0);
00623     sgSetVec3 (v2, vsw.x, vsw.y, 0);
00624     sgSetVec3 (v3, vne.x, vne.y, 0);
00625     sgSetVec3 (v4, vse.x, vse.y, 0);
00626 
00627     // Define arrays for face data
00628     ssgVertexArray *va = new ssgVertexArray(4);
00629     va->add (v1);
00630     va->add (v2);
00631     va->add (v3);
00632     va->add (v4);
00633 
00634     // Allocate texture coordinates
00635     sgVec2 t1, t2, t3, t4;
00636     sgSetVec2 (t1, info.lls, info.llt);   // NW = Lower-left
00637     sgSetVec2 (t2, info.lls, info.urt);   // SW = Upper-left
00638     sgSetVec2 (t3, info.urs, info.llt);   // NE = Lower-right
00639     sgSetVec2 (t4, info.urs, info.urt);   // SE = Upper-right
00640 
00641     ssgTexCoordArray *ta = new ssgTexCoordArray(4);
00642     ta->add (t1);
00643     ta->add (t2);
00644     ta->add (t3);
00645     ta->add (t4);
00646 
00647     ssgVtxTable *vtab = new ssgVtxTable (GL_TRIANGLE_STRIP, va, NULL, ta, NULL);
00648     vtab->setState (state);
00649     vtab->setName ("TriStrip");
00650 
00651     top->addKid (vtab);
00652   } else {
00653     // Create sliced detail tiles
00654     for (i=0; i<dimn; i++) {      // X-index from W to E
00655       for (j=0; j<dimn; j++) {    // Z-index from S to N
00656         int dx = (x * dimn) + i;
00657         int dz = (z * dimn) + j;
00658 
00659         CDetailTile *dt = new CDetailTile (dx, dz);
00660         dtArray[i][j] = dt;
00661 
00662         // Assign low-detail texture that was supplied by parent CSlicedQuarterGlobeTile
00663         STileTextureInfo dtinfo;
00664         STileTextureInfo &info = texinfo[detail];
00665         float sDelta = (info.urs - info.lls) / dimn;
00666         float tDelta = (info.urt - info.llt) / dimn;
00667         dtinfo.texid = info.texid;
00668         dtinfo.lls = info.lls + (i * sDelta);
00669         dtinfo.urs = dtinfo.lls + sDelta;
00670         dtinfo.llt = info.llt + ((dimn - j - 1) * tDelta);
00671         dtinfo.urt = dtinfo.llt + tDelta;
00672         dt->AssignTexture (detail, dtinfo);
00673         dt->Create ();
00674         top->addKid (dt->GetSSGEntity());
00675       }
00676     }
00677   }
00678 
00679   CTerrainTile::Create ();
00680 }
00681 
00682 void CSlicedSuperTile::Destroy (void)
00683 {
00684   int i, j;
00685 
00686   // Delete array of detail tiles
00687   for (i=0; i<dimn; i++) {
00688     for (j=0; j<dimn; j++) {
00689       CDetailTile *dt = dtArray[i][j];
00690       if (dt != NULL) {
00691         dt->Destroy ();
00692         delete dt;
00693         dtArray[i][j] = NULL;
00694       }
00695     }
00696   }
00697 
00698   CTerrainTile::Destroy ();
00699 }
00700 
00701 void CSlicedSuperTile::Print (FILE *f)
00702 {
00703 }
00704 
00705 
00706 
00707 //
00708 // CSlicedTextureList
00709 //
00710 CSlicedTextureList::CSlicedTextureList (void)
00711 {
00712   nTextureNames = 0;
00713   textureNames = NULL;
00714 }
00715 
00716 CSlicedTextureList::~CSlicedTextureList (void)
00717 {
00718   for (int i=0; i<nTextureNames; i++) {
00719     delete[] textureNames[i];
00720   }
00721   delete[] textureNames;
00722 }
00723 
00724 int CSlicedTextureList::Read (SStream *stream, Tag tag)
00725 {
00726   int i;
00727 
00728   int rc = TAG_IGNORED;
00729 
00730   switch (tag) {
00731   case 'txtl':
00732     // Texture name list; first entry is number of elements
00733     ReadInt (&nTextureNames, stream);
00734     textureNames = new char*[nTextureNames];
00735     for (i=0; i<nTextureNames; i++) {
00736       textureNames[i] = new char[64];
00737       ReadString (textureNames[i], 64, stream);
00738     }
00739     rc = TAG_READ;
00740     break;
00741   }
00742 
00743   return rc;
00744 }
00745 
00746 char* CSlicedTextureList::TextureName (int i)
00747 {
00748   return textureNames[i];
00749 }
00750 
00751 
SourceForge.net Logo Documentation generated by doxygen