add SurroundMap intergration to world generator (WIP)

This commit is contained in:
MihailRis 2024-09-11 11:35:56 +03:00
parent 80d8a6738b
commit 8268176527
6 changed files with 76 additions and 10 deletions

View File

@ -99,14 +99,27 @@ function generate_heightmap(x, y, w, h, seed)
return map
end
function generate_biome_parameters(x, y, w, h, seed)
local function _generate_biome_parameters(x, y, w, h, seed, s)
local tempmap = Heightmap(w, h)
tempmap.noiseSeed = seed + 5324
tempmap:noise({x, y}, 0.4, 4)
tempmap:noise({x, y}, 0.4*s, 4)
local hummap = Heightmap(w, h)
hummap.noiseSeed = seed + 953
hummap:noise({x, y}, 0.16, 4)
hummap:noise({x, y}, 0.16*s, 4)
tempmap:pow(2)
hummap:pow(2)
return tempmap, hummap
end
function generate_biome_parameters(x, y, w, h, seed)
local bpd = 4
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

@ -35,7 +35,11 @@ ChunksController::ChunksController(Level* level, uint padding)
ChunksController::~ChunksController() = default;
void ChunksController::update(int64_t maxDuration) {
void ChunksController::update(
int64_t maxDuration, int loadDistance, int centerX, int centerY
) {
generator->update(centerX, centerY, loadDistance);
int64_t mcstotal = 0;
for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) {

View File

@ -28,5 +28,9 @@ public:
~ChunksController();
/// @param maxDuration milliseconds reserved for chunks loading
void update(int64_t maxDuration);
void update(
int64_t maxDuration,
int loadDistance,
int centerX,
int centerY);
};

View File

@ -10,6 +10,7 @@
#include "settings.hpp"
#include "world/Level.hpp"
#include "world/World.hpp"
#include "maths/voxmaths.hpp"
#include "scripting/scripting.hpp"
static debug::Logger logger("level-control");
@ -38,7 +39,10 @@ void LevelController::update(float delta, bool input, bool pause) {
position.z,
settings.chunks.loadDistance.get() + settings.chunks.padding.get() * 2
);
chunks->update(settings.chunks.loadSpeed.get());
chunks->update(
settings.chunks.loadSpeed.get(), settings.chunks.loadDistance.get(),
floordiv(position.x, CHUNK_W), floordiv(position.z, CHUNK_D)
);
if (!pause) {
// update all objects that needed

View File

@ -9,13 +9,35 @@
#include "voxels/Chunk.hpp"
#include "world/generator/GeneratorDef.hpp"
#include "util/timeutil.hpp"
#include "debug/Logger.hpp"
static debug::Logger logger("world-generator");
static inline constexpr uint MAX_PARAMETERS = 16;
static inline constexpr uint MAX_CHUNK_PROTOTYPE_LEVELS = 8;
WorldGenerator::WorldGenerator(
const GeneratorDef& def, const Content* content, uint64_t seed
)
: def(def), content(content), seed(seed) {
: def(def),
content(content),
seed(seed),
surroundMap(0, MAX_CHUNK_PROTOTYPE_LEVELS)
{
surroundMap.setOutCallback([this](int const x, int const z, int8_t) {
const auto& found = prototypes.find({x, z});
if (found == prototypes.end()) {
logger.warning() << "unable to remove non-existing chunk prototype";
return;
}
prototypes.erase({x, z});
});
surroundMap.setLevelCallback(1, [this](int const x, int const z) {
if (prototypes.find({x, z}) != prototypes.end()) {
return;
}
prototypes[{x, z}] = generatePrototype(x, z);
});
}
static inline void generate_pole(
@ -78,7 +100,6 @@ static inline const Biome* choose_biome(
std::unique_ptr<ChunkPrototype> WorldGenerator::generatePrototype(
int chunkX, int chunkZ
) {
// timeutil::ScopeLogTimer log(666);
auto biomeParams = def.script->generateParameterMaps(
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed);
const auto& biomes = def.script->getBiomes();
@ -103,11 +124,23 @@ void WorldGenerator::generateHeightmap(
prototype->level = ChunkPrototypeLevel::HEIGHTMAP;
}
void WorldGenerator::update(int centerX, int centerY, int loadDistance) {
surroundMap.setCenter(centerX, centerY);
surroundMap.resize(loadDistance);
surroundMap.setCenter(centerX, centerY);
}
void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) {
//timeutil::ScopeLogTimer log(555);
surroundMap.completeAt(chunkX, chunkZ);
auto prototype = generatePrototype(chunkX, chunkZ);
generateHeightmap(prototype.get(), chunkX, chunkZ);
const auto& found = prototypes.find({chunkX, chunkZ});
if (found == prototypes.end()) {
throw std::runtime_error("no prototype found");
}
auto prototype = found->second.get();
generateHeightmap(prototype, chunkX, chunkZ);
const auto values = prototype->heightmap->getValues();

View File

@ -3,10 +3,12 @@
#include <string>
#include <memory>
#include <vector>
#include <unordered_map>
#include "constants.hpp"
#include "typedefs.hpp"
#include "voxels/voxel.hpp"
#include "SurroundMap.hpp"
class Content;
struct GeneratorDef;
@ -42,6 +44,10 @@ class WorldGenerator {
const Content* content;
/// @param seed world seed
uint64_t seed;
/// @brief Chunk prototypes main storage
std::unordered_map<glm::ivec2, std::unique_ptr<ChunkPrototype>> prototypes;
/// @brief Chunk prototypes loading surround map
SurroundMap surroundMap;
/// @brief Generate chunk prototype (see ChunkPrototype)
/// @param x chunk position X divided by CHUNK_W
@ -57,6 +63,8 @@ public:
);
virtual ~WorldGenerator() = default;
virtual void update(int centerX, int centerY, int loadDistance);
/// @brief Generate complete chunk voxels
/// @param voxels destinatiopn chunk voxels buffer
/// @param x chunk position X divided by CHUNK_W