mirror of
https://github.com/glest/glest-source.git
synced 2025-02-25 12:12:25 +01:00
- a better way to cache fog of war and use much less memory
This commit is contained in:
parent
5a2adde414
commit
b96eba3829
@ -51,6 +51,15 @@ class World;
|
||||
class Faction;
|
||||
class GameSettings;
|
||||
|
||||
class FowAlphaCellsLookupItem {
|
||||
public:
|
||||
|
||||
std::vector<Vec2i> surfPosList;
|
||||
std::vector<float> alphaList;
|
||||
|
||||
static time_t lastDebug;
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class Faction
|
||||
//
|
||||
|
@ -486,6 +486,8 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos,
|
||||
addItemToVault(&this->hp,this->hp);
|
||||
addItemToVault(&this->ep,this->ep);
|
||||
|
||||
calculateFogOfWarRadius();
|
||||
|
||||
// if(isUnitDeleted(this) == true) {
|
||||
// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));
|
||||
// deletedUnits.erase(this);
|
||||
@ -1088,9 +1090,53 @@ void Unit::setPos(const Vec2i &pos, bool clearPathFinder) {
|
||||
// Attempt to improve performance
|
||||
this->exploreCells();
|
||||
|
||||
calculateFogOfWarRadius();
|
||||
|
||||
logSynchData(__FILE__,__LINE__);
|
||||
}
|
||||
|
||||
FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const {
|
||||
if(useCache == true && Config::getInstance().getBool("EnableFowCache","true") == true) {
|
||||
return cachedFow;
|
||||
}
|
||||
|
||||
FowAlphaCellsLookupItem result;
|
||||
//iterate through all cells
|
||||
int sightRange= this->getType()->getSight();
|
||||
PosCircularIterator pci(map, this->getPos(), sightRange + World::indirectSightRange);
|
||||
while(pci.next()){
|
||||
const Vec2i sightpos= pci.getPos();
|
||||
Vec2i surfPos= Map::toSurfCoords(sightpos);
|
||||
|
||||
//compute max alpha
|
||||
float maxAlpha= 0.0f;
|
||||
if(surfPos.x > 1 && surfPos.y > 1 && surfPos.x < map->getSurfaceW() -2 && surfPos.y < map->getSurfaceH() -2) {
|
||||
maxAlpha= 1.f;
|
||||
}
|
||||
else if(surfPos.x > 0 && surfPos.y > 0 && surfPos.x < map->getSurfaceW() -1 && surfPos.y < map->getSurfaceH() -1) {
|
||||
maxAlpha= 0.3f;
|
||||
}
|
||||
|
||||
//compute alpha
|
||||
float alpha = maxAlpha;
|
||||
float dist = this->getPos().dist(sightpos);
|
||||
if(dist > sightRange) {
|
||||
alpha= clamp(1.f-(dist - sightRange) / (World::indirectSightRange), 0.f, maxAlpha);
|
||||
}
|
||||
result.surfPosList.push_back(surfPos);
|
||||
result.alphaList.push_back(alpha);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Unit::calculateFogOfWarRadius() {
|
||||
if(game->getWorld()->getFogOfWar() == true) {
|
||||
if(Config::getInstance().getBool("EnableFowCache","true") == true && this->pos != this->lastPos) {
|
||||
cachedFow = getFogOfWarRadius(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setTargetPos(const Vec2i &targetPos) {
|
||||
|
||||
if(map->isInside(targetPos) == false || map->isInsideSurface(map->toSurfCoords(targetPos)) == false) {
|
||||
@ -4279,6 +4325,8 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *
|
||||
result->pathFindRefreshCellCount = unitNode->getAttribute("pathFindRefreshCellCount")->getIntValue();
|
||||
}
|
||||
|
||||
result->calculateFogOfWarRadius();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -456,6 +456,7 @@ private:
|
||||
RandomGen random;
|
||||
int pathFindRefreshCellCount;
|
||||
|
||||
FowAlphaCellsLookupItem cachedFow;
|
||||
|
||||
public:
|
||||
Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
|
||||
@ -478,6 +479,10 @@ public:
|
||||
inline void incrementPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount++; }
|
||||
inline void resetPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount=0; }
|
||||
|
||||
const FowAlphaCellsLookupItem & getCachedFow() const { return cachedFow; }
|
||||
FowAlphaCellsLookupItem getFogOfWarRadius(bool useCache) const;
|
||||
void calculateFogOfWarRadius();
|
||||
|
||||
//queries
|
||||
Command *getCurrrentCommandThreadSafe();
|
||||
void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;}
|
||||
|
@ -47,6 +47,7 @@ class Resource;
|
||||
class TechTree;
|
||||
class GameSettings;
|
||||
class World;
|
||||
|
||||
// =====================================================
|
||||
// class Cell
|
||||
//
|
||||
|
@ -54,7 +54,7 @@ World::World() {
|
||||
ExploredCellsLookupItemCache.clear();
|
||||
ExploredCellsLookupItemCacheTimer.clear();
|
||||
ExploredCellsLookupItemCacheTimerCount = 0;
|
||||
FowAlphaCellsLookupItemCache.clear();
|
||||
//FowAlphaCellsLookupItemCache.clear();
|
||||
// Disable this cache as it takes too much RAM (not sure if its worth the performance gain)
|
||||
enableFowAlphaCellsLookupItemCache = config.getBool("EnableFowCache","true");
|
||||
|
||||
@ -92,7 +92,7 @@ void World::cleanup() {
|
||||
|
||||
ExploredCellsLookupItemCache.clear();
|
||||
ExploredCellsLookupItemCacheTimer.clear();
|
||||
FowAlphaCellsLookupItemCache.clear();
|
||||
//FowAlphaCellsLookupItemCache.clear();
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
@ -150,7 +150,7 @@ void World::endScenario() {
|
||||
|
||||
ExploredCellsLookupItemCache.clear();
|
||||
ExploredCellsLookupItemCacheTimer.clear();
|
||||
FowAlphaCellsLookupItemCache.clear();
|
||||
//FowAlphaCellsLookupItemCache.clear();
|
||||
|
||||
fogOfWarOverride = false;
|
||||
|
||||
@ -166,7 +166,7 @@ void World::end(){
|
||||
|
||||
ExploredCellsLookupItemCache.clear();
|
||||
ExploredCellsLookupItemCacheTimer.clear();
|
||||
FowAlphaCellsLookupItemCache.clear();
|
||||
//FowAlphaCellsLookupItemCache.clear();
|
||||
|
||||
for(int i= 0; i<factions.size(); ++i){
|
||||
factions[i]->end();
|
||||
@ -215,7 +215,7 @@ void World::init(Game *game, bool createUnits, bool initFactions){
|
||||
|
||||
ExploredCellsLookupItemCache.clear();
|
||||
ExploredCellsLookupItemCacheTimer.clear();
|
||||
FowAlphaCellsLookupItemCache.clear();
|
||||
//FowAlphaCellsLookupItemCache.clear();
|
||||
|
||||
this->game = game;
|
||||
scriptManager= game->getScriptManager();
|
||||
@ -2238,6 +2238,26 @@ void World::computeFow(int factionIdxToTick) {
|
||||
if(unit->isOperative()){
|
||||
int sightRange= unit->getType()->getSight();
|
||||
|
||||
if(enableFowAlphaCellsLookupItemCache == true) {
|
||||
const FowAlphaCellsLookupItem &cellList = unit->getCachedFow();
|
||||
for(int k = 0; k < cellList.surfPosList.size(); ++k) {
|
||||
const Vec2i &surfPos = cellList.surfPosList[k];
|
||||
const float &alpha = cellList.alphaList[k];
|
||||
|
||||
minimap.incFowTextureAlphaSurface(surfPos, alpha);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const FowAlphaCellsLookupItem cellList = unit->getFogOfWarRadius(false);
|
||||
for(int k = 0; k < cellList.surfPosList.size(); ++k) {
|
||||
const Vec2i &surfPos = cellList.surfPosList[k];
|
||||
const float &alpha = cellList.alphaList[k];
|
||||
|
||||
minimap.incFowTextureAlphaSurface(surfPos, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bool foundInCache = false;
|
||||
if(enableFowAlphaCellsLookupItemCache == true) {
|
||||
std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > >::iterator iterMap = FowAlphaCellsLookupItemCache.find(unit->getPos());
|
||||
@ -2283,8 +2303,10 @@ void World::computeFow(int factionIdxToTick) {
|
||||
}
|
||||
minimap.incFowTextureAlphaSurface(surfPos, alpha);
|
||||
|
||||
itemCache.surfPosList.push_back(surfPos);
|
||||
itemCache.alphaList.push_back(alpha);
|
||||
if(enableFowAlphaCellsLookupItemCache == true) {
|
||||
itemCache.surfPosList.push_back(surfPos);
|
||||
itemCache.alphaList.push_back(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
if(enableFowAlphaCellsLookupItemCache == true) {
|
||||
@ -2293,6 +2315,7 @@ void World::computeFow(int factionIdxToTick) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2403,19 +2426,30 @@ string World::getFowAlphaCellsLookupItemCacheStats() {
|
||||
int alphaListCount = 0;
|
||||
|
||||
//std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > > FowAlphaCellsLookupItemCache;
|
||||
for(std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > >::iterator iterMap1 = FowAlphaCellsLookupItemCache.begin();
|
||||
iterMap1 != FowAlphaCellsLookupItemCache.end(); ++iterMap1) {
|
||||
posCount++;
|
||||
// for(std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > >::iterator iterMap1 = FowAlphaCellsLookupItemCache.begin();
|
||||
// iterMap1 != FowAlphaCellsLookupItemCache.end(); ++iterMap1) {
|
||||
// posCount++;
|
||||
//
|
||||
// for(std::map<int, FowAlphaCellsLookupItem >::iterator iterMap2 = iterMap1->second.begin();
|
||||
// iterMap2 != iterMap1->second.end(); ++iterMap2) {
|
||||
// sightCount++;
|
||||
//
|
||||
// surfPosCount += iterMap2->second.surfPosList.size();
|
||||
// alphaListCount += iterMap2->second.alphaList.size();
|
||||
// }
|
||||
// }
|
||||
for(int i=0; i<getFactionCount(); ++i) {
|
||||
Faction *faction= getFaction(i);
|
||||
if(faction->getTeam() == thisTeamIndex) {
|
||||
for(int j=0; j<faction->getUnitCount(); ++j) {
|
||||
const Unit *unit= faction->getUnit(j);
|
||||
const FowAlphaCellsLookupItem &cache = unit->getCachedFow();
|
||||
|
||||
for(std::map<int, FowAlphaCellsLookupItem >::iterator iterMap2 = iterMap1->second.begin();
|
||||
iterMap2 != iterMap1->second.end(); ++iterMap2) {
|
||||
sightCount++;
|
||||
|
||||
surfPosCount += iterMap2->second.surfPosList.size();
|
||||
alphaListCount += iterMap2->second.alphaList.size();
|
||||
surfPosCount += cache.surfPosList.size();
|
||||
alphaListCount += cache.alphaList.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64 totalBytes = surfPosCount * sizeof(Vec2i);
|
||||
totalBytes += alphaListCount * sizeof(float);
|
||||
|
||||
|
@ -76,15 +76,6 @@ public:
|
||||
static time_t lastDebug;
|
||||
};
|
||||
|
||||
class FowAlphaCellsLookupItem {
|
||||
public:
|
||||
|
||||
std::vector<Vec2i> surfPosList;
|
||||
std::vector<float> alphaList;
|
||||
|
||||
static time_t lastDebug;
|
||||
};
|
||||
|
||||
class World {
|
||||
private:
|
||||
typedef vector<Faction *> Factions;
|
||||
@ -94,7 +85,7 @@ private:
|
||||
int ExploredCellsLookupItemCacheTimerCount;
|
||||
|
||||
bool enableFowAlphaCellsLookupItemCache;
|
||||
std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > > FowAlphaCellsLookupItemCache;
|
||||
//std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > > FowAlphaCellsLookupItemCache;
|
||||
|
||||
public:
|
||||
static const int generationArea= 100;
|
||||
@ -283,6 +274,8 @@ public:
|
||||
std::vector<std::string> validateResourceTypes();
|
||||
|
||||
void setFogOfWar(bool value);
|
||||
bool getFogOfWar() const { return fogOfWar; }
|
||||
|
||||
std::string DumpWorldToLog(bool consoleBasicInfoOnly = false) const;
|
||||
|
||||
inline int getUpdateFps(int factionIndex) const {
|
||||
|
Loading…
x
Reference in New Issue
Block a user