mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-18 00:27:02 +08:00
feat: add BlockType
This commit is contained in:
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
|
using BlockType = uint8_t;
|
||||||
|
|
||||||
struct BlockTexture {
|
struct BlockTexture {
|
||||||
std::string name;
|
std::string name;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "Cubed/primitive_data.hpp"
|
#include "Cubed/primitive_data.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
@@ -32,7 +31,7 @@ private:
|
|||||||
World& m_world;
|
World& m_world;
|
||||||
HeightMapArray m_heightmap;
|
HeightMapArray m_heightmap;
|
||||||
// the index is a array of block id
|
// the index is a array of block id
|
||||||
std::vector<uint8_t> m_blocks;
|
std::vector<BlockType> m_blocks;
|
||||||
GLuint m_vbo = 0;
|
GLuint m_vbo = 0;
|
||||||
std::vector<Vertex> m_vertexs_data;
|
std::vector<Vertex> m_vertexs_data;
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ public:
|
|||||||
|
|
||||||
BiomeType get_biome() const;
|
BiomeType get_biome() const;
|
||||||
ChunkPos get_chunk_pos() 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;
|
HeightMapArray get_heightmap() const;
|
||||||
static int get_index(int x, int y, int z);
|
static int get_index(int x, int y, int z);
|
||||||
static int get_index(const glm::vec3& pos);
|
static int get_index(const glm::vec3& pos);
|
||||||
@@ -69,8 +68,8 @@ public:
|
|||||||
// Generate terrain blocks from heightmap and biome
|
// Generate terrain blocks from heightmap and biome
|
||||||
void gen_phase_five();
|
void gen_phase_five();
|
||||||
// Blend surface blocks at chunk borders with neighbors
|
// Blend surface blocks at chunk borders with neighbors
|
||||||
void gen_phase_six(const std::array<std::optional<std::vector<uint8_t>>, 4>&
|
void gen_phase_six(const std::array<std::optional<std::vector<BlockType>>,
|
||||||
neighbor_block);
|
4>& neighbor_block);
|
||||||
// Generate biome-specific vegetation/structures
|
// Generate biome-specific vegetation/structures
|
||||||
void gen_phase_seven();
|
void gen_phase_seven();
|
||||||
// void gen_vertex_data();
|
// void gen_vertex_data();
|
||||||
@@ -79,7 +78,7 @@ public:
|
|||||||
// 2 : (0, 1)
|
// 2 : (0, 1)
|
||||||
// 3 : (0, -1)
|
// 3 : (0, -1)
|
||||||
void gen_vertex_data(
|
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();
|
void upload_to_gpu();
|
||||||
|
|
||||||
GLuint get_vbo() const;
|
GLuint get_vbo() const;
|
||||||
@@ -97,7 +96,7 @@ public:
|
|||||||
BiomeType biome() const;
|
BiomeType biome() const;
|
||||||
void biome(BiomeType b);
|
void biome(BiomeType b);
|
||||||
HeightMapArray& heightmap();
|
HeightMapArray& heightmap();
|
||||||
std::vector<uint8_t>& blocks();
|
std::vector<BlockType>& blocks();
|
||||||
World& world();
|
World& world();
|
||||||
unsigned seed() const;
|
unsigned seed() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Cubed/constants.hpp"
|
#include "Cubed/constants.hpp"
|
||||||
#include "Cubed/gameplay/biome.hpp"
|
#include "Cubed/gameplay/biome.hpp"
|
||||||
|
#include "Cubed/gameplay/block.hpp"
|
||||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||||
#include "Cubed/tools/cubed_random.hpp"
|
#include "Cubed/tools/cubed_random.hpp"
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ public:
|
|||||||
void generate_terrain_blocks();
|
void generate_terrain_blocks();
|
||||||
// Adjust Block;
|
// Adjust Block;
|
||||||
void blend_surface_blocks_borders(
|
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);
|
neighbor_block);
|
||||||
// Generate Structure
|
// Generate Structure
|
||||||
void generate_vegetation();
|
void generate_vegetation();
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ BiomeType Chunk::get_biome() const { return m_biome.load(); }
|
|||||||
|
|
||||||
ChunkPos Chunk::get_chunk_pos() const { return m_chunk_pos; }
|
ChunkPos Chunk::get_chunk_pos() const { return m_chunk_pos; }
|
||||||
|
|
||||||
const std::vector<uint8_t>& Chunk::get_chunk_blocks() const { return m_blocks; }
|
const std::vector<BlockType>& Chunk::get_chunk_blocks() const {
|
||||||
|
return m_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
HeightMapArray Chunk::get_heightmap() const {
|
HeightMapArray Chunk::get_heightmap() const {
|
||||||
// Logger::info("Chunk pos {} {} in get_heightmap this {}", m_chunk_pos.x,
|
// Logger::info("Chunk pos {} {} in get_heightmap this {}", m_chunk_pos.x,
|
||||||
@@ -76,7 +78,7 @@ int Chunk::get_index(const glm::vec3& pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::gen_vertex_data(
|
void Chunk::gen_vertex_data(
|
||||||
const std::array<const std::vector<uint8_t>*, 4>& neighbor_block) {
|
const std::array<const std::vector<BlockType>*, 4>& neighbor_block) {
|
||||||
if (m_is_on_gen_vertex_data) {
|
if (m_is_on_gen_vertex_data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -116,7 +118,7 @@ void Chunk::gen_vertex_data(
|
|||||||
World::chunk_pos(world_nx, world_nz);
|
World::chunk_pos(world_nx, world_nz);
|
||||||
|
|
||||||
auto is_cull =
|
auto is_cull =
|
||||||
[&](const std::vector<uint8_t>* chunk_blocks) {
|
[&](const std::vector<BlockType>* chunk_blocks) {
|
||||||
if (chunk_blocks == nullptr) {
|
if (chunk_blocks == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -252,7 +254,8 @@ void Chunk::gen_phase_five() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::gen_phase_six(
|
void Chunk::gen_phase_six(
|
||||||
const std::array<std::optional<std::vector<uint8_t>>, 4>& neighbor_block) {
|
const std::array<std::optional<std::vector<BlockType>>, 4>&
|
||||||
|
neighbor_block) {
|
||||||
if (!m_generator) {
|
if (!m_generator) {
|
||||||
Logger::error("ChunkGenerator is Nullptr");
|
Logger::error("ChunkGenerator is Nullptr");
|
||||||
return;
|
return;
|
||||||
@@ -308,7 +311,7 @@ BiomeType Chunk::biome() const { return m_biome; }
|
|||||||
void Chunk::biome(BiomeType b) { m_biome = b; }
|
void Chunk::biome(BiomeType b) { m_biome = b; }
|
||||||
|
|
||||||
HeightMapArray& Chunk::heightmap() { return m_heightmap; }
|
HeightMapArray& Chunk::heightmap() { return m_heightmap; }
|
||||||
std::vector<uint8_t>& Chunk::blocks() { return m_blocks; }
|
std::vector<BlockType>& Chunk::blocks() { return m_blocks; }
|
||||||
World& Chunk::world() { return m_world; }
|
World& Chunk::world() { return m_world; }
|
||||||
unsigned Chunk::seed() const {
|
unsigned Chunk::seed() const {
|
||||||
if (m_seed == 0) {
|
if (m_seed == 0) {
|
||||||
|
|||||||
@@ -366,7 +366,8 @@ void ChunkGenerator::generate_terrain_blocks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ChunkGenerator::blend_surface_blocks_borders(
|
void ChunkGenerator::blend_surface_blocks_borders(
|
||||||
const std::array<std::optional<std::vector<uint8_t>>, 4>& neighbor_block) {
|
const std::array<std::optional<std::vector<BlockType>>, 4>&
|
||||||
|
neighbor_block) {
|
||||||
auto& m_blocks = m_chunk.blocks();
|
auto& m_blocks = m_chunk.blocks();
|
||||||
auto& m_heightmap = m_chunk.heightmap();
|
auto& m_heightmap = m_chunk.heightmap();
|
||||||
|
|
||||||
@@ -374,8 +375,8 @@ void ChunkGenerator::blend_surface_blocks_borders(
|
|||||||
|
|
||||||
// Helper lambda: get top block type from a neighbor's block data at (nx,
|
// Helper lambda: get top block type from a neighbor's block data at (nx,
|
||||||
// nz)
|
// nz)
|
||||||
auto get_top_block_from_neighbor = [&](const std::vector<uint8_t>& blocks,
|
auto get_top_block_from_neighbor = [&](const std::vector<BlockType>& blocks,
|
||||||
int nx, int nz) -> uint8_t {
|
int nx, int nz) -> BlockType {
|
||||||
// Search from topmost y downwards for the first non-zero block
|
// Search from topmost y downwards for the first non-zero block
|
||||||
for (int y = WORLD_HEIGHT - 1; y >= 0; --y) {
|
for (int y = WORLD_HEIGHT - 1; y >= 0; --y) {
|
||||||
int idx = Chunk::get_index(
|
int idx = Chunk::get_index(
|
||||||
@@ -392,7 +393,7 @@ void ChunkGenerator::blend_surface_blocks_borders(
|
|||||||
for (int x = 0; x < CHUNK_SIZE; ++x) {
|
for (int x = 0; x < CHUNK_SIZE; ++x) {
|
||||||
for (int z = 0; z < CHUNK_SIZE; ++z) {
|
for (int z = 0; z < CHUNK_SIZE; ++z) {
|
||||||
// Get the current top block type of this column from m_blocks
|
// Get the current top block type of this column from m_blocks
|
||||||
uint8_t type_self = 0;
|
BlockType type_self = 0;
|
||||||
int top_y = -1;
|
int top_y = -1;
|
||||||
top_y = m_heightmap[x][z];
|
top_y = m_heightmap[x][z];
|
||||||
type_self = m_blocks[Chunk::get_index(x, top_y, z)];
|
type_self = m_blocks[Chunk::get_index(x, top_y, z)];
|
||||||
@@ -401,7 +402,7 @@ void ChunkGenerator::blend_surface_blocks_borders(
|
|||||||
continue; // no block? skip
|
continue; // no block? skip
|
||||||
|
|
||||||
// Weight map: type -> total weight
|
// Weight map: type -> total weight
|
||||||
std::unordered_map<uint8_t, float> weights;
|
std::unordered_map<BlockType, float> weights;
|
||||||
weights[type_self] = 1.0f; // self weight
|
weights[type_self] = 1.0f; // self weight
|
||||||
|
|
||||||
// --- Right neighbor (index 0) ---
|
// --- Right neighbor (index 0) ---
|
||||||
@@ -410,7 +411,7 @@ void ChunkGenerator::blend_surface_blocks_borders(
|
|||||||
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
||||||
t = t * t * (3.0f - 2.0f * t); // smoothstep
|
t = t * t * (3.0f - 2.0f * t); // smoothstep
|
||||||
if (t > 0.0f) {
|
if (t > 0.0f) {
|
||||||
uint8_t type_neighbor =
|
BlockType type_neighbor =
|
||||||
get_top_block_from_neighbor(*neighbor_block[0], 0, z);
|
get_top_block_from_neighbor(*neighbor_block[0], 0, z);
|
||||||
weights[type_neighbor] += t;
|
weights[type_neighbor] += t;
|
||||||
}
|
}
|
||||||
@@ -422,7 +423,7 @@ void ChunkGenerator::blend_surface_blocks_borders(
|
|||||||
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
||||||
t = t * t * (3.0f - 2.0f * t);
|
t = t * t * (3.0f - 2.0f * t);
|
||||||
if (t > 0.0f) {
|
if (t > 0.0f) {
|
||||||
uint8_t type_neighbor = get_top_block_from_neighbor(
|
BlockType type_neighbor = get_top_block_from_neighbor(
|
||||||
*neighbor_block[1], CHUNK_SIZE - 1, z);
|
*neighbor_block[1], CHUNK_SIZE - 1, z);
|
||||||
weights[type_neighbor] += t;
|
weights[type_neighbor] += t;
|
||||||
}
|
}
|
||||||
@@ -434,7 +435,7 @@ void ChunkGenerator::blend_surface_blocks_borders(
|
|||||||
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
||||||
t = t * t * (3.0f - 2.0f * t);
|
t = t * t * (3.0f - 2.0f * t);
|
||||||
if (t > 0.0f) {
|
if (t > 0.0f) {
|
||||||
uint8_t type_neighbor =
|
BlockType type_neighbor =
|
||||||
get_top_block_from_neighbor(*neighbor_block[2], x, 0);
|
get_top_block_from_neighbor(*neighbor_block[2], x, 0);
|
||||||
weights[type_neighbor] += t;
|
weights[type_neighbor] += t;
|
||||||
}
|
}
|
||||||
@@ -446,14 +447,14 @@ void ChunkGenerator::blend_surface_blocks_borders(
|
|||||||
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
float t = 1.0f - static_cast<float>(dist) / BLEND_RADIUS;
|
||||||
t = t * t * (3.0f - 2.0f * t);
|
t = t * t * (3.0f - 2.0f * t);
|
||||||
if (t > 0.0f) {
|
if (t > 0.0f) {
|
||||||
uint8_t type_neighbor = get_top_block_from_neighbor(
|
BlockType type_neighbor = get_top_block_from_neighbor(
|
||||||
*neighbor_block[3], x, CHUNK_SIZE - 1);
|
*neighbor_block[3], x, CHUNK_SIZE - 1);
|
||||||
weights[type_neighbor] += t;
|
weights[type_neighbor] += t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find type with maximum total weight
|
// Find type with maximum total weight
|
||||||
uint8_t final_type = type_self;
|
BlockType final_type = type_self;
|
||||||
float max_weight = weights[type_self];
|
float max_weight = weights[type_self];
|
||||||
for (const auto& [type, w] : weights) {
|
for (const auto& [type, w] : weights) {
|
||||||
if (w > max_weight) {
|
if (w > max_weight) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
struct ChunkRenderData {
|
struct ChunkRenderData {
|
||||||
std::array<const std::vector<uint8_t>*, 4> neighbor_block;
|
std::array<const std::vector<BlockType>*, 4> neighbor_block;
|
||||||
Chunk* chunk;
|
Chunk* chunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ void World::init_chunks() {
|
|||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
for (auto& [pos, chunks] : temp_neighbor) {
|
||||||
chunks.gen_phase_five();
|
chunks.gen_phase_five();
|
||||||
}
|
}
|
||||||
std::array<std::optional<std::vector<uint8_t>>, 4> neighbor_block;
|
std::array<std::optional<std::vector<BlockType>>, 4> neighbor_block;
|
||||||
for (auto& [pos, chunks] : m_chunks) {
|
for (auto& [pos, chunks] : m_chunks) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
auto neighbor_pos = pos + CHUNK_DIR[i];
|
||||||
@@ -456,7 +456,7 @@ void World::gen_chunks_internal() {
|
|||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
for (auto& [pos, chunks] : temp_neighbor) {
|
||||||
chunks.gen_phase_five();
|
chunks.gen_phase_five();
|
||||||
}
|
}
|
||||||
std::array<std::optional<std::vector<uint8_t>>, 4> neighbor_blocks_data;
|
std::array<std::optional<std::vector<BlockType>>, 4> neighbor_blocks_data;
|
||||||
for (auto& [pos, chunks] : new_chunks) {
|
for (auto& [pos, chunks] : new_chunks) {
|
||||||
{
|
{
|
||||||
// std::lock_guard lk(m_chunks_mutex);
|
// std::lock_guard lk(m_chunks_mutex);
|
||||||
@@ -477,7 +477,7 @@ void World::gen_chunks_internal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.6f;
|
m_chunk_gen_fraction = 0.6f;
|
||||||
std::array<const std::vector<uint8_t>*, 4> neighbor_block;
|
std::array<const std::vector<BlockType>*, 4> neighbor_block;
|
||||||
for (auto& [pos, chunk] : new_chunks) {
|
for (auto& [pos, chunk] : new_chunks) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
auto it = new_chunks_neighbor.find(pos + CHUNK_DIR[i]);
|
auto it = new_chunks_neighbor.find(pos + CHUNK_DIR[i]);
|
||||||
@@ -784,7 +784,7 @@ void World::update(float delta_time) {
|
|||||||
for (auto& [pos, chunk] : m_chunks) {
|
for (auto& [pos, chunk] : m_chunks) {
|
||||||
if (chunk.is_dirty()) {
|
if (chunk.is_dirty()) {
|
||||||
// the curial fator influence
|
// the curial fator influence
|
||||||
std::array<const std::vector<uint8_t>*, 4> neighbor_block;
|
std::array<const std::vector<BlockType>*, 4> neighbor_block;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
auto it = m_chunks.find(pos + CHUNK_DIR[i]);
|
auto it = m_chunks.find(pos + CHUNK_DIR[i]);
|
||||||
if (it != m_chunks.end()) {
|
if (it != m_chunks.end()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user