Merge branch 'main' into heightmaps

This commit is contained in:
MihailRis
2024-10-03 19:12:37 +03:00
64 changed files with 3472 additions and 732 deletions
+11
View File
@@ -1,8 +1,10 @@
#include "Block.hpp"
#include <set>
#include <utility>
#include "core_defs.hpp"
#include "data/StructLayout.hpp"
#include "util/stringutil.hpp"
std::string to_string(BlockModel model) {
@@ -102,6 +104,8 @@ Block::Block(const std::string& name)
} {
}
Block::~Block() {}
Block::Block(std::string name, const std::string& texture)
: name(std::move(name)),
textureFaces {texture, texture, texture, texture, texture, texture} {
@@ -138,3 +142,10 @@ void Block::cloneTo(Block& dst) {
dst.inventorySize = inventorySize;
dst.tickInterval = tickInterval;
}
static std::set<std::string, std::less<>> RESERVED_BLOCK_FIELDS {
};
bool Block::isReservedBlockField(std::string_view view) {
return RESERVED_BLOCK_FIELDS.find(view) != RESERVED_BLOCK_FIELDS.end();
}
+11
View File
@@ -9,6 +9,10 @@
#include "maths/aabb.hpp"
#include "typedefs.hpp"
namespace data {
class StructLayout;
}
inline std::string BLOCK_ITEM_SUFFIX = ".item";
inline constexpr uint FACE_MX = 0;
@@ -22,6 +26,8 @@ inline constexpr uint FACE_PZ = 5;
/// complex hitboxes
inline constexpr uint BLOCK_AABB_GRID = 16;
inline constexpr size_t MAX_USER_BLOCK_FIELDS_SIZE = 240;
inline std::string DEFAULT_MATERIAL = "base:stone";
struct block_funcs_set {
@@ -184,6 +190,8 @@ public:
// @brief Block tick interval (1 - 20tps, 2 - 10tps)
uint tickInterval = 1;
std::unique_ptr<data::StructLayout> dataStruct;
/// @brief Runtime indices (content indexing results)
struct {
/// @brief block runtime integer id
@@ -211,8 +219,11 @@ public:
Block(const std::string& name);
Block(std::string name, const std::string& texture);
Block(const Block&) = delete;
~Block();
void cloneTo(Block& dst);
static bool isReservedBlockField(std::string_view view);
};
inline glm::ivec3 get_ground_direction(const Block& def, int rotation) {
+17 -34
View File
@@ -2,9 +2,10 @@
#include <utility>
#include "content/ContentLUT.hpp"
#include "content/ContentReport.hpp"
#include "items/Inventory.hpp"
#include "lighting/Lightmap.hpp"
#include "util/data_io.hpp"
#include "voxel.hpp"
Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos) {
@@ -53,7 +54,7 @@ void Chunk::removeBlockInventory(uint x, uint y, uint z) {
}
}
void Chunk::setBlockInventories(chunk_inventories_map map) {
void Chunk::setBlockInventories(ChunkInventoriesMap map) {
inventories = std::move(map);
}
@@ -78,59 +79,41 @@ std::unique_ptr<Chunk> Chunk::clone() const {
/**
Current chunk format:
- byte-order: big-endian
- [don't panic!] first and second bytes are separated for RLE efficiency
- byte-order: little-endian
```cpp
uint8_t voxel_id_first_byte[CHUNK_VOL];
uint8_t voxel_id_second_byte[CHUNK_VOL];
uint8_t voxel_states_first_byte[CHUNK_VOL];
uint8_t voxel_states_second_byte[CHUNK_VOL];
uint16_t voxel_id[CHUNK_VOL];
uint16_t voxel_states[CHUNK_VOL];
```
Total size: (CHUNK_VOL * 4) bytes
*/
std::unique_ptr<ubyte[]> Chunk::encode() const {
auto buffer = std::make_unique<ubyte[]>(CHUNK_DATA_LEN);
auto dst = reinterpret_cast<uint16_t*>(buffer.get());
for (uint i = 0; i < CHUNK_VOL; i++) {
buffer[i] = voxels[i].id >> 8;
buffer[CHUNK_VOL + i] = voxels[i].id & 0xFF;
blockstate_t state = blockstate2int(voxels[i].state);
buffer[CHUNK_VOL * 2 + i] = state >> 8;
buffer[CHUNK_VOL * 3 + i] = state & 0xFF;
dst[i] = dataio::h2le(voxels[i].id);
dst[CHUNK_VOL + i] = dataio::h2le(blockstate2int(voxels[i].state));
}
return buffer;
}
bool Chunk::decode(const ubyte* data) {
auto src = reinterpret_cast<const uint16_t*>(data);
for (uint i = 0; i < CHUNK_VOL; i++) {
voxel& vox = voxels[i];
ubyte bid1 = data[i];
ubyte bid2 = data[CHUNK_VOL + i];
ubyte bst1 = data[CHUNK_VOL * 2 + i];
ubyte bst2 = data[CHUNK_VOL * 3 + i];
vox.id =
(static_cast<blockid_t>(bid1) << 8) | static_cast<blockid_t>(bid2);
vox.state = int2blockstate(
(static_cast<blockstate_t>(bst1) << 8) |
static_cast<blockstate_t>(bst2)
);
vox.id = dataio::le2h(src[i]);
vox.state = int2blockstate(dataio::le2h(src[CHUNK_VOL + i]));
}
return true;
}
void Chunk::convert(ubyte* data, const ContentLUT* lut) {
void Chunk::convert(ubyte* data, const ContentReport* report) {
auto buffer = reinterpret_cast<uint16_t*>(data);
for (uint i = 0; i < CHUNK_VOL; i++) {
// see encode method to understand what the hell is going on here
blockid_t id =
((static_cast<blockid_t>(data[i]) << 8) |
static_cast<blockid_t>(data[CHUNK_VOL + i]));
blockid_t replacement = lut->blocks.getId(id);
data[i] = replacement >> 8;
data[CHUNK_VOL + i] = replacement & 0xFF;
blockid_t id = dataio::le2h(buffer[i]);
blockid_t replacement = report->blocks.getId(id);
buffer[i] = dataio::h2le(replacement);
}
}
+13 -6
View File
@@ -7,17 +7,19 @@
#include "constants.hpp"
#include "lighting/Lightmap.hpp"
#include "util/SmallHeap.hpp"
#include "voxel.hpp"
inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL * 4;
class Lightmap;
class ContentLUT;
class ContentReport;
class Inventory;
using chunk_inventories_map =
using ChunkInventoriesMap =
std::unordered_map<uint, std::shared_ptr<Inventory>>;
using BlocksMetadata = util::SmallHeap<uint16_t, uint8_t>;
class Chunk {
public:
int x, z;
@@ -32,10 +34,13 @@ public:
bool unsaved : 1;
bool loadedLights : 1;
bool entities : 1;
bool blocksData : 1;
} flags {};
/// @brief Block inventories map where key is index of block in voxels array
chunk_inventories_map inventories;
ChunkInventoriesMap inventories;
/// @brief Blocks metadata heap
BlocksMetadata blocksMetadata;
Chunk(int x, int z);
@@ -52,7 +57,7 @@ public:
std::shared_ptr<Inventory> inventory, uint x, uint y, uint z
);
void removeBlockInventory(uint x, uint y, uint z);
void setBlockInventories(chunk_inventories_map map);
void setBlockInventories(ChunkInventoriesMap map);
/// @return inventory bound to the given block or nullptr
std::shared_ptr<Inventory> getBlockInventory(uint x, uint y, uint z) const;
@@ -62,10 +67,12 @@ public:
flags.unsaved = true;
}
/// @brief Encode chunk to bytes array of size CHUNK_DATA_LEN
/// @see /doc/specs/region_voxels_chunk_spec.md
std::unique_ptr<ubyte[]> encode() const;
/// @return true if all is fine
bool decode(const ubyte* data);
static void convert(ubyte* data, const ContentLUT* lut);
static void convert(ubyte* data, const ContentReport* report);
};
+9
View File
@@ -6,6 +6,7 @@
#include <algorithm>
#include <vector>
#include "data/StructLayout.hpp"
#include "coders/byte_utils.hpp"
#include "coders/json.hpp"
#include "content/Content.hpp"
@@ -363,6 +364,7 @@ void Chunks::set(
}
int lx = x - cx * CHUNK_W;
int lz = z - cz * CHUNK_D;
size_t index = vox_index(lx, y, lz);
// block finalization
voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
@@ -373,6 +375,13 @@ void Chunks::set(
if (prevdef.rt.extended && !vox.state.segment) {
eraseSegments(prevdef, vox.state, x, y, z);
}
if (prevdef.dataStruct) {
if (auto found = chunk->blocksMetadata.find(index)) {
chunk->blocksMetadata.free(found);
chunk->flags.unsaved = true;
chunk->flags.blocksData = true;
}
}
// block initialization
const auto& newdef = indices->blocks.require(id);
+4 -5
View File
@@ -59,8 +59,7 @@ std::shared_ptr<Chunk> ChunksStorage::create(int x, int z) {
auto chunk = std::make_shared<Chunk>(x, z);
store(chunk);
auto data = regions.getChunk(chunk->x, chunk->z);
if (data) {
if (auto data = regions.getVoxels(chunk->x, chunk->z)) {
chunk->decode(data.get());
auto invs = regions.fetchInventories(chunk->x, chunk->z);
@@ -78,17 +77,17 @@ std::shared_ptr<Chunk> ChunksStorage::create(int x, int z) {
}
verifyLoadedChunk(level->content->getIndices(), chunk.get());
}
auto lights = regions.getLights(chunk->x, chunk->z);
if (lights) {
if (auto lights = regions.getLights(chunk->x, chunk->z)) {
chunk->lightmap.set(lights.get());
chunk->flags.loadedLights = true;
}
chunk->blocksMetadata = regions.getBlocksData(chunk->x, chunk->z);
return chunk;
}
// reduce nesting on next modification
// 25.06.2024: not now
// TODO: move to Chunks for performance improvement
void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const {
const Content* content = level->content;
auto indices = content->getIndices();