From 68694a9c9d7d27d3b79c7b96bb67f56db2f75c45 Mon Sep 17 00:00:00 2001 From: untodesu Date: Thu, 11 Sep 2025 18:18:08 +0500 Subject: Metadata voxels! --- game/shared/world/voxel_registry.cc | 194 ++++++------------------------------ 1 file changed, 32 insertions(+), 162 deletions(-) (limited to 'game/shared/world/voxel_registry.cc') diff --git a/game/shared/world/voxel_registry.cc b/game/shared/world/voxel_registry.cc index b44845e..4c2f360 100644 --- a/game/shared/world/voxel_registry.cc +++ b/game/shared/world/voxel_registry.cc @@ -2,195 +2,65 @@ #include "shared/world/voxel_registry.hh" -#include "core/math/crc64.hh" +static std::uint64_t registry_checksum = 0U; +emhash8::HashMap world::voxel_registry::names; +std::vector> world::voxel_registry::voxels; -std::unordered_map world::voxel_registry::builders = {}; -std::unordered_map world::voxel_registry::names = {}; -std::vector> world::voxel_registry::voxels = {}; - -world::VoxelInfoBuilder::VoxelInfoBuilder(std::string_view name, voxel_type type, bool animated, bool blending) -{ - prototype.name = name; - prototype.type = type; - prototype.animated = animated; - prototype.blending = blending; - - switch(type) { - case voxel_type::CUBE: - prototype.textures.resize(static_cast(voxel_face::CUBE__NR)); - break; - case voxel_type::CROSS: - prototype.textures.resize(static_cast(voxel_face::CROSS__NR)); - break; - case voxel_type::MODEL: - // Custom models should use a different texture - // resource management that is not a voxel atlas - // TODO: actually implement custom models lol - prototype.textures.resize(0); - break; - default: - // Something really bad should happen if we end up here. - // The outside code would static_cast an int to VoxelType - // and possibly fuck a lot of things up to cause this - spdlog::critical("voxel_registry: {}: unknown voxel type {}", name, static_cast(type)); - std::terminate(); - } - - // Physics properties - prototype.touch_type = voxel_touch::SOLID; - prototype.touch_values = glm::fvec3(0.0f, 0.0f, 0.0f); - prototype.surface = voxel_surface::DEFAULT; - - // Things set in future by item_def - prototype.item_pick = NULL_ITEM_ID; -} - -world::VoxelInfoBuilder& world::VoxelInfoBuilder::add_texture_default(std::string_view texture) +static void recalculate_checksum(void) { - default_texture.paths.push_back(std::string(texture)); - return *this; -} + registry_checksum = 0U; -world::VoxelInfoBuilder& world::VoxelInfoBuilder::add_texture(voxel_face face, std::string_view texture) -{ - const auto index = static_cast(face); - prototype.textures[index].paths.push_back(std::string(texture)); - return *this; -} - -world::VoxelInfoBuilder& world::VoxelInfoBuilder::set_touch(voxel_touch type, const glm::fvec3& values) -{ - prototype.touch_type = type; - prototype.touch_values = values; - return *this; + for(const auto& voxel : world::voxel_registry::voxels) { + registry_checksum = voxel->calculate_checksum(registry_checksum); + } } -world::VoxelInfoBuilder& world::VoxelInfoBuilder::set_surface(voxel_surface surface) +world::Voxel* world::voxel_registry::register_voxel(const Voxel& voxel_template) { - prototype.surface = surface; - return *this; -} + assert(voxel_template.get_name().size()); + assert(nullptr == find(voxel_template.get_name())); -voxel_id world::VoxelInfoBuilder::build(void) const -{ - const auto it = world::voxel_registry::names.find(prototype.name); + const auto id = static_cast(voxels.size()); - if(it != world::voxel_registry::names.cend()) { - spdlog::warn("voxel_registry: cannot build {}: name already present", prototype.name); - return it->second; - } + auto voxel = voxel_template.clone(); + voxel->set_id(id); - std::size_t state_count; - - switch(prototype.type) { - case voxel_type::CUBE: - case voxel_type::CROSS: - case voxel_type::MODEL: - state_count = 1; - break; - default: - // Something really bad should happen if we end up here. - // The outside code would static_cast an int to VoxelType - // and possibly fuck a lot of things up to cause this - spdlog::critical("voxel_registry: {}: unknown voxel type {}", prototype.name, static_cast(prototype.type)); - std::terminate(); - } + names.emplace(std::string(voxel_template.get_name()), id); + voxels.push_back(std::move(voxel)); - if((world::voxel_registry::voxels.size() + state_count) >= MAX_VOXEL_ID) { - spdlog::critical("voxel_registry: voxel registry overflow"); - std::terminate(); - } + recalculate_checksum(); - auto new_info = std::make_shared(); - new_info->name = prototype.name; - new_info->type = prototype.type; - new_info->animated = prototype.animated; - new_info->blending = prototype.blending; - - new_info->textures.resize(prototype.textures.size()); - - for(std::size_t i = 0; i < prototype.textures.size(); ++i) { - if(prototype.textures[i].paths.empty()) { - new_info->textures[i].paths = default_texture.paths; - new_info->textures[i].cached_offset = SIZE_MAX; - new_info->textures[i].cached_plane = SIZE_MAX; - } - else { - new_info->textures[i].paths = prototype.textures[i].paths; - new_info->textures[i].cached_offset = SIZE_MAX; - new_info->textures[i].cached_plane = SIZE_MAX; - } - } - - // Physics properties - new_info->touch_type = prototype.touch_type; - new_info->touch_values = prototype.touch_values; - new_info->surface = prototype.surface; - - // Things set in future by item_def - new_info->item_pick = prototype.item_pick; - - // Base voxel identifier offset - new_info->base_voxel = world::voxel_registry::voxels.size() + 1; - - for(std::size_t i = 0; i < state_count; ++i) - world::voxel_registry::voxels.push_back(new_info); - world::voxel_registry::names.insert_or_assign(new_info->name, new_info->base_voxel); - - return new_info->base_voxel; -} - -world::VoxelInfoBuilder& world::voxel_registry::construct(std::string_view name, voxel_type type, bool animated, bool blending) -{ - const auto it = world::voxel_registry::builders.find(std::string(name)); - - if(it != world::voxel_registry::builders.cend()) { - return it->second; - } - else { - return world::voxel_registry::builders.emplace(std::string(name), VoxelInfoBuilder(name, type, animated, blending)).first->second; - } + return voxels.back().get(); } -world::VoxelInfo* world::voxel_registry::find(std::string_view name) +world::Voxel* world::voxel_registry::find(std::string_view name) { - const auto it = world::voxel_registry::names.find(std::string(name)); + const auto it = names.find(name); - if(it != world::voxel_registry::names.cend()) { - return world::voxel_registry::find(it->second); - } - else { + if(it == names.end()) { return nullptr; } + + return voxels[it->second].get(); } -world::VoxelInfo* world::voxel_registry::find(const voxel_id voxel) +world::Voxel* world::voxel_registry::find(voxel_id id) { - if((voxel != NULL_VOXEL_ID) && (voxel <= world::voxel_registry::voxels.size())) { - return world::voxel_registry::voxels[voxel - 1].get(); - } - else { + if(id >= voxels.size()) { return nullptr; } + + return voxels[id].get(); } void world::voxel_registry::purge(void) { - world::voxel_registry::builders.clear(); - world::voxel_registry::names.clear(); - world::voxel_registry::voxels.clear(); + registry_checksum = 0U; + voxels.clear(); + names.clear(); } -std::uint64_t world::voxel_registry::calculate_checksum(void) +std::uint64_t world::voxel_registry::get_checksum(void) { - std::uint64_t result = 0; - - for(const std::shared_ptr& info : world::voxel_registry::voxels) { - result = math::crc64(info->name, result); - result += static_cast(info->type); - result += static_cast(info->base_voxel); - result += info->blending ? 256 : 1; - } - - return result; + return registry_checksum; } -- cgit From e9076f22fe2a49d1cd8933e54b7b00c5dd943269 Mon Sep 17 00:00:00 2001 From: untodesu Date: Fri, 12 Sep 2025 13:33:52 +0500 Subject: It compiles --- game/shared/world/voxel_registry.cc | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'game/shared/world/voxel_registry.cc') diff --git a/game/shared/world/voxel_registry.cc b/game/shared/world/voxel_registry.cc index 4c2f360..97485e6 100644 --- a/game/shared/world/voxel_registry.cc +++ b/game/shared/world/voxel_registry.cc @@ -4,7 +4,7 @@ static std::uint64_t registry_checksum = 0U; emhash8::HashMap world::voxel_registry::names; -std::vector> world::voxel_registry::voxels; +std::vector> world::voxel_registry::voxels; static void recalculate_checksum(void) { @@ -15,17 +15,15 @@ static void recalculate_checksum(void) } } -world::Voxel* world::voxel_registry::register_voxel(const Voxel& voxel_template) +world::Voxel* world::voxel_registry::register_voxel(const VoxelBuilder& builder) { - assert(voxel_template.get_name().size()); - assert(nullptr == find(voxel_template.get_name())); + assert(builder.get_name().size()); + assert(nullptr == find(builder.get_name())); - const auto id = static_cast(voxels.size()); + const auto id = static_cast(1 + voxels.size()); - auto voxel = voxel_template.clone(); - voxel->set_id(id); - - names.emplace(std::string(voxel_template.get_name()), id); + std::unique_ptr voxel(builder.build(id)); + names.emplace(std::string(builder.get_name()), id); voxels.push_back(std::move(voxel)); recalculate_checksum(); @@ -35,7 +33,7 @@ world::Voxel* world::voxel_registry::register_voxel(const Voxel& voxel_template) world::Voxel* world::voxel_registry::find(std::string_view name) { - const auto it = names.find(name); + const auto it = names.find(std::string(name)); if(it == names.end()) { return nullptr; @@ -46,11 +44,11 @@ world::Voxel* world::voxel_registry::find(std::string_view name) world::Voxel* world::voxel_registry::find(voxel_id id) { - if(id >= voxels.size()) { + if(id == NULL_VOXEL_ID || id > voxels.size()) { return nullptr; } - return voxels[id].get(); + return voxels[id - 1].get(); } void world::voxel_registry::purge(void) -- cgit From 73cbcdd6e8c849e32abbf9757e603e6a6654e870 Mon Sep 17 00:00:00 2001 From: untodesu Date: Fri, 12 Sep 2025 14:09:34 +0500 Subject: Metaitems --- game/shared/world/voxel_registry.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'game/shared/world/voxel_registry.cc') diff --git a/game/shared/world/voxel_registry.cc b/game/shared/world/voxel_registry.cc index 97485e6..573a606 100644 --- a/game/shared/world/voxel_registry.cc +++ b/game/shared/world/voxel_registry.cc @@ -11,7 +11,7 @@ static void recalculate_checksum(void) registry_checksum = 0U; for(const auto& voxel : world::voxel_registry::voxels) { - registry_checksum = voxel->calculate_checksum(registry_checksum); + registry_checksum = voxel->get_checksum(registry_checksum); } } @@ -39,7 +39,7 @@ world::Voxel* world::voxel_registry::find(std::string_view name) return nullptr; } - return voxels[it->second].get(); + return voxels[it->second - 1].get(); } world::Voxel* world::voxel_registry::find(voxel_id id) -- cgit