mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-18 00:27:02 +08:00
refactor: terrain generation (#9)
* feat: add BlockType * refactor: use fBM for heightmap generation * feat: improve mountain realism * refactor: adjust mountain spawn probability * feat: add biome boundary blending * refactor: remove resolve_biome_adjacency_conflict function * feat: add snowy plain * perf: speed up world generation * refactor: lower overall terrain height
This commit is contained in:
@@ -8,7 +8,7 @@ constexpr int WORLD_SIZE_Y = 256;
|
||||
constexpr int CHUNK_SIZE = 16;
|
||||
constexpr int SEA_LEVEL = 64;
|
||||
|
||||
constexpr int MAX_BLOCK_NUM = 8;
|
||||
constexpr int MAX_BLOCK_NUM = 9;
|
||||
constexpr int MAX_UI_NUM = 1;
|
||||
constexpr int MAX_BLOCK_STATUS = 1;
|
||||
constexpr int MAX_BIOME_SUM = 4;
|
||||
|
||||
@@ -5,9 +5,24 @@
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
constexpr float BIOME_NOISE_FREQUENCY = 0.03f;
|
||||
constexpr float BIOME_NOISE_FREQUENCY = 0.06f;
|
||||
constexpr float HEIGHTMAP_NOISE_FREQUENCY = 0.001f;
|
||||
constexpr float MOUNTAINOUS_NOISE_FREQUENCY = 0.003f;
|
||||
enum class BiomeType {
|
||||
PLAIN = 0,
|
||||
FOREST,
|
||||
DESERT,
|
||||
MOUNTAIN,
|
||||
RIVER,
|
||||
SNOWY_PLAIN,
|
||||
NONE
|
||||
};
|
||||
|
||||
enum class BiomeType { PLAIN = 0, FOREST, DESERT, MOUNTAIN, RIVER, NONE };
|
||||
struct BiomeConditions {
|
||||
float temp = 0.0f;
|
||||
float humid = 0.0f;
|
||||
float mountainous = 0.0f;
|
||||
};
|
||||
|
||||
struct BiomeHeightRange {
|
||||
int base_y;
|
||||
@@ -47,13 +62,14 @@ struct MountainParams : public BaseBiomeParams {};
|
||||
struct RiverParams : public BaseBiomeParams {};
|
||||
|
||||
std::string get_biome_str(BiomeType biome);
|
||||
BiomeType get_biome_from_noise(float temp, float humid);
|
||||
std::array<float, 3> get_noise_frequencies_for_biome(BiomeType biome);
|
||||
BiomeHeightRange get_biome_height_range(BiomeType biome);
|
||||
// std::array<float, 3> get_noise_frequencies_for_biome(BiomeType biome);
|
||||
// BiomeHeightRange get_biome_height_range(BiomeType biome);
|
||||
BiomeType safe_int_to_biome(int x);
|
||||
int get_interpolated_height(float world_x, float world_z, float temp,
|
||||
float humid);
|
||||
|
||||
BiomeType determine_biome(const BiomeConditions& conditions);
|
||||
|
||||
PlainParams& plain_params();
|
||||
ForestParams& forest_params();
|
||||
DesertParams& desert_params();
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
using BlockType = uint8_t;
|
||||
|
||||
struct BlockTexture {
|
||||
std::string name;
|
||||
unsigned id;
|
||||
@@ -39,10 +41,11 @@ struct LookBlock {
|
||||
};
|
||||
|
||||
constexpr std::array<std::string_view, MAX_BLOCK_NUM> BLOCK_REISTER{
|
||||
"air", "grass_block", "dirt", "stone", "sand", "log", "leaf", "water"};
|
||||
"air", "grass_block", "dirt", "stone", "sand", "log", "leaf",
|
||||
"water", "snowy_grass_block"};
|
||||
|
||||
const std::array<bool, MAX_BLOCK_NUM> TRANSPARENT_MAP{
|
||||
true, false, false, false, false, false, true};
|
||||
true, false, false, false, false, false, true, false, false};
|
||||
|
||||
inline bool is_in_transparent_map(unsigned id) {
|
||||
ASSERT_MSG(id < MAX_BLOCK_NUM, "ID is invaild");
|
||||
|
||||
21
include/Cubed/gameplay/builders/snowy_plain_builder.hpp
Normal file
21
include/Cubed/gameplay/builders/snowy_plain_builder.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class SnowyPlainBuilder : public BiomeBuilder {
|
||||
public:
|
||||
SnowyPlainBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
@@ -32,13 +31,16 @@ private:
|
||||
World& m_world;
|
||||
HeightMapArray m_heightmap;
|
||||
// the index is a array of block id
|
||||
std::vector<uint8_t> m_blocks;
|
||||
std::vector<BlockType> m_blocks;
|
||||
GLuint m_vbo = 0;
|
||||
std::vector<Vertex> m_vertexs_data;
|
||||
|
||||
float frequency = 0.01f;
|
||||
float height = 80;
|
||||
unsigned m_seed = 0;
|
||||
|
||||
BiomeConditions m_conditions;
|
||||
|
||||
void clear_dirty();
|
||||
|
||||
public:
|
||||
@@ -49,12 +51,21 @@ public:
|
||||
Chunk(Chunk&&) noexcept;
|
||||
Chunk& operator=(Chunk&&) noexcept;
|
||||
|
||||
static std::tuple<int, int, int> world_to_block(int world_x, int world_y,
|
||||
int world_z, int chunk_x,
|
||||
int chunk_z);
|
||||
static std::tuple<int, int, int> world_to_block(const glm::ivec3& block_pos,
|
||||
ChunkPos chunk_pos);
|
||||
static std::tuple<int, int, int> block_to_world(int x, int y, int z,
|
||||
int chunk_x, int chunk_z);
|
||||
static std::tuple<int, int, int> block_to_world(const glm::ivec3& block_pos,
|
||||
ChunkPos chunk_pos);
|
||||
BiomeType get_biome() const;
|
||||
ChunkPos get_chunk_pos() const;
|
||||
const std::vector<uint8_t>& get_chunk_blocks() const;
|
||||
const std::vector<BlockType>& get_chunk_blocks() const;
|
||||
HeightMapArray get_heightmap() const;
|
||||
static int get_index(int x, int y, int z);
|
||||
static int get_index(const glm::vec3& pos);
|
||||
static int index(int x, int y, int z);
|
||||
static int index(const glm::vec3& pos);
|
||||
// Init Chunk
|
||||
// Determine biome from temperature and humidity noise
|
||||
void gen_phase_one();
|
||||
@@ -69,8 +80,8 @@ public:
|
||||
// Generate terrain blocks from heightmap and biome
|
||||
void gen_phase_five();
|
||||
// Blend surface blocks at chunk borders with neighbors
|
||||
void gen_phase_six(const std::array<std::optional<std::vector<uint8_t>>, 4>&
|
||||
neighbor_block);
|
||||
void gen_phase_six(const std::array<std::optional<std::vector<BlockType>>,
|
||||
4>& neighbor_block);
|
||||
// Generate biome-specific vegetation/structures
|
||||
void gen_phase_seven();
|
||||
// void gen_vertex_data();
|
||||
@@ -79,7 +90,7 @@ public:
|
||||
// 2 : (0, 1)
|
||||
// 3 : (0, -1)
|
||||
void gen_vertex_data(
|
||||
const std::array<const std::vector<uint8_t>*, 4>& neighbor_block);
|
||||
const std::array<const std::vector<BlockType>*, 4>& neighbor_block);
|
||||
void upload_to_gpu();
|
||||
|
||||
GLuint get_vbo() const;
|
||||
@@ -97,9 +108,10 @@ public:
|
||||
BiomeType biome() const;
|
||||
void biome(BiomeType b);
|
||||
HeightMapArray& heightmap();
|
||||
std::vector<uint8_t>& blocks();
|
||||
std::vector<BlockType>& blocks();
|
||||
World& world();
|
||||
unsigned seed() const;
|
||||
BiomeConditions& conditions();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/biome.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
void generate_terrain_blocks();
|
||||
// Adjust Block;
|
||||
void blend_surface_blocks_borders(
|
||||
const std::array<std::optional<std::vector<uint8_t>>, 4>&
|
||||
const std::array<std::optional<std::vector<BlockType>>, 4>&
|
||||
neighbor_block);
|
||||
// Generate Structure
|
||||
void generate_vegetation();
|
||||
@@ -44,6 +45,7 @@ public:
|
||||
Chunk& chunk();
|
||||
Random& random();
|
||||
const std::array<BiomeType, 8>& neighbor_biome() const;
|
||||
void generate_cave();
|
||||
|
||||
private:
|
||||
static inline std::atomic<bool> is_init{false};
|
||||
@@ -57,7 +59,6 @@ private:
|
||||
unsigned m_chunk_seed = 0;
|
||||
|
||||
void make_biome_builder();
|
||||
void generate_cave();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class PerlinNoise {
|
||||
class PerlinNoise3D {
|
||||
public:
|
||||
static void init(unsigned seed);
|
||||
static float noise(float x, float y, float z);
|
||||
@@ -18,4 +18,19 @@ private:
|
||||
static float grad(int hash, float x, float y, float z);
|
||||
};
|
||||
|
||||
class PerlinNoise2D {
|
||||
public:
|
||||
static void init(unsigned seed);
|
||||
static float noise(float x, float y);
|
||||
static void reload(unsigned seed);
|
||||
|
||||
private:
|
||||
static inline std::atomic<bool> is_init = false;
|
||||
static inline std::vector<int> p;
|
||||
|
||||
static float fade(float t);
|
||||
static float lerp(float t, float a, float b);
|
||||
static float grad(int hash, float x, float y);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user