mirror of
https://github.com/Kbz-8/42_vox.git
synced 2026-01-11 14:43:34 +00:00
Better biome generation w/ temperature & humidity
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#include "Biome.h"
|
#include "Biome.h"
|
||||||
#include "Block.h"
|
#include "Block.h"
|
||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
|
#include "NoiseCollection.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
Biome::Biome(std::uint32_t filler, std::uint32_t water_level, std::map<std::uint32_t, std::pair<BlockPlacementType, std::vector<BlockType>>> blocks): filler(filler), water_level(water_level), c_blockmap(blocks)
|
Biome::Biome(std::uint32_t filler, std::uint32_t water_level, std::map<std::uint32_t, std::pair<BlockPlacementType, std::vector<BlockType>>> blocks): filler(filler), water_level(water_level), c_blockmap(blocks)
|
||||||
@@ -18,11 +19,14 @@ const std::array<std::uint32_t, CHUNK_SIZE.y> Biome::GetBiomeBlocks(const std::u
|
|||||||
{
|
{
|
||||||
std::array<std::uint32_t, CHUNK_SIZE.y> data;
|
std::array<std::uint32_t, CHUNK_SIZE.y> data;
|
||||||
|
|
||||||
auto it = c_blockmap.lower_bound(height);
|
std::memset(data.data(), static_cast<std::uint32_t>(BlockType::Air), data.size() * sizeof(std::uint32_t));
|
||||||
|
std::fill(data.begin(), data.begin() + ARTIFICIAL_ELEVATION, filler);
|
||||||
|
std::fill(data.begin() + ARTIFICIAL_ELEVATION, data.begin() + ARTIFICIAL_ELEVATION + water_level, static_cast<std::uint32_t>(BlockType::Water));
|
||||||
|
auto it = c_blockmap.lower_bound(height - ARTIFICIAL_ELEVATION);
|
||||||
|
|
||||||
if (it == c_blockmap.end())
|
if (it == c_blockmap.end())
|
||||||
Scop::FatalError("Biome declaration does not have a value for a certain generated height");
|
Scop::FatalError("Biome declaration does not have a value for a certain generated height");
|
||||||
for(std::uint32_t y = 0; y < std::min(height, CHUNK_SIZE.y); y++)
|
for(std::uint32_t y = ARTIFICIAL_ELEVATION; y < std::min(height, CHUNK_SIZE.y); y++)
|
||||||
{
|
{
|
||||||
if(y > std::min(height, CHUNK_SIZE.y) - 2)
|
if(y > std::min(height, CHUNK_SIZE.y) - 2)
|
||||||
{
|
{
|
||||||
@@ -31,7 +35,7 @@ const std::array<std::uint32_t, CHUNK_SIZE.y> Biome::GetBiomeBlocks(const std::u
|
|||||||
{
|
{
|
||||||
case(static_cast<std::uint8_t>(BlockPlacementType::Simple)):
|
case(static_cast<std::uint8_t>(BlockPlacementType::Simple)):
|
||||||
{
|
{
|
||||||
data[y] = static_cast<std::uint32_t>(blockTypes.front());
|
data[y] = static_cast<std::uint32_t>(blockTypes.at(0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(static_cast<std::uint8_t>(BlockPlacementType::PseudoRandom)):
|
case(static_cast<std::uint8_t>(BlockPlacementType::PseudoRandom)):
|
||||||
@@ -44,7 +48,7 @@ const std::array<std::uint32_t, CHUNK_SIZE.y> Biome::GetBiomeBlocks(const std::u
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Stone);
|
data[y] = static_cast<std::uint32_t>(BlockType::Stone); // fallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -52,10 +56,5 @@ const std::array<std::uint32_t, CHUNK_SIZE.y> Biome::GetBiomeBlocks(const std::u
|
|||||||
data[y] = filler;
|
data[y] = filler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(std::uint32_t y = 0; y < water_level; y++)
|
|
||||||
{
|
|
||||||
if(data[y] == static_cast<std::uint32_t>(BlockType::Air))
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Water);
|
|
||||||
}
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Biome.h"
|
#include "Biome.h"
|
||||||
|
#include "Block.h"
|
||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
#include "Maths/Vec2.h"
|
#include "Maths/Vec2.h"
|
||||||
|
|
||||||
@@ -16,10 +17,30 @@ class BiomeCollection
|
|||||||
{
|
{
|
||||||
m_collection.emplace("grassland", std::make_unique<Biome>(
|
m_collection.emplace("grassland", std::make_unique<Biome>(
|
||||||
static_cast<std::uint32_t>(BlockType::Stone),
|
static_cast<std::uint32_t>(BlockType::Stone),
|
||||||
0,
|
20,
|
||||||
{
|
std::map<std::uint32_t, std::pair<BlockPlacementType, std::vector<BlockType>>>{
|
||||||
{20, {BlockPlacementType::Simple, {BlockType::Sand}}},
|
{23, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::Simple, std::vector<BlockType>{BlockType::Sand}}},
|
||||||
{255, {BlockPlacementType::Simple, {BlockType::Snow}}}
|
{125, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::Simple, std::vector<BlockType>{BlockType::Grass}}},
|
||||||
|
{132, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::PseudoRandom, std::vector<BlockType>{BlockType::SnowyGrass, BlockType::Grass}}},
|
||||||
|
{140, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::PseudoRandom, std::vector<BlockType>{BlockType::Snow, BlockType::SnowyGrass}}},
|
||||||
|
{255, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::Simple, std::vector<BlockType>{BlockType::Snow}}}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
m_collection.emplace("tundra", std::make_unique<Biome>(
|
||||||
|
static_cast<std::uint32_t>(BlockType::Stone),
|
||||||
|
20,
|
||||||
|
std::map<std::uint32_t, std::pair<BlockPlacementType, std::vector<BlockType>>>{
|
||||||
|
{23, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::Simple, std::vector<BlockType>{BlockType::Snow}}},
|
||||||
|
{120, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::Simple, std::vector<BlockType>{BlockType::SnowyGrass}}},
|
||||||
|
{140, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::PseudoRandom, std::vector<BlockType>{BlockType::Snow, BlockType::SnowyGrass}}},
|
||||||
|
{255, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::Simple, std::vector<BlockType>{BlockType::Snow}}}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
m_collection.emplace("desert", std::make_unique<Biome>(
|
||||||
|
static_cast<std::uint32_t>(BlockType::Stone),
|
||||||
|
20,
|
||||||
|
std::map<std::uint32_t, std::pair<BlockPlacementType, std::vector<BlockType>>>{
|
||||||
|
{255, std::pair<BlockPlacementType, std::vector<BlockType>>{BlockPlacementType::Simple, std::vector<BlockType>{BlockType::Sand}}}
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,50 +20,14 @@ const std::array<std::uint32_t, CHUNK_SIZE.y> NoiseCollection::GetBlocks(Scop::V
|
|||||||
{
|
{
|
||||||
const std::uint32_t height = m_collection["terrain"]->Perlin2D(pos.x, pos.y) + ARTIFICIAL_ELEVATION;
|
const std::uint32_t height = m_collection["terrain"]->Perlin2D(pos.x, pos.y) + ARTIFICIAL_ELEVATION;
|
||||||
std::array<std::uint32_t, CHUNK_SIZE.y> data;
|
std::array<std::uint32_t, CHUNK_SIZE.y> data;
|
||||||
|
|
||||||
std::memset(data.data(), static_cast<std::uint32_t>(BlockType::Air), data.size() * sizeof(std::uint32_t));
|
|
||||||
|
|
||||||
data = c_biomecollection.GetBiomeBlocks("grassland", height, pos);
|
|
||||||
return data;
|
|
||||||
for(std::uint32_t y = 0; y < std::min(height, CHUNK_SIZE.y); y++)
|
|
||||||
{
|
|
||||||
// const std::uint32_t value = Perlin3D(pos.x, y, pos.y);
|
|
||||||
if(y > std::min(height, CHUNK_SIZE.y) - 2)
|
|
||||||
{
|
|
||||||
if(height <= 23 + ARTIFICIAL_ELEVATION)
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Sand);
|
|
||||||
else if(height < 125 + ARTIFICIAL_ELEVATION)
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Grass);
|
|
||||||
else if (height < 132 + ARTIFICIAL_ELEVATION)
|
|
||||||
{
|
|
||||||
float weight = sin(2 * (pos.x * pos.y)) + sin(Scop::Pi<float>() * (pos.x * pos.y));
|
|
||||||
if (weight > 0.0f)
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Grass);
|
|
||||||
else
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::SnowyGrass);
|
|
||||||
}
|
|
||||||
else if (height < 140 + ARTIFICIAL_ELEVATION)
|
|
||||||
{
|
|
||||||
float weight = sin(2 * (pos.x * pos.y)) + sin(Scop::Pi<float>() * (pos.x * pos.y));
|
|
||||||
if (weight > 0.0f)
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Snow);
|
|
||||||
else
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::SnowyGrass);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Snow);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Stone);
|
|
||||||
}
|
|
||||||
for(std::uint32_t y = 0; y < ARTIFICIAL_ELEVATION + WATER_LEVEL; y++)
|
|
||||||
{
|
|
||||||
if(data[y] == static_cast<std::uint32_t>(BlockType::Air))
|
|
||||||
data[y] = static_cast<std::uint32_t>(BlockType::Water);
|
|
||||||
}
|
|
||||||
const std::uint32_t biome_value = m_collection["biomes"]->Perlin2D(pos.x, pos.y);
|
const std::uint32_t biome_value = m_collection["biomes"]->Perlin2D(pos.x, pos.y);
|
||||||
|
const std::uint32_t temperature = m_collection["temperature"]->Perlin2D(pos.x, pos.y);
|
||||||
if (biome_value > 20)
|
const std::uint32_t humidity = m_collection["humidity"]->Perlin2D(pos.x, pos.y);
|
||||||
data[240] = static_cast<std::uint32_t>(BlockType::Stone);
|
if (temperature < 85 && humidity <= 110)
|
||||||
return data;
|
return c_biomecollection.GetBiomeBlocks("tundra", height, pos);
|
||||||
|
if (temperature >= 85 && temperature <= 145 && humidity >= 85)
|
||||||
|
return c_biomecollection.GetBiomeBlocks("grassland", height, pos);
|
||||||
|
if (temperature >= 145)
|
||||||
|
return c_biomecollection.GetBiomeBlocks("desert", height, pos);
|
||||||
|
return c_biomecollection.GetBiomeBlocks("grassland", height, pos);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,15 @@ class NoiseCollection
|
|||||||
4,
|
4,
|
||||||
1.2f
|
1.2f
|
||||||
));
|
));
|
||||||
|
m_collection.emplace("humidity", std::make_unique<Noise>(seed, // seed
|
||||||
|
0.02f,
|
||||||
|
0.3f,
|
||||||
|
1,
|
||||||
|
2.0f,
|
||||||
|
0.6f,
|
||||||
|
2,
|
||||||
|
1.0f
|
||||||
|
));
|
||||||
m_collection.emplace("caves", std::make_unique<Noise>(seed,
|
m_collection.emplace("caves", std::make_unique<Noise>(seed,
|
||||||
0.02f,
|
0.02f,
|
||||||
1.0f,
|
1.0f,
|
||||||
@@ -34,15 +43,24 @@ class NoiseCollection
|
|||||||
3,
|
3,
|
||||||
1.0f
|
1.0f
|
||||||
)); // TODO !!!!!!
|
)); // TODO !!!!!!
|
||||||
m_collection.emplace("biomes", std::make_unique<Noise>(seed,
|
m_collection.emplace("biomes", std::make_unique<Noise>(seed + 1,
|
||||||
0.05f,
|
0.05f,
|
||||||
1.0f,
|
0.1f,
|
||||||
1,
|
1,
|
||||||
2.0f,
|
2.0f,
|
||||||
0.5f,
|
0.5f,
|
||||||
1,
|
1,
|
||||||
1.0f
|
1.0f
|
||||||
));
|
));
|
||||||
|
m_collection.emplace("temperature", std::make_unique<Noise>(seed + 1,
|
||||||
|
0.02f,
|
||||||
|
0.3f,
|
||||||
|
2,
|
||||||
|
2.0f,
|
||||||
|
0.55f,
|
||||||
|
2,
|
||||||
|
1.05f
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Noise* GetNoise(const std::string& key) const;
|
Noise* GetNoise(const std::string& key) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user