summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Generating/BioGen.cpp148
-rw-r--r--src/VoronoiMap.cpp91
-rw-r--r--src/VoronoiMap.h13
3 files changed, 164 insertions, 88 deletions
diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp
index 60ad4e3eb..217ca8f80 100644
--- a/src/Generating/BioGen.cpp
+++ b/src/Generating/BioGen.cpp
@@ -13,72 +13,6 @@
////////////////////////////////////////////////////////////////////////////////
-// cBiomeGen:
-
-cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault)
-{
- AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
- if (BiomeGenName.empty())
- {
- LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
- BiomeGenName = "MultiStepMap";
- }
-
- cBiomeGen * res = NULL;
- a_CacheOffByDefault = false;
- if (NoCaseCompare(BiomeGenName, "constant") == 0)
- {
- res = new cBioGenConstant;
- a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :)
- }
- else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
- {
- res = new cBioGenCheckerboard;
- a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data
- }
- else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
- {
- res = new cBioGenVoronoi(a_Seed);
- }
- else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0)
- {
- res = new cBioGenDistortedVoronoi(a_Seed);
- }
- else if (NoCaseCompare(BiomeGenName, "twolevel") == 0)
- {
- res = new cBioGenTwoLevel(a_Seed);
- }
- else
- {
- if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
- {
- LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
- }
- res = new cBioGenMultiStepMap(a_Seed);
-
- /*
- // Performance-testing:
- LOGINFO("Measuring performance of cBioGenMultiStepMap...");
- clock_t BeginTick = clock();
- for (int x = 0; x < 5000; x++)
- {
- cChunkDef::BiomeMap Biomes;
- res->GenBiomes(x * 5, x * 5, Biomes);
- }
- clock_t Duration = clock() - BeginTick;
- LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
- //*/
- }
- res->InitializeBiomeGen(a_IniFile);
-
- return res;
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
// cBioGenConstant:
void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
@@ -402,8 +336,13 @@ void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap &
void cBioGenVoronoi::InitializeBiomeGen(cIniFile & a_IniFile)
{
super::InitializeBiomeGen(a_IniFile);
- m_Voronoi.SetCellSize(a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64));
- InitializeBiomes (a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""));
+ int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 128);
+ int JitterSize = a_IniFile.GetValueSetI("Generator", "VoronoiJitterSize", CellSize);
+ int OddRowOffset = a_IniFile.GetValueSetI("Generator", "VoronoiOddRowOffset", 0);
+ m_Voronoi.SetCellSize(CellSize);
+ m_Voronoi.SetJitterSize(JitterSize);
+ m_Voronoi.SetOddRowOffset(OddRowOffset);
+ InitializeBiomes(a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""));
}
@@ -846,9 +785,10 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
{
for (int x = 0; x < cChunkDef::Width; x++)
{
- int MinDist1, MinDist2;
- int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 7;
- int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11;
+ int SeedX, SeedZ, MinDist2;
+ int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 7;
+ int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 11;
+ int MinDist1 = (DistortX[x][z] - SeedX) * (DistortX[x][z] - SeedX) + (DistortZ[x][z] - SeedZ) * (DistortZ[x][z] - SeedZ);
cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1));
}
}
@@ -987,3 +927,69 @@ void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile)
+
+////////////////////////////////////////////////////////////////////////////////
+// cBiomeGen:
+
+cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault)
+{
+ AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
+ if (BiomeGenName.empty())
+ {
+ LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
+ BiomeGenName = "MultiStepMap";
+ }
+
+ cBiomeGen * res = NULL;
+ a_CacheOffByDefault = false;
+ if (NoCaseCompare(BiomeGenName, "constant") == 0)
+ {
+ res = new cBioGenConstant;
+ a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :)
+ }
+ else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
+ {
+ res = new cBioGenCheckerboard;
+ a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data
+ }
+ else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
+ {
+ res = new cBioGenVoronoi(a_Seed);
+ }
+ else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0)
+ {
+ res = new cBioGenDistortedVoronoi(a_Seed);
+ }
+ else if (NoCaseCompare(BiomeGenName, "twolevel") == 0)
+ {
+ res = new cBioGenTwoLevel(a_Seed);
+ }
+ else
+ {
+ if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
+ {
+ LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
+ }
+ res = new cBioGenMultiStepMap(a_Seed);
+
+ /*
+ // Performance-testing:
+ LOGINFO("Measuring performance of cBioGenMultiStepMap...");
+ clock_t BeginTick = clock();
+ for (int x = 0; x < 5000; x++)
+ {
+ cChunkDef::BiomeMap Biomes;
+ res->GenBiomes(x * 5, x * 5, Biomes);
+ }
+ clock_t Duration = clock() - BeginTick;
+ LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
+ //*/
+ }
+ res->InitializeBiomeGen(a_IniFile);
+
+ return res;
+}
+
+
+
+
diff --git a/src/VoronoiMap.cpp b/src/VoronoiMap.cpp
index 68147ebfc..5ad634fe4 100644
--- a/src/VoronoiMap.cpp
+++ b/src/VoronoiMap.cpp
@@ -59,8 +59,8 @@ void cVoronoiMap::SetOddRowOffset(int a_OddRowOffset)
int cVoronoiMap::GetValueAt(int a_X, int a_Y)
{
- int MinDist1, MinDist2;
- return GetValueAt(a_X, a_Y, MinDist1, MinDist2);
+ int SeedX, SeedY, MinDist2;
+ return GetValueAt(a_X, a_Y, SeedX, SeedY, MinDist2);
}
@@ -69,41 +69,47 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y)
int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist)
{
- int MinDist2;
- return GetValueAt(a_X, a_Y, a_MinDist, MinDist2);
+ int SeedX, SeedY, MinDist2;
+ int res = GetValueAt(a_X, a_Y, SeedX, SeedY, MinDist2);
+ a_MinDist = (a_X - SeedX) * (a_X - SeedX) + (a_Y - SeedY) * (a_Y - SeedY);
+ return res;
}
-int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2)
+int cVoronoiMap::GetValueAt(
+ int a_X, int a_Y, // Coords to query
+ int & a_NearestSeedX, int & a_NearestSeedY, // Coords of the closest cell
+ int & a_MinDist2 // Distance to the second closest cell
+)
{
- // Note that due to historical reasons, the algorithm uses XZ coords, while the input uses XY coords.
- // This is because the algorithm was first implemented directly in the biome generators which use MC coords.
-
int CellX = a_X / m_CellSize;
- int CellZ = a_Y / m_CellSize;
+ int CellY = a_Y / m_CellSize;
- UpdateCell(CellX, CellZ);
+ UpdateCell(CellX, CellY);
// Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell
+ int NearestSeedX = 0, NearestSeedY = 0;
int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this
int MinDist2 = MinDist;
int res = 0; // Will be overriden
for (int x = 0; x < 5; x++)
{
- for (int z = 0; z < 5; z++)
+ for (int y = 0; y < 5; y++)
{
- int SeedX = m_SeedX[x][z];
- int SeedZ = m_SeedZ[x][z];
+ int SeedX = m_SeedX[x][y];
+ int SeedY = m_SeedZ[x][y];
- int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedZ - a_Y) * (SeedZ - a_Y);
+ int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedY - a_Y) * (SeedY - a_Y);
if (Dist < MinDist)
{
+ NearestSeedX = SeedX;
+ NearestSeedY = SeedY;
MinDist2 = MinDist;
MinDist = Dist;
- res = m_Noise3.IntNoise2DInt(x + CellX - 2, z + CellZ - 2);
+ res = m_Noise3.IntNoise2DInt(x + CellX - 2, y + CellY - 2);
}
else if (Dist < MinDist2)
{
@@ -112,7 +118,8 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
} // for z
} // for x
- a_MinDist1 = MinDist;
+ a_NearestSeedX = NearestSeedX;
+ a_NearestSeedY = NearestSeedY;
a_MinDist2 = MinDist2;
return res;
}
@@ -121,6 +128,58 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
+void cVoronoiMap::FindNearestSeeds(
+ int a_X, int a_Y,
+ int & a_NearestSeedX, int & a_NearestSeedY,
+ int & a_SecondNearestSeedX, int & a_SecondNearestSeedY
+)
+{
+ int CellX = a_X / m_CellSize;
+ int CellY = a_Y / m_CellSize;
+
+ UpdateCell(CellX, CellY);
+
+ // Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell
+ int NearestSeedX = 0, NearestSeedY = 0;
+ int SecondNearestSeedX = 0, SecondNearestSeedY = 0;
+ int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this
+ int MinDist2 = MinDist;
+ for (int x = 0; x < 5; x++)
+ {
+ for (int y = 0; y < 5; y++)
+ {
+ int SeedX = m_SeedX[x][y];
+ int SeedY = m_SeedZ[x][y];
+
+ int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedY - a_Y) * (SeedY - a_Y);
+ if (Dist < MinDist)
+ {
+ SecondNearestSeedX = NearestSeedX;
+ SecondNearestSeedY = NearestSeedY;
+ MinDist2 = MinDist;
+ NearestSeedX = SeedX;
+ NearestSeedY = SeedY;
+ MinDist = Dist;
+ }
+ else if (Dist < MinDist2)
+ {
+ SecondNearestSeedX = SeedX;
+ SecondNearestSeedY = SeedY;
+ MinDist2 = Dist;
+ }
+ } // for z
+ } // for x
+
+ a_NearestSeedX = NearestSeedX;
+ a_NearestSeedY = NearestSeedY;
+ a_SecondNearestSeedX = SecondNearestSeedX;
+ a_SecondNearestSeedY = SecondNearestSeedY;
+}
+
+
+
+
+
void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ)
{
// If the specified cell is currently cached, bail out:
diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h
index 49f6c1da1..dfb11e9ce 100644
--- a/src/VoronoiMap.h
+++ b/src/VoronoiMap.h
@@ -40,7 +40,18 @@ public:
/** Returns the value in the cell into which the specified point lies,
and the distances to the 2 nearest Voronoi seeds. Uses a cache. */
- int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2);
+ int GetValueAt(
+ int a_X, int a_Y, // Coords to query
+ int & a_NearestSeedX, int & a_NearestSeedY, // Coords of the closest cell's seed
+ int & a_MinDist2 // Distance to the second closest cell's seed
+ );
+
+ /** Finds the nearest and second nearest seeds, returns their coords. */
+ void FindNearestSeeds(
+ int a_X, int a_Y,
+ int & a_NearestSeedX, int & a_NearestSeedY,
+ int & a_SecondNearestSeedX, int & a_SecondNearestSeedY
+ );
protected:
/// The noise used for generating Voronoi seeds