From 5462f43baefdf839d7d2e5036d2ec3c95d888c02 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 24 Mar 2013 16:07:51 +0000 Subject: Fixed rounding error in MultiStepMap BioGen, introduced in rev 1289. git-svn-id: http://mc-server.googlecode.com/svn/trunk@1307 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Generating/BioGen.cpp | 29 +++++++++++++++++--------- source/Generating/BioGen.h | 7 ++++--- source/Noise.h | 48 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/source/Generating/BioGen.cpp b/source/Generating/BioGen.cpp index 40fa0de53..8e38dc19f 100644 --- a/source/Generating/BioGen.cpp +++ b/source/Generating/BioGen.cpp @@ -393,10 +393,10 @@ cBioGenMultiStepMap::cBioGenMultiStepMap(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed), m_OceanCellSize(384), - m_MushroomIslandSize(32), - m_RiverCellSize(128), - m_RiverWidthThreshold((float)0.05), - m_LandBiomesSize(192) + m_MushroomIslandSize(64), + m_RiverCellSize(384), + m_RiverWidthThreshold(0.125), + m_LandBiomesSize(1024) { } @@ -409,7 +409,7 @@ void cBioGenMultiStepMap::Initialize(cIniFile & a_IniFile) m_OceanCellSize = a_IniFile.GetValueSetI("Generator", "MultiStepMapOceanCellSize", m_OceanCellSize); m_MushroomIslandSize = a_IniFile.GetValueSetI("Generator", "MultiStepMapMushroomIslandSize", m_MushroomIslandSize); m_RiverCellSize = a_IniFile.GetValueSetI("Generator", "MultiStepMapRiverCellSize", m_RiverCellSize); - m_RiverWidthThreshold = (float)a_IniFile.GetValueSetF("Generator", "MultiStepMapRiverWidth", m_RiverWidthThreshold); + m_RiverWidthThreshold = a_IniFile.GetValueSetF("Generator", "MultiStepMapRiverWidth", m_RiverWidthThreshold); m_LandBiomesSize = (float)a_IniFile.GetValueSetI("Generator", "MultiStepMapLandBiomeSize", (int)m_LandBiomesSize); } @@ -595,7 +595,9 @@ void cBioGenMultiStepMap::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_ChunkZ, IntMap & a_TemperatureMap, IntMap & a_HumidityMap) { - // Linear interpolation over 8x8 blocks + // Linear interpolation over 8x8 blocks; use double for better precision: + DblMap TemperatureMap; + DblMap HumidityMap; for (int z = 0; z < 17; z += 8) { float NoiseCoordZ = (float)(a_ChunkZ * cChunkDef::Width + z) / m_LandBiomesSize; @@ -606,16 +608,23 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk double NoiseT = m_Noise.CubicNoise3D( NoiseCoordX, NoiseCoordZ, 7000); NoiseT += 0.5 * m_Noise.CubicNoise3D(2 * NoiseCoordX, 2 * NoiseCoordZ, 8000); NoiseT += 0.1 * m_Noise.CubicNoise3D(8 * NoiseCoordX, 8 * NoiseCoordZ, 9000); - a_TemperatureMap[x + 17 * z] = std::max(0, std::min(255, (int)(128 + NoiseT * 128))); + TemperatureMap[x + 17 * z] = NoiseT; double NoiseH = m_Noise.CubicNoise3D( NoiseCoordX, NoiseCoordZ, 9000); NoiseH += 0.5 * m_Noise.CubicNoise3D(2 * NoiseCoordX, 2 * NoiseCoordZ, 5000); NoiseH += 0.1 * m_Noise.CubicNoise3D(8 * NoiseCoordX, 8 * NoiseCoordZ, 1000); - a_HumidityMap[x + 17 * z] = std::max(0, std::min(255, (int)(128 + NoiseH * 128))); + HumidityMap[x + 17 * z] = NoiseH; } // for x } // for z - IntArrayLinearInterpolate2D(a_TemperatureMap, 17, 17, 8, 8); - IntArrayLinearInterpolate2D(a_HumidityMap, 17, 17, 8, 8); + ArrayLinearInterpolate2D(TemperatureMap, 17, 17, 8, 8); + ArrayLinearInterpolate2D(HumidityMap, 17, 17, 8, 8); + + // Re-map into integral values in [0 .. 255] range: + for (int idx = 0; idx < ARRAYCOUNT(a_TemperatureMap); idx++) + { + a_TemperatureMap[idx] = std::max(0, std::min(255, (int)(128 + TemperatureMap[idx] * 128))); + a_HumidityMap[idx] = std::max(0, std::min(255, (int)(128 + HumidityMap[idx] * 128))); + } } diff --git a/source/Generating/BioGen.h b/source/Generating/BioGen.h index 88ca3e438..ad3ff01a3 100644 --- a/source/Generating/BioGen.h +++ b/source/Generating/BioGen.h @@ -180,10 +180,11 @@ protected: int m_OceanCellSize; int m_MushroomIslandSize; int m_RiverCellSize; - float m_RiverWidthThreshold; - float m_LandBiomesSize; + double m_RiverWidthThreshold; + float m_LandBiomesSize; - typedef int IntMap[17 * 17]; // x + 17 * z, expected trimmed into [0..255] range + typedef int IntMap[17 * 17]; // x + 17 * z, expected trimmed into [0..255] range + typedef double DblMap[17 * 17]; // x + 17 * z, expected trimmed into [0..1] range // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; diff --git a/source/Noise.h b/source/Noise.h index 68428d33e..9a129d81f 100644 --- a/source/Noise.h +++ b/source/Noise.h @@ -85,6 +85,54 @@ extern void IntArrayLinearInterpolate2D( +/// Linearly interpolates values in the array between the anchor points; universal data type +template void ArrayLinearInterpolate2D( + TYPE * a_Array, + int a_SizeX, int a_SizeY, // Dimensions of the array + int a_AnchorStepX, int a_AnchorStepY // Distances between the anchor points in each direction +) +{ + // First interpolate columns where the anchor points are: + int LastYCell = a_SizeY - a_AnchorStepY; + for (int y = 0; y < LastYCell; y += a_AnchorStepY) + { + int Idx = a_SizeX * y; + for (int x = 0; x < a_SizeX; x += a_AnchorStepX) + { + TYPE StartValue = a_Array[Idx]; + TYPE EndValue = a_Array[Idx + a_SizeX * a_AnchorStepY]; + TYPE Diff = EndValue - StartValue; + for (int CellY = 1; CellY < a_AnchorStepY; CellY++) + { + a_Array[Idx + a_SizeX * CellY] = StartValue + Diff * CellY / a_AnchorStepY; + } // for CellY + Idx += a_AnchorStepX; + } // for x + } // for y + + // Now interpolate in rows, each row has values in the anchor columns + int LastXCell = a_SizeX - a_AnchorStepX; + for (int y = 0; y < a_SizeY; y++) + { + int Idx = a_SizeX * y; + for (int x = 0; x < LastXCell; x += a_AnchorStepX) + { + TYPE StartValue = a_Array[Idx]; + TYPE EndValue = a_Array[Idx + a_AnchorStepX]; + TYPE Diff = EndValue - StartValue; + for (int CellX = 1; CellX < a_AnchorStepX; CellX++) + { + a_Array[Idx + CellX] = StartValue + CellX * Diff / a_AnchorStepX; + } // for CellY + Idx += a_AnchorStepX; + } + } +} + + + + + #if NOISE_USE_INLINE #include "Noise.inc" #endif -- cgit v1.2.3