- 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 Faction;
|
||||||
class GameSettings;
|
class GameSettings;
|
||||||
|
|
||||||
|
class FowAlphaCellsLookupItem {
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::vector<Vec2i> surfPosList;
|
||||||
|
std::vector<float> alphaList;
|
||||||
|
|
||||||
|
static time_t lastDebug;
|
||||||
|
};
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class Faction
|
// class Faction
|
||||||
//
|
//
|
||||||
|
|
|
@ -486,6 +486,8 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos,
|
||||||
addItemToVault(&this->hp,this->hp);
|
addItemToVault(&this->hp,this->hp);
|
||||||
addItemToVault(&this->ep,this->ep);
|
addItemToVault(&this->ep,this->ep);
|
||||||
|
|
||||||
|
calculateFogOfWarRadius();
|
||||||
|
|
||||||
// if(isUnitDeleted(this) == true) {
|
// if(isUnitDeleted(this) == true) {
|
||||||
// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));
|
// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));
|
||||||
// deletedUnits.erase(this);
|
// deletedUnits.erase(this);
|
||||||
|
@ -1088,9 +1090,53 @@ void Unit::setPos(const Vec2i &pos, bool clearPathFinder) {
|
||||||
// Attempt to improve performance
|
// Attempt to improve performance
|
||||||
this->exploreCells();
|
this->exploreCells();
|
||||||
|
|
||||||
|
calculateFogOfWarRadius();
|
||||||
|
|
||||||
logSynchData(__FILE__,__LINE__);
|
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) {
|
void Unit::setTargetPos(const Vec2i &targetPos) {
|
||||||
|
|
||||||
if(map->isInside(targetPos) == false || map->isInsideSurface(map->toSurfCoords(targetPos)) == false) {
|
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->pathFindRefreshCellCount = unitNode->getAttribute("pathFindRefreshCellCount")->getIntValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result->calculateFogOfWarRadius();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -456,6 +456,7 @@ private:
|
||||||
RandomGen random;
|
RandomGen random;
|
||||||
int pathFindRefreshCellCount;
|
int pathFindRefreshCellCount;
|
||||||
|
|
||||||
|
FowAlphaCellsLookupItem cachedFow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
|
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 incrementPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount++; }
|
||||||
inline void resetPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount=0; }
|
inline void resetPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount=0; }
|
||||||
|
|
||||||
|
const FowAlphaCellsLookupItem & getCachedFow() const { return cachedFow; }
|
||||||
|
FowAlphaCellsLookupItem getFogOfWarRadius(bool useCache) const;
|
||||||
|
void calculateFogOfWarRadius();
|
||||||
|
|
||||||
//queries
|
//queries
|
||||||
Command *getCurrrentCommandThreadSafe();
|
Command *getCurrrentCommandThreadSafe();
|
||||||
void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;}
|
void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;}
|
||||||
|
|
|
@ -47,6 +47,7 @@ class Resource;
|
||||||
class TechTree;
|
class TechTree;
|
||||||
class GameSettings;
|
class GameSettings;
|
||||||
class World;
|
class World;
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class Cell
|
// class Cell
|
||||||
//
|
//
|
||||||
|
|
|
@ -54,7 +54,7 @@ World::World() {
|
||||||
ExploredCellsLookupItemCache.clear();
|
ExploredCellsLookupItemCache.clear();
|
||||||
ExploredCellsLookupItemCacheTimer.clear();
|
ExploredCellsLookupItemCacheTimer.clear();
|
||||||
ExploredCellsLookupItemCacheTimerCount = 0;
|
ExploredCellsLookupItemCacheTimerCount = 0;
|
||||||
FowAlphaCellsLookupItemCache.clear();
|
//FowAlphaCellsLookupItemCache.clear();
|
||||||
// Disable this cache as it takes too much RAM (not sure if its worth the performance gain)
|
// Disable this cache as it takes too much RAM (not sure if its worth the performance gain)
|
||||||
enableFowAlphaCellsLookupItemCache = config.getBool("EnableFowCache","true");
|
enableFowAlphaCellsLookupItemCache = config.getBool("EnableFowCache","true");
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ void World::cleanup() {
|
||||||
|
|
||||||
ExploredCellsLookupItemCache.clear();
|
ExploredCellsLookupItemCache.clear();
|
||||||
ExploredCellsLookupItemCacheTimer.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__);
|
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();
|
ExploredCellsLookupItemCache.clear();
|
||||||
ExploredCellsLookupItemCacheTimer.clear();
|
ExploredCellsLookupItemCacheTimer.clear();
|
||||||
FowAlphaCellsLookupItemCache.clear();
|
//FowAlphaCellsLookupItemCache.clear();
|
||||||
|
|
||||||
fogOfWarOverride = false;
|
fogOfWarOverride = false;
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ void World::end(){
|
||||||
|
|
||||||
ExploredCellsLookupItemCache.clear();
|
ExploredCellsLookupItemCache.clear();
|
||||||
ExploredCellsLookupItemCacheTimer.clear();
|
ExploredCellsLookupItemCacheTimer.clear();
|
||||||
FowAlphaCellsLookupItemCache.clear();
|
//FowAlphaCellsLookupItemCache.clear();
|
||||||
|
|
||||||
for(int i= 0; i<factions.size(); ++i){
|
for(int i= 0; i<factions.size(); ++i){
|
||||||
factions[i]->end();
|
factions[i]->end();
|
||||||
|
@ -215,7 +215,7 @@ void World::init(Game *game, bool createUnits, bool initFactions){
|
||||||
|
|
||||||
ExploredCellsLookupItemCache.clear();
|
ExploredCellsLookupItemCache.clear();
|
||||||
ExploredCellsLookupItemCacheTimer.clear();
|
ExploredCellsLookupItemCacheTimer.clear();
|
||||||
FowAlphaCellsLookupItemCache.clear();
|
//FowAlphaCellsLookupItemCache.clear();
|
||||||
|
|
||||||
this->game = game;
|
this->game = game;
|
||||||
scriptManager= game->getScriptManager();
|
scriptManager= game->getScriptManager();
|
||||||
|
@ -2238,6 +2238,26 @@ void World::computeFow(int factionIdxToTick) {
|
||||||
if(unit->isOperative()){
|
if(unit->isOperative()){
|
||||||
int sightRange= unit->getType()->getSight();
|
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;
|
bool foundInCache = false;
|
||||||
if(enableFowAlphaCellsLookupItemCache == true) {
|
if(enableFowAlphaCellsLookupItemCache == true) {
|
||||||
std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > >::iterator iterMap = FowAlphaCellsLookupItemCache.find(unit->getPos());
|
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);
|
minimap.incFowTextureAlphaSurface(surfPos, alpha);
|
||||||
|
|
||||||
itemCache.surfPosList.push_back(surfPos);
|
if(enableFowAlphaCellsLookupItemCache == true) {
|
||||||
itemCache.alphaList.push_back(alpha);
|
itemCache.surfPosList.push_back(surfPos);
|
||||||
|
itemCache.alphaList.push_back(alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enableFowAlphaCellsLookupItemCache == true) {
|
if(enableFowAlphaCellsLookupItemCache == true) {
|
||||||
|
@ -2293,6 +2315,7 @@ void World::computeFow(int factionIdxToTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2403,19 +2426,30 @@ string World::getFowAlphaCellsLookupItemCacheStats() {
|
||||||
int alphaListCount = 0;
|
int alphaListCount = 0;
|
||||||
|
|
||||||
//std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > > FowAlphaCellsLookupItemCache;
|
//std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > > FowAlphaCellsLookupItemCache;
|
||||||
for(std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > >::iterator iterMap1 = FowAlphaCellsLookupItemCache.begin();
|
// for(std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > >::iterator iterMap1 = FowAlphaCellsLookupItemCache.begin();
|
||||||
iterMap1 != FowAlphaCellsLookupItemCache.end(); ++iterMap1) {
|
// iterMap1 != FowAlphaCellsLookupItemCache.end(); ++iterMap1) {
|
||||||
posCount++;
|
// 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();
|
surfPosCount += cache.surfPosList.size();
|
||||||
iterMap2 != iterMap1->second.end(); ++iterMap2) {
|
alphaListCount += cache.alphaList.size();
|
||||||
sightCount++;
|
}
|
||||||
|
|
||||||
surfPosCount += iterMap2->second.surfPosList.size();
|
|
||||||
alphaListCount += iterMap2->second.alphaList.size();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 totalBytes = surfPosCount * sizeof(Vec2i);
|
uint64 totalBytes = surfPosCount * sizeof(Vec2i);
|
||||||
totalBytes += alphaListCount * sizeof(float);
|
totalBytes += alphaListCount * sizeof(float);
|
||||||
|
|
||||||
|
|
|
@ -76,15 +76,6 @@ public:
|
||||||
static time_t lastDebug;
|
static time_t lastDebug;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FowAlphaCellsLookupItem {
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::vector<Vec2i> surfPosList;
|
|
||||||
std::vector<float> alphaList;
|
|
||||||
|
|
||||||
static time_t lastDebug;
|
|
||||||
};
|
|
||||||
|
|
||||||
class World {
|
class World {
|
||||||
private:
|
private:
|
||||||
typedef vector<Faction *> Factions;
|
typedef vector<Faction *> Factions;
|
||||||
|
@ -94,7 +85,7 @@ private:
|
||||||
int ExploredCellsLookupItemCacheTimerCount;
|
int ExploredCellsLookupItemCacheTimerCount;
|
||||||
|
|
||||||
bool enableFowAlphaCellsLookupItemCache;
|
bool enableFowAlphaCellsLookupItemCache;
|
||||||
std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > > FowAlphaCellsLookupItemCache;
|
//std::map<Vec2i, std::map<int, FowAlphaCellsLookupItem > > FowAlphaCellsLookupItemCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int generationArea= 100;
|
static const int generationArea= 100;
|
||||||
|
@ -283,6 +274,8 @@ public:
|
||||||
std::vector<std::string> validateResourceTypes();
|
std::vector<std::string> validateResourceTypes();
|
||||||
|
|
||||||
void setFogOfWar(bool value);
|
void setFogOfWar(bool value);
|
||||||
|
bool getFogOfWar() const { return fogOfWar; }
|
||||||
|
|
||||||
std::string DumpWorldToLog(bool consoleBasicInfoOnly = false) const;
|
std::string DumpWorldToLog(bool consoleBasicInfoOnly = false) const;
|
||||||
|
|
||||||
inline int getUpdateFps(int factionIndex) const {
|
inline int getUpdateFps(int factionIndex) const {
|
||||||
|
|
Loading…
Reference in New Issue