mirror of
https://github.com/vcmi/vcmi.git
synced 2025-05-23 22:40:07 +02:00
Final shape of algorithm
This commit is contained in:
parent
990e38e961
commit
0dbfee0edb
@ -42,7 +42,8 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
|||||||
{
|
{
|
||||||
//gravity-based algorithm
|
//gravity-based algorithm
|
||||||
|
|
||||||
float gravityConstant = 5e-3;
|
const float gravityConstant = 5e-3;
|
||||||
|
const float stiffnessConstant = 1e-3;
|
||||||
float zoneScale = 0.5f; //zones starts small and then inflate
|
float zoneScale = 0.5f; //zones starts small and then inflate
|
||||||
const float inflateModifier = 1.02;
|
const float inflateModifier = 1.02;
|
||||||
|
|
||||||
@ -69,6 +70,10 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
|||||||
bool undergroundFlag = false;
|
bool undergroundFlag = false;
|
||||||
|
|
||||||
std::vector<float> totalSize = { 0, 0 }; //make sure that sum of zone sizes on surface and uderground match size of the map
|
std::vector<float> totalSize = { 0, 0 }; //make sure that sum of zone sizes on surface and uderground match size of the map
|
||||||
|
|
||||||
|
const float radius = 0.4f;
|
||||||
|
const float pi2 = 6.28f;
|
||||||
|
|
||||||
for (auto zone : zonesVector)
|
for (auto zone : zonesVector)
|
||||||
{
|
{
|
||||||
//even distribution for surface / underground zones. Surface zones always have priority.
|
//even distribution for surface / underground zones. Surface zones always have priority.
|
||||||
@ -87,7 +92,8 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
|||||||
}
|
}
|
||||||
|
|
||||||
totalSize[level] += (zone.second->getSize() * zone.second->getSize());
|
totalSize[level] += (zone.second->getSize() * zone.second->getSize());
|
||||||
zone.second->setCenter (float3(rand->nextDouble(0.2, 0.8), rand->nextDouble(0.2, 0.8), level)); //start away from borders
|
float randomAngle = rand->nextDouble(0, pi2);
|
||||||
|
zone.second->setCenter(float3(0.5f + std::sin(randomAngle) * radius, 0.5f + std::cos(randomAngle) * radius, level)); //place zones around circle
|
||||||
}
|
}
|
||||||
//prescale zones
|
//prescale zones
|
||||||
std::vector<float> prescaler = { 0, 0 };
|
std::vector<float> prescaler = { 0, 0 };
|
||||||
@ -135,7 +141,7 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
|||||||
if (distance > minDistance)
|
if (distance > minDistance)
|
||||||
{
|
{
|
||||||
//WARNING: compiler used to 'optimize' that line so it never actually worked
|
//WARNING: compiler used to 'optimize' that line so it never actually worked
|
||||||
forceVector += (((otherZoneCenter - pos)*(pos.z == otherZoneCenter.z ? (minDistance/distance) : 1)/ getDistance(distance))); //positive value
|
forceVector += (((otherZoneCenter - pos)*(pos.z == otherZoneCenter.z ? (minDistance/distance) : 1)/ getDistance(distance))) * gravityConstant; //positive value
|
||||||
totalDistance += (distance - minDistance);
|
totalDistance += (distance - minDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +160,7 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
|||||||
float minDistance = (zone.second->getSize() + otherZone.second->getSize())/mapSize * zoneScale;
|
float minDistance = (zone.second->getSize() + otherZone.second->getSize())/mapSize * zoneScale;
|
||||||
if (distance < minDistance)
|
if (distance < minDistance)
|
||||||
{
|
{
|
||||||
forceVector -= (((otherZoneCenter - pos)*(minDistance/(distance ? distance : 1e-3))) / getDistance(distance)); //negative value
|
forceVector -= (((otherZoneCenter - pos)*(minDistance/(distance ? distance : 1e-3))) / getDistance(distance)) * stiffnessConstant; //negative value
|
||||||
totalOverlap += (minDistance - distance);
|
totalOverlap += (minDistance - distance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,11 +170,11 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
|||||||
//do not scale boundary distance - zones tend to get squashed
|
//do not scale boundary distance - zones tend to get squashed
|
||||||
float size = zone.second->getSize() / mapSize;
|
float size = zone.second->getSize() / mapSize;
|
||||||
|
|
||||||
auto pushAwayFromBoundary = [&forceVector, pos, &getDistance, size](float x, float y)
|
auto pushAwayFromBoundary = [&forceVector, pos, &getDistance, size, stiffnessConstant](float x, float y)
|
||||||
{
|
{
|
||||||
float3 boundary = float3 (x, y, pos.z);
|
float3 boundary = float3 (x, y, pos.z);
|
||||||
float distance = pos.dist2d(boundary);
|
float distance = pos.dist2d(boundary);
|
||||||
forceVector -= (boundary - pos) * (size - distance) / getDistance(distance); //negative value
|
forceVector -= (boundary - pos) * (size - distance) / getDistance(distance) * stiffnessConstant; //negative value
|
||||||
};
|
};
|
||||||
if (pos.x < size)
|
if (pos.x < size)
|
||||||
{
|
{
|
||||||
@ -186,9 +192,8 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
|||||||
{
|
{
|
||||||
pushAwayFromBoundary(pos.x, 1);
|
pushAwayFromBoundary(pos.x, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceVector.z = 0; //operator - doesn't preserve z coordinate :/
|
forceVector.z = 0; //operator - doesn't preserve z coordinate :/
|
||||||
forces[zone.second] = forceVector * gravityConstant;
|
forces[zone.second] = forceVector;
|
||||||
}
|
}
|
||||||
//update positions
|
//update positions
|
||||||
for (auto zone : forces)
|
for (auto zone : forces)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user