mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-05 13:04:54 +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
|
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainView(const int3 & pos, const TerrainViewPattern & pattern, int recDepth /*= 0*/) const
|
||||||
{
|
{
|
||||||
|
auto flippedPattern = pattern;
|
||||||
for(int flip = 0; flip < 4; ++flip)
|
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)
|
if(valRslt.result)
|
||||||
{
|
{
|
||||||
valRslt.flip = flip;
|
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)
|
if(flip == 0)
|
||||||
{
|
{
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainViewPattern ret = pattern;
|
//always flip horizontal
|
||||||
if(flip == FLIP_PATTERN_HORIZONTAL || flip == FLIP_PATTERN_BOTH)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
int y = i * 3;
|
int y = i * 3;
|
||||||
std::swap(ret.data[y], ret.data[y + 2]);
|
std::swap(pattern.data[y], pattern.data[y + 2]);
|
||||||
}
|
}
|
||||||
}
|
//flip vertical only at 2nd step
|
||||||
if(flip == FLIP_PATTERN_VERTICAL || flip == FLIP_PATTERN_BOTH)
|
if(flip == FLIP_PATTERN_VERTICAL)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 3; ++i)
|
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)
|
void CDrawTerrainOperation::invalidateTerrainViews(const int3 & centerPos)
|
||||||
|
@ -334,7 +334,7 @@ private:
|
|||||||
ValidationResult validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth = 0) const;
|
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
|
/// Tests whether the given terrain type is a sand type. Sand types are: Water, Sand and Rock
|
||||||
bool isSandType(ETerrainType terType) const;
|
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_HORIZONTAL = 1;
|
||||||
static const int FLIP_PATTERN_VERTICAL = 2;
|
static const int FLIP_PATTERN_VERTICAL = 2;
|
||||||
|
@ -219,6 +219,12 @@ void CMapGenerator::fillZones()
|
|||||||
|
|
||||||
logGlobal->infoStream() << "Started filling zones";
|
logGlobal->infoStream() << "Started filling zones";
|
||||||
|
|
||||||
|
//initialize possible tiles before any object is actually placed
|
||||||
|
for (auto it : zones)
|
||||||
|
{
|
||||||
|
it.second->initFreeTiles(this);
|
||||||
|
}
|
||||||
|
|
||||||
createConnections();
|
createConnections();
|
||||||
//make sure all connections are passable before creating borders
|
//make sure all connections are passable before creating borders
|
||||||
for (auto it : zones)
|
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)
|
void CRmgTemplateZone::createBorder(CMapGenerator* gen)
|
||||||
{
|
{
|
||||||
for (auto tile : tileinfo)
|
for (auto tile : tileinfo)
|
||||||
@ -1072,6 +1080,12 @@ void CRmgTemplateZone::createTreasures(CMapGenerator* gen)
|
|||||||
|
|
||||||
do {
|
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;
|
int3 pos;
|
||||||
if ( ! findPlaceForTreasurePile(gen, minDistance, pos))
|
if ( ! findPlaceForTreasurePile(gen, minDistance, pos))
|
||||||
{
|
{
|
||||||
@ -1144,7 +1158,7 @@ void CRmgTemplateZone::createObstacles(CMapGenerator* gen)
|
|||||||
if (canObstacleBePlacedHere(gen, temp, obstaclePos)) //can be placed here
|
if (canObstacleBePlacedHere(gen, temp, obstaclePos)) //can be placed here
|
||||||
{
|
{
|
||||||
auto obj = VLC->objtypeh->getHandlerFor(temp.id, temp.subid)->create(temp);
|
auto obj = VLC->objtypeh->getHandlerFor(temp.id, temp.subid)->create(temp);
|
||||||
placeObject(gen, obj, obstaclePos);
|
placeObject(gen, obj, obstaclePos, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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
|
freePaths.insert(pos); //zone center should be always clear to allow other tiles to connect
|
||||||
|
|
||||||
addAllPossibleObjects (gen);
|
addAllPossibleObjects (gen);
|
||||||
|
|
||||||
placeMines(gen);
|
placeMines(gen);
|
||||||
createRequiredObjects(gen);
|
createRequiredObjects(gen);
|
||||||
fractalize(gen); //after required objects are created and linked with their own paths
|
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;
|
bool result = false;
|
||||||
|
|
||||||
//logGlobal->infoStream() << boost::format("Min dist for density %f is %d") % density % min_dist;
|
//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();
|
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;
|
bool allTilesAvailable = true;
|
||||||
gen->foreach_neighbour (tile, [&gen, &allTilesAvailable](int3 neighbour)
|
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();
|
//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;
|
//logGlobal->traceStream() << boost::format("Inserting object at %d %d") % pos.x % pos.y;
|
||||||
|
|
||||||
@ -1364,12 +1379,15 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
|||||||
gen->setOccupied(p, ETileType::USED);
|
gen->setOccupied(p, ETileType::USED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(auto tile : tileinfo)
|
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
|
si32 d = pos.dist2dSQ(tile); //optimization, only relative distance is interesting
|
||||||
gen->setNearestObjectDistance(tile, std::min(d, gen->getNearestObjectDistance(tile)));
|
gen->setNearestObjectDistance(tile, std::min(d, gen->getNearestObjectDistance(tile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CRmgTemplateZone::placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard)
|
void CRmgTemplateZone::placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard)
|
||||||
{
|
{
|
||||||
@ -1461,7 +1479,7 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
|
|||||||
ui32 minValue = 0.25f * value;
|
ui32 minValue = 0.25f * value;
|
||||||
|
|
||||||
//roulette wheel
|
//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)
|
if (oi.value >= minValue && oi.value <= value && oi.maxPerZone > 0)
|
||||||
{
|
{
|
||||||
|
@ -145,6 +145,7 @@ public:
|
|||||||
void setPos(const int3 &pos);
|
void setPos(const int3 &pos);
|
||||||
|
|
||||||
void addTile (const int3 &pos);
|
void addTile (const int3 &pos);
|
||||||
|
void initFreeTiles (CMapGenerator* gen);
|
||||||
std::set<int3> getTileInfo () const;
|
std::set<int3> getTileInfo () const;
|
||||||
void discardDistantTiles (CMapGenerator* gen, float distance);
|
void discardDistantTiles (CMapGenerator* gen, float distance);
|
||||||
|
|
||||||
@ -206,6 +207,7 @@ private:
|
|||||||
int3 pos;
|
int3 pos;
|
||||||
float3 center;
|
float3 center;
|
||||||
std::set<int3> tileinfo; //irregular area assined to zone
|
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::vector<TRmgTemplateZoneId> connections; //list of adjacent zones
|
||||||
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
|
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 findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dist, int3 &pos);
|
||||||
bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos);
|
bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos);
|
||||||
void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const 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);
|
bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str, bool zoneGuard = false);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user