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 + -
显示快捷键?