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 return placements
end 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 umap = Heightmap(w, h)
local vmap = Heightmap(w, h) local vmap = Heightmap(w, h)
umap.noiseSeed = seed umap.noiseSeed = seed
@ -37,18 +37,7 @@ local function _generate_heightmap(x, y, w, h, seed, s)
return map return map
end end
function generate_heightmap(x, y, w, h, seed) function generate_biome_parameters(x, y, w, h, seed, s)
-- 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)
local tempmap = Heightmap(w, h) local tempmap = Heightmap(w, h)
tempmap.noiseSeed = seed + 5324 tempmap.noiseSeed = seed + 5324
tempmap:noise({x, y}, 0.04*s, 6) 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) hummap:pow(3)
return tempmap, hummap return tempmap, hummap
end 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; return meta;
} }
static std::vector<std::unique_ptr<GeneratingVoxelStructure>> load_structures( static std::vector<std::unique_ptr<VoxelStructure>> load_structures(
const fs::path& structuresFile const fs::path& structuresFile
) { ) {
auto structuresDir = structuresFile.parent_path() / fs::path("fragments"); auto structuresDir = structuresFile.parent_path() / fs::path("fragments");
auto map = files::read_json(structuresFile); 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()) { for (auto& [name, config] : map.asObject()) {
auto structFile = structuresDir / fs::u8path(name + ".vox"); auto structFile = structuresDir / fs::u8path(name + ".vox");
logger.debug() << "loading voxel fragment " << structFile.u8string(); 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>(); auto fragment = std::make_unique<VoxelFragment>();
fragment->deserialize(files::read_binary_json(structFile)); 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), load_structure_meta(name, config),
std::move(fragment) std::move(fragment)
)); ));
@ -193,6 +193,8 @@ void ContentLoader::loadGenerator(
} }
auto map = files::read_toml(generatorsDir / fs::u8path(name + ".toml")); auto map = files::read_toml(generatorsDir / fs::u8path(name + ".toml"));
map.at("biome_parameters").get(def.biomeParameters); 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); map.at("sea_level").get(def.seaLevel);
auto folder = generatorsDir / fs::u8path(name + ".files"); auto folder = generatorsDir / fs::u8path(name + ".files");

View File

@ -26,7 +26,7 @@ public:
{} {}
std::shared_ptr<Heightmap> generateHeightmap( 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 { ) override {
auto L = lua::get_main_thread(); auto L = lua::get_main_thread();
lua::pushenv(L, *env); lua::pushenv(L, *env);
@ -34,7 +34,8 @@ public:
lua::pushivec_stack(L, offset); lua::pushivec_stack(L, offset);
lua::pushivec_stack(L, size); lua::pushivec_stack(L, size);
lua::pushinteger(L, seed); 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(); auto map = lua::touserdata<lua::LuaHeightmap>(L, -1)->getHeightmap();
lua::pop(L, 2); lua::pop(L, 2);
return map; return map;
@ -45,7 +46,7 @@ public:
} }
std::vector<std::shared_ptr<Heightmap>> generateParameterMaps( 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 { ) override {
std::vector<std::shared_ptr<Heightmap>> maps; std::vector<std::shared_ptr<Heightmap>> maps;
@ -56,7 +57,8 @@ public:
lua::pushivec_stack(L, offset); lua::pushivec_stack(L, offset);
lua::pushivec_stack(L, size); lua::pushivec_stack(L, size);
lua::pushinteger(L, seed); 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--) { for (int i = biomeParameters-1; i >= 0; i--) {
maps.push_back( maps.push_back(
lua::touserdata<lua::LuaHeightmap>(L, -1-i)->getHeightmap()); lua::touserdata<lua::LuaHeightmap>(L, -1-i)->getHeightmap());

View File

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

View File

@ -123,27 +123,51 @@ class GeneratorScript {
public: public:
virtual ~GeneratorScript() = default; 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 offset position of the heightmap in the world
/// @param size size of the heightmap /// @param size size of the heightmap
/// @param seed world seed /// @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( 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( 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( virtual std::vector<StructurePlacement> placeStructures(
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed, const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed,
const std::shared_ptr<Heightmap>& heightmap) = 0; const std::shared_ptr<Heightmap>& heightmap) = 0;
}; };
struct GeneratingVoxelStructure { /// @brief Structure voxel fragments and metadata
struct VoxelStructure {
VoxelStructureMeta meta; VoxelStructureMeta meta;
/// @brief voxel fragment and 3 pre-calculated rotated versions
std::array<std::unique_ptr<VoxelFragment>, 4> fragments; std::array<std::unique_ptr<VoxelFragment>, 4> fragments;
GeneratingVoxelStructure( VoxelStructure(
VoxelStructureMeta meta, VoxelStructureMeta meta,
std::unique_ptr<VoxelFragment> structure std::unique_ptr<VoxelFragment> structure
); );
@ -161,8 +185,14 @@ struct GeneratorDef {
/// @brief Number of biome parameters, that biome choosing depending on /// @brief Number of biome parameters, that biome choosing depending on
uint biomeParameters = 0; 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::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; std::vector<Biome> biomes;
GeneratorDef(std::string name); GeneratorDef(std::string name);

View File

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