00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
00055
00056
00057
00058 int n = 16;
00059 globe_x = x / n;
00060 globe_z = z / n;
00061
00062
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
00072 double dLat = (globe_ne_lat - globe_sw_lat) / n;
00073 double dLon = (globe_ne_lon - globe_sw_lon) / n;
00074
00075
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
00102
00103
00104 CDefaultSuperTile::CDefaultSuperTile (unsigned int x, unsigned int z)
00105 : CSuperTile (x, z)
00106 {
00107 int i, j;
00108
00109
00110 if (globals->terrainmgr->debugLevel == SUPER_TILES) {
00111
00112
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
00120 SSurface *surface = CreateSurface (64, 64);
00121 unsigned int bg = MakeRGB (128, 128, 128);
00122 unsigned int fg = MakeRGB (255, 255, 255);
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
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
00153 state->enable (GL_TEXTURE_2D);
00154 state->setTexture (texid);
00155 state->disable (GL_COLOR_MATERIAL);
00156
00157
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
00165 ssgVertexArray *va = new ssgVertexArray(4);
00166 va->add (v1);
00167 va->add (v2);
00168 va->add (v3);
00169 va->add (v4);
00170
00171
00172 sgVec2 t1, t2, t3, t4;
00173 sgSetVec2 (t1, 0.0, 1.0);
00174 sgSetVec2 (t2, 0.0, 0.0);
00175 sgSetVec2 (t3, 1.0, 1.0);
00176 sgSetVec2 (t4, 1.0, 0.0);
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
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
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
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
00229 ETileDetail detail = TILE_DETAIL_LOW;
00230
00231
00232 top = new ssgBranch;
00233 char name[64];
00234 sprintf (name, "ST %d,%d", x, z);
00235 top->setName (name);
00236
00237
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
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
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
00283
00284
00285
00286
00287
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
00302 ReadInt (&dimn, stream);
00303
00304
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
00313 ReadInt (&type, stream);
00314 rc = TAG_READ;
00315 break;
00316
00317 case 'prta':
00318
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
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
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
00359 tref = NULL;
00360 dtArray = NULL;
00361 textureList = NULL;
00362
00363
00364 block = NULL;
00365
00366
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
00376 detail = TILE_DETAIL_LOW;
00377 }
00378
00379 CSlicedSuperTile::~CSlicedSuperTile (void)
00380 {
00381 if (IsCreated()) Destroy();
00382
00383 int i;
00384
00385
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
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
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
00426 ReadInt (&dimn, stream);
00427
00428
00429
00430
00431 if (dimn != 4) {
00432 gtfo ("CSlicedSuperTile::Read : <dimn>=%d, must be 4", dimn);
00433 }
00434
00435
00436 tref = new int*[dimn];
00437
00438 rc = TAG_READ;
00439 break;
00440
00441 case 'type':
00442
00443 ReadInt (&type, stream);
00444 rc = TAG_READ;
00445 break;
00446
00447 case 'prta':
00448
00449 ReadInt (&prta_x, stream);
00450 ReadInt (&prta_z, stream);
00451
00452
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
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
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
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
00500 gtfo ("CSuperTile : <dimn> tag must precede <elev> data");
00501 }
00502 rc = TAG_READ;
00503 break;
00504
00505 case 'hdtl':
00506
00507 if (dimn != 0) {
00508 int dx = x * dimn;
00509 int dz = z * dimn;
00510
00511
00512
00513
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
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
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
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
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
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
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
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
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
00616 state->enable (GL_TEXTURE_2D);
00617 state->setTexture (info.texid);
00618 state->disable (GL_COLOR_MATERIAL);
00619
00620
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
00628 ssgVertexArray *va = new ssgVertexArray(4);
00629 va->add (v1);
00630 va->add (v2);
00631 va->add (v3);
00632 va->add (v4);
00633
00634
00635 sgVec2 t1, t2, t3, t4;
00636 sgSetVec2 (t1, info.lls, info.llt);
00637 sgSetVec2 (t2, info.lls, info.urt);
00638 sgSetVec2 (t3, info.urs, info.llt);
00639 sgSetVec2 (t4, info.urs, info.urt);
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
00654 for (i=0; i<dimn; i++) {
00655 for (j=0; j<dimn; j++) {
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
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
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
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
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