trpage_managers.cpp
来自「最新osg包」· C++ 代码 · 共 1,227 行 · 第 1/3 页
CPP
1,227 行
void trpgPageManager::LodPageInfo::AckUnload(){ if (activeUnload) { trpgManagedTile *tile = unload[0]; tile->Reset(); freeList.push_back(tile); unload.pop_front(); } activeUnload = false;}bool trpgPageManager::LodPageInfo::isWithin(trpgManagedTile *tile,trpg2iPoint &sw,trpg2iPoint &ne){ int tileX,tileY,tileLod; tile->GetTileLoc(tileX,tileY,tileLod); if (tileX >= sw.x && tileX <= ne.x && tileY >= sw.y && tileY <= ne.y) return true; else return false;}bool trpgPageManager::LodPageInfo::Stop(){ // Empty the load list unsigned int i; for (i=0;i<load.size();i++) freeList.push_back(load[i]); load.resize(0); // Move the current tiles to the unload list for (i=0;i<current.size();i++) if (current[i]) unload.push_back(current[i]); current.resize(0); return (unload.size() > 0);}void trpgPageManager::LodPageInfo::AddChildrenToLoadList(std::vector<trpgManagedTile*>& parentList){ if(parentList.size() == 0) return; // Area coverage, in cell unit trpg2iPoint sw,ne; sw.x = cell.x - aoiSize.x; sw.y = cell.y - aoiSize.y; ne.x = cell.x + aoiSize.x; ne.y = cell.y + aoiSize.y; sw.x = MAX(0,sw.x); sw.y = MAX(0,sw.y); ne.x = MIN(lodSize.x-1,ne.x); ne.y = MIN(lodSize.y-1,ne.y); int dx = ne.x - sw.x +1; int dy = ne.y - sw.y +1; // Mark the one that are already there tmpCurrent.resize(dx*dy); std::fill(tmpCurrent.begin(), tmpCurrent.end(), false); for (unsigned int i = 0; i<current.size(); i++) { trpgManagedTile *tile = current[i]; if (tile) { int tileX,tileY,tileLod; tile->GetTileLoc(tileX,tileY,tileLod); tmpCurrent[(tileY-sw.y)*dx + (tileX-sw.x)] = true; } } for (unsigned int i=0;i<load.size();i++) { trpgManagedTile *tile = load[i]; if (tile) { int tileX,tileY,tileLod; tile->GetTileLoc(tileX,tileY,tileLod); tmpCurrent[(tileY-sw.y)*dx + (tileX-sw.x)] = true; } } for(unsigned int parentIdx = 0; parentIdx < parentList.size(); ++parentIdx) { trpgManagedTile* parentTile = parentList[parentIdx]; unsigned int nbChildren = parentTile->GetNbChildren(); for(unsigned int childIdx = 0; childIdx < nbChildren; ++childIdx) { const TileLocationInfo& childLoc = parentTile->GetChildLocationInfo(childIdx); // a sanity check: if the lod is not the same then this // parent is not at the right place if(childLoc.lod != lod) break; // Make sure it is within if (childLoc.x >= sw.x && childLoc.x <= ne.x && childLoc.y >= sw.y && childLoc.y <= ne.y) { // Is it alread there ? if(!tmpCurrent[(childLoc.y - sw.y)*dx + (childLoc.x - sw.x)]) { // Not there, add it AddToLoadList(childLoc.x, childLoc.y, childLoc.addr); } } } }} bool trpgPageManager::LodPageInfo::AddToLoadList(int x, int y, const trpgwAppAddress& addr){ trpg2iPoint sw,ne; // Figure out the lower left and upper right corners // in cell coordinates sw.x = cell.x - aoiSize.x; sw.y = cell.y - aoiSize.y; ne.x = cell.x + aoiSize.x; ne.y = cell.y + aoiSize.y; sw.x = MAX(0,sw.x); sw.y = MAX(0,sw.y); ne.x = MIN(lodSize.x-1,ne.x); ne.y = MIN(lodSize.y-1,ne.y); if (x >= sw.x && x <= ne.x && y >= sw.y && y <= ne.y) { trpgManagedTile *tile = 0; if(freeList.size() > 0){ tile = freeList[0]; freeList.pop_front(); } else tile = new trpgManagedTile(); tile->SetTileLoc(x, y, lod); tile->SetTileAddress(addr); load.push_back(tile); return true; } else return false;}/* Update does the major work of figuring out what to load and what to unload.*/void trpgPageManager::LodPageInfo::Update(){ trpg2iPoint sw,ne; // Figure out the lower left and upper right corners // in cell coordinates sw.x = cell.x - aoiSize.x; sw.y = cell.y - aoiSize.y; ne.x = cell.x + aoiSize.x; ne.y = cell.y + aoiSize.y; sw.x = MAX(0,sw.x); sw.y = MAX(0,sw.y); ne.x = MIN(lodSize.x-1,ne.x); ne.y = MIN(lodSize.y-1,ne.y); /* Load list - Some of the tiles we're supposed to load may now be out of range. Take them off the load list. */ unsigned int i; for (i=0;i<load.size();i++) { if (load[i] && !isWithin(load[i],sw,ne)) { freeList.push_back(load[i]); load[i] = NULL; } } /* Unload list - Some of the tiles we were planning on unloading may now be in view again. Move them back to current. */ for (i=0;i<unload.size();i++) { if (unload[i] && isWithin(unload[i],sw,ne)) { current.push_back(unload[i]); unload[i] = NULL; } } /* Current list - We need to figure out a few things here. 1) What's in the current list that should be paged out. 2) What's already paged, sorted into tmpCurrent. 3) What's missing from tmpCurrent and should be paged in. */ // Look for tiles to page out // Move them to the unload list for (i=0;i<current.size();i++) { if (current[i] && !isWithin(current[i],sw,ne)) { unload.push_back(current[i]); current[i] = NULL; } } // Clean the NULLs out of the current list int curPos = 0; for (i=0;i<current.size();i++) { if (current[i]) { current[curPos] = current[i]; curPos++; } } current.resize(curPos); bool doUpdate = true; if(majorVersion == 2 && minorVersion >= 1) { // Version 2.1, we update only lod 0 since the tile table // will only contain lod 0. All tiles from other lod must be // update through the trpgPageManager::AckLoad(tile info) if(lod != 0) doUpdate = false; } if(doUpdate) { // Sort the currently loaded stuff into a spatial array // so we can figure out what needs to be loaded in addition. int dx,dy; dx = ne.x - sw.x+1; dy = ne.y - sw.y+1; tmpCurrent.resize(dx*dy); for (i=0;i<tmpCurrent.size();i++) tmpCurrent[i] = false; for (i=0;i<current.size();i++) { trpgManagedTile *tile = current[i]; if (tile) { int tileX,tileY,tileLod; tile->GetTileLoc(tileX,tileY,tileLod); tmpCurrent[(tileY-sw.y)*dx + (tileX-sw.x)] = true; } } // Now figure out which ones are missing and add them // to the load list for (int x=0;x<dx;x++) { for (int y=0;y<dy;y++) { if (!tmpCurrent[y*dx + x]) { // Allocate a new tile trpgManagedTile *tile = NULL; if (freeList.size() > 0) { tile = freeList[0]; freeList.pop_front(); } else tile = new trpgManagedTile(); tile->SetTileLoc(x+sw.x,y+sw.y,lod); trpgwAppAddress addr; float32 zmin, zmax; if(tileTable && tileTable->GetTile(x+sw.x, y+sw.y, lod, addr, zmin, zmax)) tile->SetTileAddress(addr); load.push_back(tile); } } } } // That's it. All the rest is handled by the caller // iterating through the tiles to load and unload.}// Get the list of currently loaded tiles that falls wiithin the area calculted from// the given paging distancevoid trpgPageManager::LodPageInfo::GetLoadedTileWithin(double pagingDistance, std::vector<trpgManagedTile*>& tileList){ trpg2iPoint aoi_size((int)(pagingDistance/cellSize.x) +1, (int)(pagingDistance/cellSize.y) +1); // Calculate the area that we must check, in parent cell coordinate trpg2iPoint sw, ne; sw.x = cell.x - aoi_size.x; sw.y = cell.y - aoi_size.y; ne.x = cell.x + aoi_size.x; ne.y = cell.y + aoi_size.y; sw.x = MAX(0,sw.x); sw.y = MAX(0,sw.y); ne.x = MIN(lodSize.x-1,ne.x); ne.y = MIN(lodSize.y-1,ne.y); tileList.clear(); for (unsigned i=0; i <current.size(); i++) { if (current[i] && isWithin(current[i],sw,ne)) tileList.push_back(current[i]); }}void trpgPageManager::LodPageInfo::Print(trpgPrintBuffer &buf){ char line[1024]; unsigned int i; sprintf(line,"lod = %d, valid = %s",lod,(valid ? "yes" : "no")); buf.prnLine(line); sprintf(line,"pageDist = %f, maxNumTiles = %d",pageDist,maxNumTiles); buf.prnLine(line); sprintf(line,"cellSize = (%f,%f)",cellSize.x,cellSize.y); buf.prnLine(line); sprintf(line,"cell = (%d,%d), aoiSize = (%d,%d), lodSize = (%d,%d)",cell.x,cell.y,aoiSize.x,aoiSize.y,lodSize.x,lodSize.y); buf.prnLine(line); sprintf(line,"Loads: (activeLoad = %s)",(activeLoad ? "yes" : "no")); buf.prnLine(line); buf.IncreaseIndent(); for (i=0;i<load.size();i++) if (load[i]) load[i]->Print(buf); buf.DecreaseIndent(); sprintf(line,"Unloads: (activeUnload = %s)",(activeUnload ? "yes" : "no")); buf.prnLine(line); buf.IncreaseIndent(); for (i=0;i<unload.size();i++) if (unload[i]) unload[i]->Print(buf); buf.DecreaseIndent(); buf.prnLine("Currently loaded:"); buf.IncreaseIndent(); for (i=0;i<current.size();i++) if (current[i]) current[i]->Print(buf); buf.DecreaseIndent(); sprintf(line,"Free list size = %d", (int)freeList.size()); buf.prnLine(line);}/* Page Manager methods These are methods of the main trpgPageManager. Check the header file for more detailed information.*/trpgPageManager::trpgPageManager(){ scale = 1.0; valid = false; // This should be sufficiently unlikely pagePt.x = -1e20; pagePt.y = -1e20;}trpgPageManager::~trpgPageManager(){}void trpgPageManager::Init(trpgr_Archive *inArch){ archive = inArch; // We're resetting everything. In general, Init should only // be called once, but it'll work fine if you call it more than once. lastLoad = None; lastTile = NULL; lastLod = -1; // Need to know the number of terrain LODs const trpgHeader *head = archive->GetHeader(); int numLod; head->GetNumLods(numLod); head->GetVersion(majorVersion, minorVersion); // Reset the terrain LOD paging classes. valid = true; pageInfo.resize(numLod); for (int i=0;i<numLod;i++) { if(i > 3) pageInfo[i].Init(archive,i,scale, 4); else pageInfo[i].Init(archive,i,scale); }}// We might want to init only to support the tile table content.// For Version 2.1 the tile table contain only lod 0.// We might want to do that to use another paging scheme for// lower lodvoid trpgPageManager::Init(trpgr_Archive *inArch, int maxLod){ archive = inArch; // We're resetting everything. In general, Init should only // be called once, but it'll work fine if you call it more than once. lastLoad = None; lastTile = NULL; lastLod = -1; // Need to know the number of terrain LODs const trpgHeader *head = archive->GetHeader(); int numLod; head->GetNumLods(numLod); head->GetVersion(majorVersion, minorVersion); if(maxLod > numLod) maxLod = numLod; // Reset the terrain LOD paging classes. valid = true; pageInfo.resize(maxLod); for (int i=0;i<maxLod;i++) { if(i > 3) pageInfo[i].Init(archive,i,scale, 4); else pageInfo[i].Init(archive,i,scale); }}bool trpgPageManager::SetPageDistFactor(double inFact){ // A scaling factor less than 1 will break the archive display. if (inFact <= 1.0) return false;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?