add biome-bpd and heights-bpd generator def parameters

This commit is contained in:
MihailRis 2024-09-29 23:12:45 +03:00
parent 6c2d10e14b
commit abc8eccab8
6 changed files with 74 additions and 43 deletions

View File

@ -11,7 +11,7 @@ function place_structures(x, z, w, d, seed, hmap)
return placements
end
local function _generate_heightmap(x, y, w, h, seed, s)
function generate_heightmap(x, y, w, h, seed, s)
local umap = Heightmap(w, h)
local vmap = Heightmap(w, h)
umap.noiseSeed = seed
@ -37,18 +37,7 @@ local function _generate_heightmap(x, y, w, h, seed, s)
return map
end
function generate_heightmap(x, y, w, h, seed)
-- blocks per dot
local bpd = 4
local map = _generate_heightmap(
math.floor(x/bpd), math.floor(y/bpd),
math.floor(w/bpd)+1, math.floor(h/bpd)+1, seed, bpd)
map:resize(w+bpd, h+bpd, 'linear')
map:crop(0, 0, w, h)
return map
end
local function _generate_biome_parameters(x, y, w, h, seed, s)
function generate_biome_parameters(x, y, w, h, seed, s)
local tempmap = Heightmap(w, h)
tempmap.noiseSeed = seed + 5324
tempmap:noise({x, y}, 0.04*s, 6)
@ -59,16 +48,3 @@ local function _generate_biome_parameters(x, y, w, h, seed, s)
hummap:pow(3)
return tempmap, hummap
end
function generate_biome_parameters(x, y, w, h, seed)
local bpd = 8
local tmap, hmap = _generate_biome_parameters(
math.floor(x/bpd), math.floor(y/bpd),
math.floor(w/bpd)+1, math.floor(h/bpd)+1, seed, bpd)
tmap:resize(w+bpd, h+bpd, 'linear')
tmap:crop(0, 0, w, h)
hmap:resize(w+bpd, h+bpd, 'linear')
hmap:crop(0, 0, w, h)
return tmap, hmap
end

View File

@ -127,13 +127,13 @@ static VoxelStructureMeta load_structure_meta(
return meta;
}
static std::vector<std::unique_ptr<GeneratingVoxelStructure>> load_structures(
static std::vector<std::unique_ptr<VoxelStructure>> load_structures(
const fs::path& structuresFile
) {
auto structuresDir = structuresFile.parent_path() / fs::path("fragments");
auto map = files::read_json(structuresFile);
std::vector<std::unique_ptr<GeneratingVoxelStructure>> structures;
std::vector<std::unique_ptr<VoxelStructure>> structures;
for (auto& [name, config] : map.asObject()) {
auto structFile = structuresDir / fs::u8path(name + ".vox");
logger.debug() << "loading voxel fragment " << structFile.u8string();
@ -144,7 +144,7 @@ static std::vector<std::unique_ptr<GeneratingVoxelStructure>> load_structures(
auto fragment = std::make_unique<VoxelFragment>();
fragment->deserialize(files::read_binary_json(structFile));
structures.push_back(std::make_unique<GeneratingVoxelStructure>(
structures.push_back(std::make_unique<VoxelStructure>(
load_structure_meta(name, config),
std::move(fragment)
));
@ -193,6 +193,8 @@ void ContentLoader::loadGenerator(
}
auto map = files::read_toml(generatorsDir / fs::u8path(name + ".toml"));
map.at("biome_parameters").get(def.biomeParameters);
map.at("biome-bpd").get(def.biomesBPD);
map.at("heights-bpd").get(def.heightsBPD);
map.at("sea_level").get(def.seaLevel);
auto folder = generatorsDir / fs::u8path(name + ".files");

View File

@ -26,7 +26,7 @@ public:
{}
std::shared_ptr<Heightmap> generateHeightmap(
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed, uint bpd
) override {
auto L = lua::get_main_thread();
lua::pushenv(L, *env);
@ -34,7 +34,8 @@ public:
lua::pushivec_stack(L, offset);
lua::pushivec_stack(L, size);
lua::pushinteger(L, seed);
if (lua::call_nothrow(L, 5)) {
lua::pushinteger(L, bpd);
if (lua::call_nothrow(L, 6)) {
auto map = lua::touserdata<lua::LuaHeightmap>(L, -1)->getHeightmap();
lua::pop(L, 2);
return map;
@ -45,7 +46,7 @@ public:
}
std::vector<std::shared_ptr<Heightmap>> generateParameterMaps(
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed, uint bpd
) override {
std::vector<std::shared_ptr<Heightmap>> maps;
@ -56,7 +57,8 @@ public:
lua::pushivec_stack(L, offset);
lua::pushivec_stack(L, size);
lua::pushinteger(L, seed);
if (lua::call_nothrow(L, 5, biomeParameters)) {
lua::pushinteger(L, bpd);
if (lua::call_nothrow(L, 6, biomeParameters)) {
for (int i = biomeParameters-1; i >= 0; i--) {
maps.push_back(
lua::touserdata<lua::LuaHeightmap>(L, -1-i)->getHeightmap());

View File

@ -5,7 +5,7 @@
#include "util/stringutil.hpp"
#include "voxels/Block.hpp"
GeneratingVoxelStructure::GeneratingVoxelStructure(
VoxelStructure::VoxelStructure(
VoxelStructureMeta meta,
std::unique_ptr<VoxelFragment> structure
) : fragments({std::move(structure)}), meta(std::move(meta)) {}

View File

@ -123,27 +123,51 @@ class GeneratorScript {
public:
virtual ~GeneratorScript() = default;
/// @brief Generates a heightmap with values in range 0..1
/// @brief Generate a heightmap with values in range 0..1
/// @param offset position of the heightmap in the world
/// @param size size of the heightmap
/// @param seed world seed
/// @return generated heightmap of given size (can't be nullptr)
/// @param bpd blocks per dot
/// @return generated heightmap (can't be nullptr)
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,
uint bpd
) = 0;
/// @brief Generate a biomes parameters maps
/// @param offset position of maps in the world
/// @param size maps size
/// @param seed world seed
/// @param bpd blocks per dot
/// @return generated maps (can't be nullptr)
virtual std::vector<std::shared_ptr<Heightmap>> generateParameterMaps(
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed) = 0;
const glm::ivec2& offset,
const glm::ivec2& size,
uint64_t seed,
uint bpd
) = 0;
/// @brief Generate a list of structures placements. Structures may be
/// placed to nearest chunks also (position of out area).
/// @param offset position of the area
/// @param size size of the area (blocks)
/// @param seed world seed
/// @param heightmap area heightmap
/// @return structure placements
virtual std::vector<StructurePlacement> placeStructures(
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed,
const std::shared_ptr<Heightmap>& heightmap) = 0;
};
struct GeneratingVoxelStructure {
/// @brief Structure voxel fragments and metadata
struct VoxelStructure {
VoxelStructureMeta meta;
/// @brief voxel fragment and 3 pre-calculated rotated versions
std::array<std::unique_ptr<VoxelFragment>, 4> fragments;
GeneratingVoxelStructure(
VoxelStructure(
VoxelStructureMeta meta,
std::unique_ptr<VoxelFragment> structure
);
@ -161,8 +185,14 @@ struct GeneratorDef {
/// @brief Number of biome parameters, that biome choosing depending on
uint biomeParameters = 0;
/// @brief Biome parameter map blocks per dot
uint biomesBPD = 8;
/// @brief Heightmap blocks per dot
uint heightsBPD = 4;
std::unordered_map<std::string, size_t> structuresIndices;
std::vector<std::unique_ptr<GeneratingVoxelStructure>> structures;
std::vector<std::unique_ptr<VoxelStructure>> structures;
std::vector<Biome> biomes;
GeneratorDef(std::string name);

View File

@ -10,6 +10,7 @@
#include "VoxelFragment.hpp"
#include "util/timeutil.hpp"
#include "util/listutil.hpp"
#include "maths/voxmaths.hpp"
#include "debug/Logger.hpp"
static debug::Logger logger("world-generator");
@ -229,8 +230,19 @@ void WorldGenerator::generateBiomes(
if (prototype.level >= ChunkPrototypeLevel::BIOMES) {
return;
}
uint bpd = def.biomesBPD;
auto biomeParams = def.script->generateParameterMaps(
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed);
{floordiv(chunkX * CHUNK_W, bpd), floordiv(chunkZ * CHUNK_D, bpd)},
{floordiv(CHUNK_W, bpd)+1, floordiv(CHUNK_D, bpd)+1},
seed,
bpd
);
for (const auto& map : biomeParams) {
map->resize(
CHUNK_W + bpd, CHUNK_D + bpd, InterpolationType::LINEAR
);
map->crop(0, 0, CHUNK_W, CHUNK_D);
}
const auto& biomes = def.biomes;
auto chunkBiomes = std::make_unique<const Biome*[]>(CHUNK_W*CHUNK_D);
@ -250,8 +262,17 @@ void WorldGenerator::generateHeightmap(
if (prototype.level >= ChunkPrototypeLevel::HEIGHTMAP) {
return;
}
uint bpd = def.heightsBPD;
prototype.heightmap = def.script->generateHeightmap(
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed);
{floordiv(chunkX * CHUNK_W, bpd), floordiv(chunkZ * CHUNK_D, bpd)},
{floordiv(CHUNK_W, bpd)+1, floordiv(CHUNK_D, bpd)+1},
seed,
bpd
);
prototype.heightmap->resize(
CHUNK_W + bpd, CHUNK_D + bpd, InterpolationType::LINEAR
);
prototype.heightmap->crop(0, 0, CHUNK_W, CHUNK_D);
prototype.level = ChunkPrototypeLevel::HEIGHTMAP;
}