diff options
Diffstat (limited to 'src/Generating/StructGen.cpp')
-rw-r--r-- | src/Generating/StructGen.cpp | 198 |
1 files changed, 105 insertions, 93 deletions
diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 2b497e9a5..3e6a70996 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -37,12 +37,13 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) Dest = &WorkerDesc; WorkerDesc.SetChunkCoords({BaseX, BaseZ}); - // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single (cChunkDesc) cache + // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single + // (cChunkDesc) cache cChunkDesc::Shape workerShape; - m_BiomeGen.GenBiomes ({BaseX, BaseZ}, WorkerDesc.GetBiomeMap()); - m_ShapeGen.GenShape ({BaseX, BaseZ}, workerShape); - WorkerDesc.SetHeightFromShape (workerShape); + m_BiomeGen.GenBiomes({BaseX, BaseZ}, WorkerDesc.GetBiomeMap()); + m_ShapeGen.GenShape({BaseX, BaseZ}, workerShape); + WorkerDesc.SetHeightFromShape(workerShape); m_CompositionGen.ComposeTerrain(WorkerDesc, workerShape); } else @@ -60,7 +61,9 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) Pos.z = (m_Noise.IntNoise3DInt(BaseX - BaseZ, 0, BaseZ) / 19) % cChunkDef::Width; Pos.y = Dest->GetHeight(Pos.x, Pos.z); - if (std::abs(m_Noise.IntNoise3D(BaseX * cChunkDef::Width + Pos.x, Pos.y, BaseZ * cChunkDef::Width + Pos.z)) <= NumTrees) + if (std::abs( + m_Noise.IntNoise3D(BaseX * cChunkDef::Width + Pos.x, Pos.y, BaseZ * cChunkDef::Width + Pos.z) + ) <= NumTrees) { GenerateSingleTree(BaseX, BaseZ, 0, Pos, *Dest, OutsideLogs, OutsideOther); } @@ -94,7 +97,9 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) void cStructGenTrees::GenerateSingleTree( - int a_ChunkX, int a_ChunkZ, int a_Seq, + int a_ChunkX, + int a_ChunkZ, + int a_Seq, Vector3i a_Pos, cChunkDesc & a_ChunkDesc, sSetBlockVector & a_OutsideLogs, @@ -108,17 +113,20 @@ void cStructGenTrees::GenerateSingleTree( // Check the block underneath the tree: BLOCKTYPE TopBlock = a_ChunkDesc.GetBlockType(a_Pos.x, a_Pos.y, a_Pos.z); - if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND) && (TopBlock != E_BLOCK_MYCELIUM)) + if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND) && + (TopBlock != E_BLOCK_MYCELIUM)) { return; } sSetBlockVector TreeLogs, TreeOther; GetTreeImageByBiome( - { a_ChunkX * cChunkDef::Width + a_Pos.x, a_Pos.y + 1, a_ChunkZ * cChunkDef::Width + a_Pos.z }, - m_Noise, a_Seq, + {a_ChunkX * cChunkDef::Width + a_Pos.x, a_Pos.y + 1, a_ChunkZ * cChunkDef::Width + a_Pos.z}, + m_Noise, + a_Seq, a_ChunkDesc.GetBiome(a_Pos.x, a_Pos.z), - TreeLogs, TreeOther + TreeLogs, + TreeOther ); // Check if the generated image fits the terrain. Only the logs are checked: @@ -138,20 +146,20 @@ void cStructGenTrees::GenerateSingleTree( BLOCKTYPE Block = a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY, itr->m_RelZ); switch (Block) { - CASE_TREE_ALLOWED_BLOCKS: - { - break; - } - default: - { - // There's something in the way, abort this tree altogether - return; - } + CASE_TREE_ALLOWED_BLOCKS: + { + break; + } + default: + { + // There's something in the way, abort this tree altogether + return; + } } } ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeOther, a_OutsideOther); - ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs); + ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs); } @@ -159,7 +167,8 @@ void cStructGenTrees::GenerateSingleTree( void cStructGenTrees::ApplyTreeImage( - int a_ChunkX, int a_ChunkZ, + int a_ChunkX, + int a_ChunkZ, cChunkDesc & a_ChunkDesc, const sSetBlockVector & a_Image, sSetBlockVector & a_Overflow @@ -186,12 +195,11 @@ void cStructGenTrees::ApplyTreeImage( } CASE_TREE_OVERWRITTEN_BLOCKS: { - a_ChunkDesc.SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); + a_ChunkDesc + .SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); // If grass is below our tree, turn it to dirt - if ( - (cBlockInfo::IsSolid(itr->m_BlockType)) && - (a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ) == E_BLOCK_GRASS) - ) + if ((cBlockInfo::IsSolid(itr->m_BlockType)) && + (a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ) == E_BLOCK_GRASS)) { a_ChunkDesc.SetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ, E_BLOCK_DIRT); } @@ -212,10 +220,7 @@ void cStructGenTrees::ApplyTreeImage( -double cStructGenTrees::GetNumTrees( - int a_ChunkX, int a_ChunkZ, - const cChunkDef::BiomeMap & a_Biomes -) +double cStructGenTrees::GetNumTrees(int a_ChunkX, int a_ChunkZ, const cChunkDef::BiomeMap & a_Biomes) { auto BiomeTrees = [](EMCSBiome a_Biome) { @@ -316,22 +321,23 @@ void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - for (int z = -1; z < 2; z++) for (int x = -1; x < 2; x++) - { - if (((m_Noise.IntNoise2DInt(ChunkX + x, ChunkZ + z) / 17) % 100) > m_Probability) + for (int z = -1; z < 2; z++) + for (int x = -1; x < 2; x++) { - continue; - } + if (((m_Noise.IntNoise2DInt(ChunkX + x, ChunkZ + z) / 17) % 100) > m_Probability) + { + continue; + } - cBlockArea Lake; - CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake); + cBlockArea Lake; + CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake); - int OfsX = Lake.GetOriginX() + x * cChunkDef::Width; - int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width; + int OfsX = Lake.GetOriginX() + x * cChunkDef::Width; + int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width; - // Merge the lake into the current data - a_ChunkDesc.WriteBlockArea(Lake, OfsX, Lake.GetOriginY(), OfsZ, cBlockArea::msLake); - } // for x, z - neighbor chunks + // Merge the lake into the current data + a_ChunkDesc.WriteBlockArea(Lake, OfsX, Lake.GetOriginY(), OfsZ, cBlockArea::msLake); + } // for x, z - neighbor chunks } @@ -343,13 +349,16 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH a_Lake.Create(16, 8, 16); a_Lake.Fill(cBlockArea::baTypes, E_BLOCK_SPONGE); // Sponge is the NOP blocktype for lake merging strategy - // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max height minus 6 + // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max + // height minus 6 int MinHeight = std::max(a_MaxLakeHeight - 6, 2); int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11; - // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range + // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide + // and subtract to get range int OffsetX = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8; Rnd >>= 12; - // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range + // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide + // and subtract to get range int OffsetZ = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8; Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 512, a_ChunkZ) / 13; // Random height [1 .. MinHeight] with preference to center heights @@ -399,13 +408,14 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH // Turn air in the bottom half into liquid: for (int y = 0; y < 4; y++) { - for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) - { - if (BlockTypes[x + z * 16 + y * 16 * 16] == E_BLOCK_AIR) + for (int z = 0; z < 16; z++) + for (int x = 0; x < 16; x++) { - BlockTypes[x + z * 16 + y * 16 * 16] = m_Fluid; - } - } // for z, x + if (BlockTypes[x + z * 16 + y * 16 * 16] == E_BLOCK_AIR) + { + BlockTypes[x + z * 16 + y * 16 * 16] = m_Fluid; + } + } // for z, x } // for y // TODO: Turn sponge next to lava into stone @@ -421,8 +431,7 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH // cStructGenDirectOverhangs: cStructGenDirectOverhangs::cStructGenDirectOverhangs(int a_Seed) : - m_Noise1(a_Seed), - m_Noise2(a_Seed + 1000) + m_Noise1(a_Seed), m_Noise2(a_Seed + 1000) { } @@ -443,9 +452,10 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) const int SEGMENT_HEIGHT = 8; const int INTERPOL_X = 16; // Must be a divisor of 16 const int INTERPOL_Z = 16; // Must be a divisor of 16 - // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly interpolated separately. - // Have two buffers, one for the lowest floor and one for the highest floor, so that Y-interpolation can be done between them - // Then swap the buffers and use the previously-top one as the current-bottom, without recalculating it. + // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly + // interpolated separately. Have two buffers, one for the lowest floor and one for the highest floor, so that + // Y-interpolation can be done between them Then swap the buffers and use the previously-top one as the + // current-bottom, without recalculating it. int FloorBuf1[17 * 17]; int FloorBuf2[17 * 17]; @@ -456,48 +466,50 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) int BaseY = 63; // Interpolate the lowest floor: - for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++) - { - FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] = - m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) * - m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) / - 256; - } // for x, z - FloorLo[] + for (int z = 0; z <= 16 / INTERPOL_Z; z++) + for (int x = 0; x <= 16 / INTERPOL_X; x++) + { + FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] = + m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) * + m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) / 256; + } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); // Interpolate segments: for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) { // First update the high floor: - for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++) - { - FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] = ( - m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) * - m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256 - ); - } // for x, z - FloorLo[] + for (int z = 0; z <= 16 / INTERPOL_Z; z++) + for (int x = 0; x <= 16 / INTERPOL_X; x++) + { + FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] = + (m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) * + m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / + 256); + } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); // Interpolate between FloorLo and FloorHi: - for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) - { - EMCSBiome biome = a_ChunkDesc.GetBiome(x, z); - - if ((biome == biExtremeHills) || (biome == biExtremeHillsEdge)) + for (int z = 0; z < 16; z++) + for (int x = 0; x < 16; x++) { - int Lo = FloorLo[x + 17 * z] / 256; - int Hi = FloorHi[x + 17 * z] / 256; - for (int y = 0; y < SEGMENT_HEIGHT; y++) + EMCSBiome biome = a_ChunkDesc.GetBiome(x, z); + + if ((biome == biExtremeHills) || (biome == biExtremeHillsEdge)) { - int Val = Lo + (Hi - Lo) * y / SEGMENT_HEIGHT; - if (Val < 0) + int Lo = FloorLo[x + 17 * z] / 256; + int Hi = FloorHi[x + 17 * z] / 256; + for (int y = 0; y < SEGMENT_HEIGHT; y++) { - a_ChunkDesc.SetBlockType(x, y + Segment, z, E_BLOCK_AIR); - } - } // for y - break; - } // if (biome) - } // for z, x + int Val = Lo + (Hi - Lo) * y / SEGMENT_HEIGHT; + if (Val < 0) + { + a_ChunkDesc.SetBlockType(x, y + Segment, z, E_BLOCK_AIR); + } + } // for y + break; + } // if (biome) + } // for z, x // Swap the floors: std::swap(FloorLo, FloorHi); @@ -537,10 +549,7 @@ bool cStructGenDirectOverhangs::HasWantedBiome(cChunkDesc & a_ChunkDesc) const // cStructGenDistortedMembraneOverhangs: cStructGenDistortedMembraneOverhangs::cStructGenDistortedMembraneOverhangs(int a_Seed) : - m_NoiseX(a_Seed + 1000), - m_NoiseY(a_Seed + 2000), - m_NoiseZ(a_Seed + 3000), - m_NoiseH(a_Seed + 4000) + m_NoiseX(a_Seed + 1000), m_NoiseY(a_Seed + 2000), m_NoiseZ(a_Seed + 3000), m_NoiseH(a_Seed + 4000) { } @@ -559,14 +568,17 @@ void cStructGenDistortedMembraneOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) BLOCKTYPE ReplacementBlock = (y > 62) ? E_BLOCK_AIR : E_BLOCK_STATIONARY_WATER; for (int z = 0; z < cChunkDef::Width; z++) { - NOISE_DATATYPE NoiseZ = static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + z) / Frequency; + NOISE_DATATYPE NoiseZ = + static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + z) / Frequency; for (int x = 0; x < cChunkDef::Width; x++) { - NOISE_DATATYPE NoiseX = static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + x) / Frequency; + NOISE_DATATYPE NoiseX = + static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + x) / Frequency; NOISE_DATATYPE DistortX = m_NoiseX.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount; NOISE_DATATYPE DistortY = m_NoiseY.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount; NOISE_DATATYPE DistortZ = m_NoiseZ.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount; - int MembraneHeight = 96 - static_cast<int>((DistortY + m_NoiseH.CubicNoise2D(NoiseX + DistortX, NoiseZ + DistortZ)) * 30); + int MembraneHeight = 96 - + static_cast<int>((DistortY + m_NoiseH.CubicNoise2D(NoiseX + DistortX, NoiseZ + DistortZ)) * 30); if (MembraneHeight < y) { a_ChunkDesc.SetBlockType(x, y, z, ReplacementBlock); |