add test biomes
This commit is contained in:
parent
4bd5f1b629
commit
572eaec429
@ -19,6 +19,20 @@ biomes = {
|
|||||||
{block="base:stone", height=-1},
|
{block="base:stone", height=-1},
|
||||||
{block="base:bazalt", height=1},
|
{block="base:bazalt", height=1},
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
desert = {
|
||||||
|
parameters = {
|
||||||
|
{value=0.0, weight=1.0},
|
||||||
|
{value=0.5, weight=1.0},
|
||||||
|
},
|
||||||
|
sea_layers = {
|
||||||
|
{block="base:water", height=-1},
|
||||||
|
},
|
||||||
|
layers = {
|
||||||
|
{block="base:sand", height=6},
|
||||||
|
{block="base:stone", height=-1},
|
||||||
|
{block="base:bazalt", height=1},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,3 +79,10 @@ function generate_heightmap(x, y, w, h, seed)
|
|||||||
map:crop(0, 0, w, h)
|
map:crop(0, 0, w, h)
|
||||||
return map
|
return map
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function generate_biome_parameters(x, y, w, h, seed)
|
||||||
|
local tempmap = Heightmap(w, h)
|
||||||
|
tempmap:noise({x, y}, 0.4, 3)
|
||||||
|
local hummap = Heightmap(w, h)
|
||||||
|
return tempmap, hummap
|
||||||
|
end
|
||||||
|
|||||||
@ -9,6 +9,8 @@
|
|||||||
#include "voxels/Chunk.hpp"
|
#include "voxels/Chunk.hpp"
|
||||||
#include "world/generator/GeneratorDef.hpp"
|
#include "world/generator/GeneratorDef.hpp"
|
||||||
|
|
||||||
|
// TODO: use dynamic::* for parsing
|
||||||
|
|
||||||
class LuaGeneratorScript : public GeneratorScript {
|
class LuaGeneratorScript : public GeneratorScript {
|
||||||
scriptenv env;
|
scriptenv env;
|
||||||
std::vector<Biome> biomes;
|
std::vector<Biome> biomes;
|
||||||
@ -45,6 +47,34 @@ public:
|
|||||||
return std::make_shared<Heightmap>(size.x, size.y);
|
return std::make_shared<Heightmap>(size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Heightmap>> generateParameterMaps(
|
||||||
|
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed
|
||||||
|
) override {
|
||||||
|
std::vector<std::shared_ptr<Heightmap>> maps;
|
||||||
|
|
||||||
|
auto L = lua::get_main_thread();
|
||||||
|
lua::pushenv(L, *env);
|
||||||
|
if (lua::getfield(L, "generate_biome_parameters")) {
|
||||||
|
lua::pushivec_stack(L, offset);
|
||||||
|
lua::pushivec_stack(L, size);
|
||||||
|
lua::pushinteger(L, seed);
|
||||||
|
if (lua::call_nothrow(L, 5, biomeParameters)) {
|
||||||
|
for (int i = biomeParameters-1; i >= 0; i--) {
|
||||||
|
maps.push_back(
|
||||||
|
lua::touserdata<lua::LuaHeightmap>(L, -1-i)->getHeightmap());
|
||||||
|
|
||||||
|
}
|
||||||
|
lua::pop(L, 1+biomeParameters);
|
||||||
|
return maps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua::pop(L);
|
||||||
|
for (uint i = 0; i < biomeParameters; i++) {
|
||||||
|
maps.push_back(std::make_shared<Heightmap>(size.x, size.y));
|
||||||
|
}
|
||||||
|
return maps;
|
||||||
|
}
|
||||||
|
|
||||||
void prepare(const Content* content) override {
|
void prepare(const Content* content) override {
|
||||||
for (auto& biome : biomes) {
|
for (auto& biome : biomes) {
|
||||||
for (auto& layer : biome.groundLayers.layers) {
|
for (auto& layer : biome.groundLayers.layers) {
|
||||||
@ -118,7 +148,7 @@ static inline Biome load_biome(
|
|||||||
) {
|
) {
|
||||||
lua::pushvalue(L, idx);
|
lua::pushvalue(L, idx);
|
||||||
|
|
||||||
std::vector<BiomeParameter> parameters(parametersCount);
|
std::vector<BiomeParameter> parameters;
|
||||||
lua::requirefield(L, "parameters");
|
lua::requirefield(L, "parameters");
|
||||||
if (lua::objlen(L, -1) < parametersCount) {
|
if (lua::objlen(L, -1) < parametersCount) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
|
|||||||
@ -37,6 +37,14 @@ public:
|
|||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float get(uint x, uint y) {
|
||||||
|
return buffer.at(y * width + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
float getUnchecked(uint x, uint y) {
|
||||||
|
return buffer[y * width + x];
|
||||||
|
}
|
||||||
|
|
||||||
float* getValues() {
|
float* getValues() {
|
||||||
return buffer.data();
|
return buffer.data();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,6 +61,9 @@ public:
|
|||||||
virtual std::shared_ptr<Heightmap> generateHeightmap(
|
virtual std::shared_ptr<Heightmap> generateHeightmap(
|
||||||
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed) = 0;
|
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed) = 0;
|
||||||
|
|
||||||
|
virtual std::vector<std::shared_ptr<Heightmap>> generateParameterMaps(
|
||||||
|
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed) = 0;
|
||||||
|
|
||||||
virtual const std::vector<Biome>& getBiomes() const = 0;
|
virtual const std::vector<Biome>& getBiomes() const = 0;
|
||||||
|
|
||||||
/// @return Number of biome parameters, that biome choosing depending on
|
/// @return Number of biome parameters, that biome choosing depending on
|
||||||
|
|||||||
@ -9,6 +9,8 @@
|
|||||||
#include "voxels/voxel.hpp"
|
#include "voxels/voxel.hpp"
|
||||||
#include "world/generator/GeneratorDef.hpp"
|
#include "world/generator/GeneratorDef.hpp"
|
||||||
|
|
||||||
|
static inline constexpr uint MAX_PARAMETERS = 16;
|
||||||
|
|
||||||
WorldGenerator::WorldGenerator(const GeneratorDef& def, const Content* content)
|
WorldGenerator::WorldGenerator(const GeneratorDef& def, const Content* content)
|
||||||
: def(def), content(content) {
|
: def(def), content(content) {
|
||||||
}
|
}
|
||||||
@ -30,7 +32,6 @@ static inline void generate_pole(
|
|||||||
layerExtension = std::max(0, layer.height);
|
layerExtension = std::max(0, layer.height);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int layerHeight = layer.height;
|
int layerHeight = layer.height;
|
||||||
if (layerHeight == -1) {
|
if (layerHeight == -1) {
|
||||||
// resizeable layer
|
// resizeable layer
|
||||||
@ -47,6 +48,32 @@ static inline void generate_pole(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const Biome* choose_biome(
|
||||||
|
const std::vector<Biome>& biomes,
|
||||||
|
const std::vector<std::shared_ptr<Heightmap>>& maps,
|
||||||
|
uint x, uint z
|
||||||
|
) {
|
||||||
|
uint paramsCount = maps.size();
|
||||||
|
float params[MAX_PARAMETERS];
|
||||||
|
for (uint i = 0; i < paramsCount; i++) {
|
||||||
|
params[i] = maps[i]->getUnchecked(x, z);
|
||||||
|
}
|
||||||
|
const Biome* chosenBiome = nullptr;
|
||||||
|
float chosenScore = std::numeric_limits<float>::infinity();
|
||||||
|
for (const auto& biome : biomes) {
|
||||||
|
float score = 0.0f;
|
||||||
|
for (uint i = 0; i < paramsCount; i++) {
|
||||||
|
score += glm::abs((params[i] - biome.parameters[i].origin) /
|
||||||
|
biome.parameters[i].weight);
|
||||||
|
}
|
||||||
|
if (score < chosenScore) {
|
||||||
|
chosenScore = score;
|
||||||
|
chosenBiome = &biome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chosenBiome;
|
||||||
|
}
|
||||||
|
|
||||||
#include "util/timeutil.hpp"
|
#include "util/timeutil.hpp"
|
||||||
void WorldGenerator::generate(
|
void WorldGenerator::generate(
|
||||||
voxel* voxels, int chunkX, int chunkZ, uint64_t seed
|
voxel* voxels, int chunkX, int chunkZ, uint64_t seed
|
||||||
@ -55,11 +82,11 @@ void WorldGenerator::generate(
|
|||||||
auto heightmap = def.script->generateHeightmap(
|
auto heightmap = def.script->generateHeightmap(
|
||||||
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed
|
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed
|
||||||
);
|
);
|
||||||
|
auto biomeParams = def.script->generateParameterMaps(
|
||||||
|
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed
|
||||||
|
);
|
||||||
auto values = heightmap->getValues();
|
auto values = heightmap->getValues();
|
||||||
const auto& biomes = def.script->getBiomes();
|
const auto& biomes = def.script->getBiomes();
|
||||||
const auto& biome = biomes.at(0);
|
|
||||||
const auto& groundLayers = biome.groundLayers;
|
|
||||||
const auto& seaLayers = biome.seaLayers;
|
|
||||||
|
|
||||||
uint seaLevel = def.script->getSeaLevel();
|
uint seaLevel = def.script->getSeaLevel();
|
||||||
|
|
||||||
@ -67,9 +94,14 @@ void WorldGenerator::generate(
|
|||||||
|
|
||||||
for (uint z = 0; z < CHUNK_D; z++) {
|
for (uint z = 0; z < CHUNK_D; z++) {
|
||||||
for (uint x = 0; x < CHUNK_W; x++) {
|
for (uint x = 0; x < CHUNK_W; x++) {
|
||||||
|
const Biome* biome = choose_biome(biomes, biomeParams, x, z);
|
||||||
|
|
||||||
int height = values[z * CHUNK_W + x] * CHUNK_H;
|
int height = values[z * CHUNK_W + x] * CHUNK_H;
|
||||||
height = std::max(0, height);
|
height = std::max(0, height);
|
||||||
|
|
||||||
|
const auto& groundLayers = biome->groundLayers;
|
||||||
|
const auto& seaLayers = biome->seaLayers;
|
||||||
|
|
||||||
generate_pole(seaLayers, seaLevel, height, seaLevel, voxels, x, z);
|
generate_pole(seaLayers, seaLevel, height, seaLevel, voxels, x, z);
|
||||||
generate_pole(groundLayers, height, 0, seaLevel, voxels, x, z);
|
generate_pole(groundLayers, height, 0, seaLevel, voxels, x, z);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user