/* ************************ Copyright Terrain Experts Inc. Terrain Experts Inc (TERREX) reserves all rights to this source code unless otherwise specified in writing by the President of TERREX. This copyright may be updated in the future, in which case that version supercedes this one. ------------------- Terrex Experts Inc. 4400 East Broadway #314 Tucson, AZ 85711 info@terrex.com Tel: (520) 323-7990 ************************ */ #include #include #include /* trpage_tile.cpp This source file contains the implementation of trpgTileTable and trpgTileHeader. You'll need to edit these if you want to add something to the Tile Table (at the front of an archive) or the Tile Header (at the beginning of each tile). */ #include #include /* Write Tile Table Keeps track of tiles written to disk. */ // Constructor trpgTileTable::trpgTileTable() { localBlock = false; Reset(); } // Reset function void trpgTileTable::Reset() { errMess[0] = '\0'; mode = External; lodInfo.resize(0); valid = true; currentRow = -1; currentCol = -1; } // Destructor trpgTileTable::~trpgTileTable() { } // Set functions void trpgTileTable::SetMode(TileMode inMode) { Reset(); mode = inMode; } void trpgTileTable::SetNumLod(int numLod) { lodInfo.resize(numLod); } void trpgTileTable::SetNumTiles(int nx,int ny,int lod) { if(localBlock) { LodInfo &li = lodInfo[lod]; li.numX = nx; li.numY = ny; li.addr.resize(1); li.elev_min.resize(1,0.0); li.elev_max.resize(1,0.0); valid = true; // no need to do anything else if we only have one block. return; } if (nx <= 0 || ny <= 0 || lod < 0 || lod >= static_cast(lodInfo.size())) return; // Got a table we need to maintain if (mode == Local || mode == ExternalSaved) { // If there's a pre-existing table, we need to preserve the entries LodInfo oldLodInfo = lodInfo[lod]; LodInfo &li = lodInfo[lod]; li.numX = nx; li.numY = ny; int numTile = li.numX*li.numY; li.addr.resize(numTile); li.elev_min.resize(numTile,0.0); li.elev_max.resize(numTile,0.0); // Copy pre-existing data if it's there if (oldLodInfo.addr.size() > 0) { for (int x=0;x= static_cast(lodInfo.size())) return; if (mode == External) return; LodInfo &li = lodInfo[lod]; int loc; if(localBlock) { loc = 0; } else { if (x < 0 || x >= li.numX || y < 0 || y >= li.numY) return; loc = y*li.numX + x; } li.addr[loc] = ref; li.elev_min[loc] = zmin; li.elev_max[loc] = zmax; } bool trpgTileTable::isValid() const { return valid; } // Get methods bool trpgTileTable::GetMode(TileMode &outMode) const { if (!isValid()) return false; outMode = mode; return true; } bool trpgTileTable::GetTile(int x,int y,int lod,trpgwAppAddress &ref,float32 &zmin,float32 &zmax) const { if (!isValid()) return false; if (lod < 0 || lod >= static_cast(lodInfo.size())) return false; if (mode == External) return false; const LodInfo &li = lodInfo[lod]; int loc; if(localBlock) { loc = 0; } else { if (x < 0 || x >= li.numX || y < 0 || y >= li.numY) return false; loc = y*li.numX + x; } ref = li.addr[loc]; zmin = li.elev_min[loc]; zmax = li.elev_max[loc]; return true; } // Write tile table bool trpgTileTable::Write(trpgWriteBuffer &buf) { if (!isValid()) return false; buf.Begin(TRPGTILETABLE2); // Write the mode buf.Add(mode); // Depending on the mode we'll have a lot or a little data if (mode == Local || mode == ExternalSaved) { // The lod sizing is redundant, but it's convenient here int numLod = lodInfo.size(); buf.Add(numLod); // Write each terrain LOD set for (int i=0;i= static_cast(matList.size())) return; matList[no] = id; } void trpgTileHeader::SetModel(int no,int id) { if (no < 0 || no >= static_cast(modelList.size())) return; modelList[no] = id; } // Set functions void trpgTileHeader::AddMaterial(int id) { // Look for it first for (unsigned int i=0;i= static_cast(locMats.size())) return false; retMat = locMats[id]; return true; } const std::vector *trpgTileHeader::GetLocalMaterialList() const { if (!isValid()) return NULL; return &locMats; } // Get methods bool trpgTileHeader::GetNumMaterial(int32 &no) const { if (!isValid()) return false; no = matList.size(); return true; } bool trpgTileHeader::GetMaterial(int32 id,int32 &mat) const { if (!isValid() || id < 0 || id >= static_cast(matList.size())) return false; mat = matList[id]; return true; } bool trpgTileHeader::GetNumModel(int32 &no) const { if (!isValid()) return false; no = modelList.size(); return true; } bool trpgTileHeader::GetModel(int32 id,int32 &m) const { if (!isValid() || id < 0 || id >= static_cast(modelList.size())) return false; m = modelList[id]; return true; } bool trpgTileHeader::GetDate(int32 &d) const { if (!isValid()) return false; d = date; return true; } // Validity check bool trpgTileHeader::isValid() const { return true; } // Write to a buffer bool trpgTileHeader::Write(trpgWriteBuffer &buf) { unsigned int i; if (!isValid()) return false; for (i=0;iAddMaterial(id); } break; case TRPG_TILE_MODELLIST: buf.Get(no); if (no < 0) throw 1; for (i=0;iAddModel(id); } break; case TRPG_TILE_DATE: buf.Get(date); head->SetDate(date); break; case TRPG_TILE_LOCMATLIST: { int32 numLocMat; buf.Get(numLocMat); if (numLocMat < 0) throw 1; std::vector *locMats; locMats = const_cast *> (head->GetLocalMaterialList()); locMats->resize(numLocMat); for (i=0;iGetBlockNo(addr.row,addr.col); locMat.SetAddr(addr); buf.PopLimit(); } } break; default: // Don't care break; } } catch (...) { return NULL; } return head; } // Read tile header bool trpgTileHeader::Read(trpgReadBuffer &buf) { tileHeaderCB tcb; trpgr_Parser parse; tcb.head = this; parse.AddCallback(TRPG_TILE_MATLIST,&tcb,false); parse.AddCallback(TRPG_TILE_MODELLIST,&tcb,false); parse.AddCallback(TRPG_TILE_DATE,&tcb,false); // New for 2.0 parse.AddCallback(TRPG_TILE_LOCMATLIST,&tcb,false); parse.Parse(buf); return isValid(); }