mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-17 16:17:02 +08:00
feat: add ChunkGenerator
This commit is contained in:
@@ -20,6 +20,7 @@ enum class Biome {
|
||||
NONE
|
||||
};
|
||||
|
||||
|
||||
struct BiomeHeightRange {
|
||||
int base_y;
|
||||
int amplitude;
|
||||
@@ -31,6 +32,13 @@ struct BiomeNonAdjacent {
|
||||
Biome replace;
|
||||
};
|
||||
|
||||
static inline const std::vector<BiomeNonAdjacent> NON_ADJACENT {{
|
||||
{Biome::PLAIN, {Biome::NONE}, Biome::PLAIN},
|
||||
{Biome::FOREST, {Biome::DESERT}, Biome::PLAIN},
|
||||
{Biome::DESERT, {Biome::MOUNTAIN, Biome::FOREST}, Biome::PLAIN},
|
||||
{Biome::MOUNTAIN, {Biome::DESERT}, Biome::PLAIN}
|
||||
}};
|
||||
|
||||
struct BaseBiomeParams {
|
||||
Biome biome;
|
||||
std::pair<float, float> temp;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/primitive_data.hpp>
|
||||
#include <Cubed/gameplay/biome.hpp>
|
||||
#include <Cubed/gameplay/chunk_generator.hpp>
|
||||
#include <Cubed/gameplay/chunk_pos.hpp>
|
||||
#include <Cubed/gameplay/block.hpp>
|
||||
|
||||
@@ -19,22 +20,17 @@ private:
|
||||
static constexpr int SIZE_X = CHUCK_SIZE;
|
||||
static constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||
static constexpr int SIZE_Z = CHUCK_SIZE;
|
||||
|
||||
static inline const std::vector<BiomeNonAdjacent> NON_ADJACENT {{
|
||||
{Biome::PLAIN, {Biome::NONE}, Biome::PLAIN},
|
||||
{Biome::FOREST, {Biome::DESERT}, Biome::PLAIN},
|
||||
{Biome::DESERT, {Biome::MOUNTAIN, Biome::FOREST}, Biome::PLAIN},
|
||||
{Biome::MOUNTAIN, {Biome::DESERT}, Biome::PLAIN}
|
||||
}
|
||||
};
|
||||
|
||||
using HeightMapArray = std::array<std::array<float, SIZE_Z>, SIZE_X>;
|
||||
std::atomic<bool> m_dirty {false};
|
||||
std::atomic<bool> m_need_upload{true};
|
||||
std::atomic<bool> m_is_on_gen_vertex_data {false};
|
||||
std::atomic<size_t> m_vertex_sum = 0;
|
||||
std::atomic<Biome> m_biome = Biome::PLAIN;
|
||||
std::mutex m_vertexs_data_mutex;
|
||||
|
||||
std::atomic<Biome> m_biome = Biome::PLAIN;
|
||||
std::unique_ptr<ChunkGenerator> m_generator;
|
||||
|
||||
ChunkPos m_chunk_pos;
|
||||
World& m_world;
|
||||
HeightMapArray m_heightmap;
|
||||
@@ -57,25 +53,25 @@ public:
|
||||
Chunk& operator=(Chunk&&) noexcept;
|
||||
|
||||
Biome get_biome() const;
|
||||
|
||||
ChunkPos get_chunk_pos() const;
|
||||
const std::vector<uint8_t>& 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);
|
||||
// Init Chunk
|
||||
// Generate Biome
|
||||
// Determine biome from temperature and humidity noise
|
||||
void gen_phase_one();
|
||||
// Adjust Biome
|
||||
// Resolve biome adjacency conflicts with neighbor chunks
|
||||
void gen_phase_two(const std::array<const Chunk*, 4>& adj_chunks);
|
||||
// Generate Heightmap
|
||||
// Generate heightmap using biome-specific noise
|
||||
void gen_phase_three();
|
||||
// Adjust Height
|
||||
// Blend heightmap with neighbors for smooth transitions
|
||||
void gen_phase_four(const std::array<std::optional<HeightMapArray>, 4>& neighbor_heightmap);
|
||||
// Generate Block
|
||||
// Generate terrain blocks from heightmap and biome
|
||||
void gen_phase_five();
|
||||
// Adjust Block;
|
||||
// Blend surface blocks at chunk borders with neighbors
|
||||
void gen_phase_six(const std::array<std::optional<std::vector<uint8_t>>, 4>& neighbor_block);
|
||||
// Generate Structure
|
||||
// Generate biome-specific vegetation/structures
|
||||
void gen_phase_seven();
|
||||
//void gen_vertex_data();
|
||||
// 0 : (1, 0)
|
||||
@@ -96,6 +92,11 @@ public:
|
||||
|
||||
void set_chunk_block(int index, unsigned id);
|
||||
|
||||
ChunkPos chunk_pos() const;
|
||||
Biome biome() const;
|
||||
void biome(Biome b);
|
||||
HeightMapArray& heightmap();
|
||||
std::vector<uint8_t>& blocks();
|
||||
};
|
||||
|
||||
|
||||
|
||||
50
include/Cubed/gameplay/chunk_generator.hpp
Normal file
50
include/Cubed/gameplay/chunk_generator.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <Cubed/constants.hpp>
|
||||
#include <Cubed/tools/cubed_random.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <optional>
|
||||
namespace Cubed {
|
||||
|
||||
|
||||
class Chunk;
|
||||
|
||||
class ChunkGenerator {
|
||||
static constexpr int SIZE_X = CHUCK_SIZE;
|
||||
static constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||
static constexpr int SIZE_Z = CHUCK_SIZE;
|
||||
using HeightMapArray = std::array<std::array<float, CHUCK_SIZE>, CHUCK_SIZE>;
|
||||
public:
|
||||
ChunkGenerator(Chunk& chunk);
|
||||
|
||||
static void init();
|
||||
static void reload();
|
||||
static const unsigned& seed();
|
||||
static void seed(unsigned s);
|
||||
|
||||
// Generate Biome
|
||||
void assign_chunk_biome();
|
||||
// Adjust Biome
|
||||
void resolve_biome_adjacency_conflict(const std::array<const Chunk*, 4>& adj_chunks);
|
||||
// Generate Heightmap
|
||||
void generate_heightmap();
|
||||
// Adjust Height
|
||||
void blend_heightmap_boundaries(const std::array<std::optional<HeightMapArray>, 4>& neighbor_heightmap);
|
||||
// Generate Block
|
||||
void generate_terrain_blocks();
|
||||
// Adjust Block;
|
||||
void blend_surface_blocks_borders(const std::array<std::optional<std::vector<uint8_t>>, 4>& neighbor_block);
|
||||
// Generate Structure
|
||||
void generate_vegetation();
|
||||
|
||||
private:
|
||||
static inline std::atomic<bool> is_init {false};
|
||||
static inline unsigned m_generator_seed {0};
|
||||
static inline std::atomic<bool> is_seed_change {false};
|
||||
Chunk& m_chunk;
|
||||
Random m_random;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <string_view>
|
||||
|
||||
#include <cstdint>
|
||||
namespace Cubed {
|
||||
|
||||
|
||||
@@ -8,7 +8,26 @@ namespace HASH {
|
||||
inline std::size_t str(std::string_view value) {
|
||||
return std::hash<std::string_view>{}(value);
|
||||
}
|
||||
|
||||
inline uint32_t mix_hash(int32_t a, int32_t b, uint32_t fixed_seed) {
|
||||
uint32_t h = fixed_seed;
|
||||
|
||||
h ^= (uint32_t)a * 0xcc9e2d51u;
|
||||
h = (h << 15) | (h >> 17); // rotl 15
|
||||
h *= 0x1b873593u;
|
||||
|
||||
h ^= (uint32_t)b * 0xcc9e2d51u;
|
||||
h = (h << 15) | (h >> 17); // rotl 15
|
||||
h *= 0x1b873593u;
|
||||
|
||||
// Finalization(avalanche)
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6bu;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35u;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,16 +4,15 @@ namespace Cubed {
|
||||
|
||||
class Random {
|
||||
public:
|
||||
static unsigned get_base_seed();
|
||||
static unsigned get_thread_seed();
|
||||
static Random& get();
|
||||
Random();
|
||||
|
||||
bool random_bool(double probability);
|
||||
std::mt19937& engine();
|
||||
unsigned seed();
|
||||
|
||||
void init(unsigned seed);
|
||||
|
||||
private:
|
||||
Random();
|
||||
unsigned int m_seed = 0;
|
||||
std::mt19937 m_engine;
|
||||
};
|
||||
|
||||
@@ -7,16 +7,12 @@ namespace Cubed {
|
||||
|
||||
class PerlinNoise {
|
||||
public:
|
||||
static void init();
|
||||
static void init(unsigned seed);
|
||||
static float noise(float x, float y, float z);
|
||||
static void reload();
|
||||
static const unsigned& seed();
|
||||
static void seed(unsigned seed);
|
||||
static void reload(unsigned seed);
|
||||
private:
|
||||
static inline std::atomic<bool> is_init = false;
|
||||
static inline std::vector<int> p;
|
||||
static inline unsigned m_seed = 0;
|
||||
static inline bool is_seed_change = false;
|
||||
static float fade(float t);
|
||||
static float lerp(float t, float a, float b);
|
||||
static float grad(int hash, float x, float y, float z);
|
||||
|
||||
Reference in New Issue
Block a user