add StructurePlacement & add SurroundMap visualization test
This commit is contained in:
parent
88b0f8e3d6
commit
4f882a3ca3
@ -62,7 +62,7 @@ namespace util {
|
|||||||
return &firstBuffer[ly * sizeX + lx];
|
return &firstBuffer[ly * sizeX + lx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T get(TCoord x, TCoord y) {
|
T get(TCoord x, TCoord y) const {
|
||||||
auto lx = x - offsetX;
|
auto lx = x - offsetX;
|
||||||
auto ly = y - offsetY;
|
auto ly = y - offsetY;
|
||||||
if (lx < 0 || ly < 0 || lx >= sizeX || ly >= sizeY) {
|
if (lx < 0 || ly < 0 || lx >= sizeX || ly >= sizeY) {
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "maths/Heightmap.hpp"
|
#include "maths/Heightmap.hpp"
|
||||||
|
|
||||||
class Content;
|
class Content;
|
||||||
|
class VoxelStructure;
|
||||||
|
|
||||||
struct BlocksLayer {
|
struct BlocksLayer {
|
||||||
/// @brief Layer block
|
/// @brief Layer block
|
||||||
@ -99,8 +100,11 @@ class GeneratorScript {
|
|||||||
public:
|
public:
|
||||||
virtual ~GeneratorScript() = default;
|
virtual ~GeneratorScript() = default;
|
||||||
|
|
||||||
|
/// @brief Load all structures
|
||||||
|
//virtual std::vector<std::shared_ptr<VoxelStructure>> loadStructures() = 0;
|
||||||
|
|
||||||
/// @brief Generates a heightmap with values in range 0..1
|
/// @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 size size of the heightmap
|
||||||
/// @param seed world seed
|
/// @param seed world seed
|
||||||
/// @return generated heightmap of given size (can't be nullptr)
|
/// @return generated heightmap of given size (can't be nullptr)
|
||||||
|
|||||||
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
static debug::Logger logger("world-generator");
|
static debug::Logger logger("world-generator");
|
||||||
|
|
||||||
static inline constexpr uint MAX_PARAMETERS = 8;
|
static inline constexpr uint MAX_PARAMETERS = 4;
|
||||||
static inline constexpr uint MAX_CHUNK_PROTOTYPE_LEVELS = 8;
|
static inline constexpr uint MAX_CHUNK_PROTOTYPE_LEVELS = 3;
|
||||||
|
|
||||||
WorldGenerator::WorldGenerator(
|
WorldGenerator::WorldGenerator(
|
||||||
const GeneratorDef& def, const Content* content, uint64_t seed
|
const GeneratorDef& def, const Content* content, uint64_t seed
|
||||||
@ -114,10 +114,11 @@ std::unique_ptr<ChunkPrototype> WorldGenerator::generatePrototype(
|
|||||||
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed);
|
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed);
|
||||||
const auto& biomes = def.script->getBiomes();
|
const auto& biomes = def.script->getBiomes();
|
||||||
|
|
||||||
std::vector<const Biome*> chunkBiomes(CHUNK_W*CHUNK_D);
|
auto chunkBiomes = std::make_unique<const Biome*[]>(CHUNK_W*CHUNK_D);
|
||||||
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++) {
|
||||||
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<ChunkPrototype>(
|
return std::make_unique<ChunkPrototype>(
|
||||||
@ -162,9 +163,10 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) {
|
|||||||
PseudoRandom plantsRand;
|
PseudoRandom plantsRand;
|
||||||
plantsRand.setSeed(chunkX, chunkZ);
|
plantsRand.setSeed(chunkX, chunkZ);
|
||||||
|
|
||||||
|
const auto& biomes = prototype->biomes.get();
|
||||||
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 = prototype->biomes[z * CHUNK_W + x];
|
const Biome* biome = biomes[z * CHUNK_W + x];
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@ -20,18 +20,29 @@ enum class ChunkPrototypeLevel {
|
|||||||
BIOMES, HEIGHTMAP
|
BIOMES, HEIGHTMAP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct StructurePlacement {
|
||||||
|
VoxelStructure& structure;
|
||||||
|
|
||||||
|
glm::ivec3 position;
|
||||||
|
|
||||||
|
StructurePlacement(VoxelStructure& structure, glm::ivec3 position)
|
||||||
|
: structure(structure), position(std::move(position)) {}
|
||||||
|
};
|
||||||
|
|
||||||
struct ChunkPrototype {
|
struct ChunkPrototype {
|
||||||
ChunkPrototypeLevel level;
|
ChunkPrototypeLevel level;
|
||||||
|
|
||||||
/// @brief chunk biomes matrix
|
/// @brief chunk biomes matrix
|
||||||
std::vector<const Biome*> biomes;
|
std::unique_ptr<const Biome*[]> biomes;
|
||||||
|
|
||||||
/// @brief chunk heightmap
|
/// @brief chunk heightmap
|
||||||
std::shared_ptr<Heightmap> heightmap;
|
std::shared_ptr<Heightmap> heightmap;
|
||||||
|
|
||||||
|
std::vector<StructurePlacement> structures;
|
||||||
|
|
||||||
ChunkPrototype(
|
ChunkPrototype(
|
||||||
ChunkPrototypeLevel level,
|
ChunkPrototypeLevel level,
|
||||||
std::vector<const Biome*> biomes,
|
std::unique_ptr<const Biome*[]> biomes,
|
||||||
std::shared_ptr<Heightmap> heightmap
|
std::shared_ptr<Heightmap> heightmap
|
||||||
) : level(level),
|
) : level(level),
|
||||||
biomes(std::move(biomes)),
|
biomes(std::move(biomes)),
|
||||||
|
|||||||
@ -30,3 +30,49 @@ TEST(SurroundMap, InitTest) {
|
|||||||
map.completeAt(x - 1, y);
|
map.completeAt(x - 1, y);
|
||||||
EXPECT_EQ(affected, maxLevel * 2 - 1);
|
EXPECT_EQ(affected, maxLevel * 2 - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define VISUAL_TEST
|
||||||
|
#ifdef VISUAL_TEST
|
||||||
|
|
||||||
|
#include <glm/gtc/random.hpp>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user