From 4f882a3ca3e2eef345a0b11bbc923a18e6d38ced Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 20 Sep 2024 23:43:54 +0300 Subject: [PATCH] add StructurePlacement & add SurroundMap visualization test --- src/util/AreaMap2D.hpp | 2 +- src/world/generator/GeneratorDef.hpp | 6 +++- src/world/generator/WorldGenerator.cpp | 12 ++++--- src/world/generator/WorldGenerator.hpp | 15 +++++++-- test/world/generator/SurroundMap.cpp | 46 ++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/src/util/AreaMap2D.hpp b/src/util/AreaMap2D.hpp index 3b550ae2..a14a0a5f 100644 --- a/src/util/AreaMap2D.hpp +++ b/src/util/AreaMap2D.hpp @@ -62,7 +62,7 @@ namespace util { return &firstBuffer[ly * sizeX + lx]; } - T get(TCoord x, TCoord y) { + T get(TCoord x, TCoord y) const { auto lx = x - offsetX; auto ly = y - offsetY; if (lx < 0 || ly < 0 || lx >= sizeX || ly >= sizeY) { diff --git a/src/world/generator/GeneratorDef.hpp b/src/world/generator/GeneratorDef.hpp index 4824a39e..3b5df181 100644 --- a/src/world/generator/GeneratorDef.hpp +++ b/src/world/generator/GeneratorDef.hpp @@ -7,6 +7,7 @@ #include "maths/Heightmap.hpp" class Content; +class VoxelStructure; struct BlocksLayer { /// @brief Layer block @@ -99,8 +100,11 @@ class GeneratorScript { public: virtual ~GeneratorScript() = default; + /// @brief Load all structures + //virtual std::vector> loadStructures() = 0; + /// @brief Generates a heightmap with values in range 0..1 - /// @param offset position of the heightmap top left corner in the world + /// @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) diff --git a/src/world/generator/WorldGenerator.cpp b/src/world/generator/WorldGenerator.cpp index 726467a0..25899272 100644 --- a/src/world/generator/WorldGenerator.cpp +++ b/src/world/generator/WorldGenerator.cpp @@ -14,8 +14,8 @@ static debug::Logger logger("world-generator"); -static inline constexpr uint MAX_PARAMETERS = 8; -static inline constexpr uint MAX_CHUNK_PROTOTYPE_LEVELS = 8; +static inline constexpr uint MAX_PARAMETERS = 4; +static inline constexpr uint MAX_CHUNK_PROTOTYPE_LEVELS = 3; WorldGenerator::WorldGenerator( const GeneratorDef& def, const Content* content, uint64_t seed @@ -114,10 +114,11 @@ std::unique_ptr WorldGenerator::generatePrototype( {chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed); const auto& biomes = def.script->getBiomes(); - std::vector chunkBiomes(CHUNK_W*CHUNK_D); + auto chunkBiomes = std::make_unique(CHUNK_W*CHUNK_D); for (uint z = 0; z < CHUNK_D; z++) { for (uint x = 0; x < CHUNK_W; x++) { - chunkBiomes[z * CHUNK_W + x] = choose_biome(biomes, biomeParams, x, z); + chunkBiomes.get()[z * CHUNK_W + x] = + choose_biome(biomes, biomeParams, x, z); } } return std::make_unique( @@ -162,9 +163,10 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { PseudoRandom plantsRand; plantsRand.setSeed(chunkX, chunkZ); + const auto& biomes = prototype->biomes.get(); for (uint z = 0; z < CHUNK_D; z++) { for (uint x = 0; x < CHUNK_W; x++) { - const Biome* biome = prototype->biomes[z * CHUNK_W + x]; + const Biome* biome = biomes[z * CHUNK_W + x]; int height = values[z * CHUNK_W + x] * CHUNK_H; height = std::max(0, height); diff --git a/src/world/generator/WorldGenerator.hpp b/src/world/generator/WorldGenerator.hpp index d30d88f9..4241433e 100644 --- a/src/world/generator/WorldGenerator.hpp +++ b/src/world/generator/WorldGenerator.hpp @@ -20,18 +20,29 @@ enum class ChunkPrototypeLevel { BIOMES, HEIGHTMAP }; +struct StructurePlacement { + VoxelStructure& structure; + + glm::ivec3 position; + + StructurePlacement(VoxelStructure& structure, glm::ivec3 position) + : structure(structure), position(std::move(position)) {} +}; + struct ChunkPrototype { ChunkPrototypeLevel level; /// @brief chunk biomes matrix - std::vector biomes; + std::unique_ptr biomes; /// @brief chunk heightmap std::shared_ptr heightmap; + std::vector structures; + ChunkPrototype( ChunkPrototypeLevel level, - std::vector biomes, + std::unique_ptr biomes, std::shared_ptr heightmap ) : level(level), biomes(std::move(biomes)), diff --git a/test/world/generator/SurroundMap.cpp b/test/world/generator/SurroundMap.cpp index 7131ff94..6fb5d7ae 100644 --- a/test/world/generator/SurroundMap.cpp +++ b/test/world/generator/SurroundMap.cpp @@ -30,3 +30,49 @@ TEST(SurroundMap, InitTest) { map.completeAt(x - 1, y); EXPECT_EQ(affected, maxLevel * 2 - 1); } + +#define VISUAL_TEST +#ifdef VISUAL_TEST + +#include + +#include "coders/png.hpp" +#include "graphics/core/ImageData.hpp" + +void visualize(const SurroundMap& map, int mul, int max) { + const auto& areaMap = map.getArea(); + int w = areaMap.getWidth(); + int h = areaMap.getHeight(); + int ox = areaMap.getOffsetX(); + int oy = areaMap.getOffsetY(); + + ImageData image(ImageFormat::rgb888, w, h); + ubyte* bytes = image.getData(); + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int val = areaMap.get(x + ox, y + oy) * mul; + if (val && val / mul < max) { + val = val / 4 + 50; + } + bytes[(y * w + x) * 3] = val; + bytes[(y * w + x) * 3 + 1] = val; + bytes[(y * w + x) * 3 + 2] = val; + } + } + png::write_image("test.png", &image); +} + +TEST(SurroundMap, Visualize) { + int levels = 3; + SurroundMap map(50, levels); + map.setCenter(0, 0); + + for (int i = 0; i < 1000; i++) { + float x = glm::gaussRand(0.0f, 2.0f); + float y = glm::gaussRand(0.0f, 2.0f); + map.completeAt(x, y); + } + visualize(map, 30, levels); +} + +#endif