mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
Various optimizations based on RMG profiling.
This commit is contained in:
parent
21386081bf
commit
156e19cdf6
@ -638,9 +638,10 @@ ETerrainGroup::ETerrainGroup CDrawTerrainOperation::getTerrainGroup(ETerrainType
|
||||
|
||||
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainView(const int3 & pos, const TerrainViewPattern & pattern, int recDepth /*= 0*/) const
|
||||
{
|
||||
auto flippedPattern = pattern;
|
||||
for(int flip = 0; flip < 4; ++flip)
|
||||
{
|
||||
auto valRslt = validateTerrainViewInner(pos, flip > 0 ? getFlippedPattern(pattern, flip) : pattern, recDepth);
|
||||
auto valRslt = validateTerrainViewInner(pos, flip > 0 ? flipPattern(flippedPattern, flip) : pattern, recDepth);
|
||||
if(valRslt.result)
|
||||
{
|
||||
valRslt.flip = flip;
|
||||
@ -795,31 +796,29 @@ bool CDrawTerrainOperation::isSandType(ETerrainType terType) const
|
||||
}
|
||||
}
|
||||
|
||||
TerrainViewPattern CDrawTerrainOperation::getFlippedPattern(const TerrainViewPattern & pattern, int flip) const
|
||||
TerrainViewPattern CDrawTerrainOperation::flipPattern(TerrainViewPattern & pattern, int flip) const
|
||||
{
|
||||
if(flip == 0)
|
||||
{
|
||||
return pattern;
|
||||
}
|
||||
|
||||
TerrainViewPattern ret = pattern;
|
||||
if(flip == FLIP_PATTERN_HORIZONTAL || flip == FLIP_PATTERN_BOTH)
|
||||
//always flip horizontal
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
int y = i * 3;
|
||||
std::swap(ret.data[y], ret.data[y + 2]);
|
||||
}
|
||||
int y = i * 3;
|
||||
std::swap(pattern.data[y], pattern.data[y + 2]);
|
||||
}
|
||||
if(flip == FLIP_PATTERN_VERTICAL || flip == FLIP_PATTERN_BOTH)
|
||||
//flip vertical only at 2nd step
|
||||
if(flip == FLIP_PATTERN_VERTICAL)
|
||||
{
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
std::swap(ret.data[i], ret.data[6 + i]);
|
||||
std::swap(pattern.data[i], pattern.data[6 + i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return pattern;
|
||||
}
|
||||
|
||||
void CDrawTerrainOperation::invalidateTerrainViews(const int3 & centerPos)
|
||||
|
@ -334,7 +334,7 @@ private:
|
||||
ValidationResult validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth = 0) const;
|
||||
/// Tests whether the given terrain type is a sand type. Sand types are: Water, Sand and Rock
|
||||
bool isSandType(ETerrainType terType) const;
|
||||
TerrainViewPattern getFlippedPattern(const TerrainViewPattern & pattern, int flip) const;
|
||||
TerrainViewPattern flipPattern(TerrainViewPattern & pattern, int flip) const;
|
||||
|
||||
static const int FLIP_PATTERN_HORIZONTAL = 1;
|
||||
static const int FLIP_PATTERN_VERTICAL = 2;
|
||||
|
@ -219,6 +219,12 @@ void CMapGenerator::fillZones()
|
||||
|
||||
logGlobal->infoStream() << "Started filling zones";
|
||||
|
||||
//initialize possible tiles before any object is actually placed
|
||||
for (auto it : zones)
|
||||
{
|
||||
it.second->initFreeTiles(this);
|
||||
}
|
||||
|
||||
createConnections();
|
||||
//make sure all connections are passable before creating borders
|
||||
for (auto it : zones)
|
||||
|
@ -378,6 +378,14 @@ void CRmgTemplateZone::discardDistantTiles (CMapGenerator* gen, float distance)
|
||||
});
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::initFreeTiles (CMapGenerator* gen)
|
||||
{
|
||||
vstd::copy_if (tileinfo, vstd::set_inserter(possibleTiles), [gen](const int3 &tile) -> bool
|
||||
{
|
||||
return gen->isPossible(tile);
|
||||
});
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::createBorder(CMapGenerator* gen)
|
||||
{
|
||||
for (auto tile : tileinfo)
|
||||
@ -1072,6 +1080,12 @@ void CRmgTemplateZone::createTreasures(CMapGenerator* gen)
|
||||
|
||||
do {
|
||||
|
||||
//optimization - don't check tiles which are not allowed
|
||||
vstd::erase_if (possibleTiles, [gen](const int3 &tile) -> bool
|
||||
{
|
||||
return !gen->isPossible(tile);
|
||||
});
|
||||
|
||||
int3 pos;
|
||||
if ( ! findPlaceForTreasurePile(gen, minDistance, pos))
|
||||
{
|
||||
@ -1144,7 +1158,7 @@ void CRmgTemplateZone::createObstacles(CMapGenerator* gen)
|
||||
if (canObstacleBePlacedHere(gen, temp, obstaclePos)) //can be placed here
|
||||
{
|
||||
auto obj = VLC->objtypeh->getHandlerFor(temp.id, temp.subid)->create(temp);
|
||||
placeObject(gen, obj, obstaclePos);
|
||||
placeObject(gen, obj, obstaclePos, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1171,6 +1185,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
freePaths.insert(pos); //zone center should be always clear to allow other tiles to connect
|
||||
|
||||
addAllPossibleObjects (gen);
|
||||
|
||||
placeMines(gen);
|
||||
createRequiredObjects(gen);
|
||||
fractalize(gen); //after required objects are created and linked with their own paths
|
||||
@ -1188,11 +1203,11 @@ bool CRmgTemplateZone::findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dis
|
||||
bool result = false;
|
||||
|
||||
//logGlobal->infoStream() << boost::format("Min dist for density %f is %d") % density % min_dist;
|
||||
for(auto tile : tileinfo)
|
||||
for(auto tile : possibleTiles)
|
||||
{
|
||||
auto dist = gen->getTile(tile).getNearestObjectDistance();
|
||||
|
||||
if (gen->isPossible(tile) && (dist >= min_dist) && (dist > best_distance))
|
||||
if ((dist >= min_dist) && (dist > best_distance))
|
||||
{
|
||||
bool allTilesAvailable = true;
|
||||
gen->foreach_neighbour (tile, [&gen, &allTilesAvailable](int3 neighbour)
|
||||
@ -1347,7 +1362,7 @@ void CRmgTemplateZone::checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance*
|
||||
//logGlobal->traceStream() << boost::format ("Successfully inserted object (%d,%d) at pos %s") %object->ID %object->subID %pos();
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos)
|
||||
void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, bool updateDistance)
|
||||
{
|
||||
//logGlobal->traceStream() << boost::format("Inserting object at %d %d") % pos.x % pos.y;
|
||||
|
||||
@ -1364,10 +1379,13 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
gen->setOccupied(p, ETileType::USED);
|
||||
}
|
||||
}
|
||||
for(auto tile : tileinfo)
|
||||
{
|
||||
si32 d = pos.dist2dSQ(tile); //optimization, only relative distance is interesting
|
||||
gen->setNearestObjectDistance(tile, std::min(d, gen->getNearestObjectDistance(tile)));
|
||||
if (updateDistance)
|
||||
{
|
||||
for(auto tile : possibleTiles) //don't need to mark distance for not possible tiles
|
||||
{
|
||||
si32 d = pos.dist2dSQ(tile); //optimization, only relative distance is interesting
|
||||
gen->setNearestObjectDistance(tile, std::min(d, gen->getNearestObjectDistance(tile)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1461,7 +1479,7 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
|
||||
ui32 minValue = 0.25f * value;
|
||||
|
||||
//roulette wheel
|
||||
for (auto oi : possibleObjects)
|
||||
for (ObjectInfo &oi : possibleObjects) //copy constructor turned out to be costly
|
||||
{
|
||||
if (oi.value >= minValue && oi.value <= value && oi.maxPerZone > 0)
|
||||
{
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
void setPos(const int3 &pos);
|
||||
|
||||
void addTile (const int3 &pos);
|
||||
void initFreeTiles (CMapGenerator* gen);
|
||||
std::set<int3> getTileInfo () const;
|
||||
void discardDistantTiles (CMapGenerator* gen, float distance);
|
||||
|
||||
@ -206,6 +207,7 @@ private:
|
||||
int3 pos;
|
||||
float3 center;
|
||||
std::set<int3> tileinfo; //irregular area assined to zone
|
||||
std::set<int3> possibleTiles; //optimization purposes for treasure generation
|
||||
std::vector<TRmgTemplateZoneId> connections; //list of adjacent zones
|
||||
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
|
||||
|
||||
@ -216,6 +218,6 @@ private:
|
||||
bool findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dist, int3 &pos);
|
||||
bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos);
|
||||
void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, bool updateDistance = true);
|
||||
bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str, bool zoneGuard = false);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user