From f40d09cb8f712e87691af4912f3630d92d692779 Mon Sep 17 00:00:00 2001 From: untodesu Date: Thu, 11 Dec 2025 15:14:26 +0500 Subject: Shuffle stuff around - Use the new and improved hierarchy I figured out when making Prospero chat - Re-add NSIS scripts, again from Prospero - Update most build and utility scripts with their most recent versions --- game/shared/world/CMakeLists.txt | 20 --- game/shared/world/chunk.cc | 72 --------- game/shared/world/chunk.hh | 43 ------ game/shared/world/chunk_aabb.hh | 10 -- game/shared/world/dimension.cc | 187 ----------------------- game/shared/world/dimension.hh | 101 ------------- game/shared/world/feature.cc | 75 ---------- game/shared/world/feature.hh | 25 ---- game/shared/world/item.cc | 55 ------- game/shared/world/item.hh | 84 ----------- game/shared/world/item_registry.cc | 68 --------- game/shared/world/item_registry.hh | 26 ---- game/shared/world/ray_dda.cc | 107 -------------- game/shared/world/ray_dda.hh | 38 ----- game/shared/world/voxel.cc | 149 ------------------- game/shared/world/voxel.hh | 286 ------------------------------------ game/shared/world/voxel_registry.cc | 64 -------- game/shared/world/voxel_registry.hh | 26 ---- game/shared/world/voxel_storage.cc | 48 ------ game/shared/world/voxel_storage.hh | 20 --- 20 files changed, 1504 deletions(-) delete mode 100644 game/shared/world/CMakeLists.txt delete mode 100644 game/shared/world/chunk.cc delete mode 100644 game/shared/world/chunk.hh delete mode 100644 game/shared/world/chunk_aabb.hh delete mode 100644 game/shared/world/dimension.cc delete mode 100644 game/shared/world/dimension.hh delete mode 100644 game/shared/world/feature.cc delete mode 100644 game/shared/world/feature.hh delete mode 100644 game/shared/world/item.cc delete mode 100644 game/shared/world/item.hh delete mode 100644 game/shared/world/item_registry.cc delete mode 100644 game/shared/world/item_registry.hh delete mode 100644 game/shared/world/ray_dda.cc delete mode 100644 game/shared/world/ray_dda.hh delete mode 100644 game/shared/world/voxel.cc delete mode 100644 game/shared/world/voxel.hh delete mode 100644 game/shared/world/voxel_registry.cc delete mode 100644 game/shared/world/voxel_registry.hh delete mode 100644 game/shared/world/voxel_storage.cc delete mode 100644 game/shared/world/voxel_storage.hh (limited to 'game/shared/world') diff --git a/game/shared/world/CMakeLists.txt b/game/shared/world/CMakeLists.txt deleted file mode 100644 index db3f370..0000000 --- a/game/shared/world/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -target_sources(shared PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/chunk_aabb.hh" - "${CMAKE_CURRENT_LIST_DIR}/chunk.cc" - "${CMAKE_CURRENT_LIST_DIR}/chunk.hh" - "${CMAKE_CURRENT_LIST_DIR}/dimension.cc" - "${CMAKE_CURRENT_LIST_DIR}/dimension.hh" - "${CMAKE_CURRENT_LIST_DIR}/feature.cc" - "${CMAKE_CURRENT_LIST_DIR}/feature.hh" - "${CMAKE_CURRENT_LIST_DIR}/item_registry.cc" - "${CMAKE_CURRENT_LIST_DIR}/item_registry.hh" - "${CMAKE_CURRENT_LIST_DIR}/item.cc" - "${CMAKE_CURRENT_LIST_DIR}/item.hh" - "${CMAKE_CURRENT_LIST_DIR}/ray_dda.cc" - "${CMAKE_CURRENT_LIST_DIR}/ray_dda.hh" - "${CMAKE_CURRENT_LIST_DIR}/voxel_registry.cc" - "${CMAKE_CURRENT_LIST_DIR}/voxel_registry.hh" - "${CMAKE_CURRENT_LIST_DIR}/voxel_storage.cc" - "${CMAKE_CURRENT_LIST_DIR}/voxel_storage.hh" - "${CMAKE_CURRENT_LIST_DIR}/voxel.cc" - "${CMAKE_CURRENT_LIST_DIR}/voxel.hh") diff --git a/game/shared/world/chunk.cc b/game/shared/world/chunk.cc deleted file mode 100644 index f8f7b93..0000000 --- a/game/shared/world/chunk.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/chunk.hh" - -#include "shared/world/voxel_registry.hh" - -#include "shared/coord.hh" - -world::Chunk::Chunk(entt::entity entity, Dimension* dimension) -{ - m_entity = entity; - m_dimension = dimension; - m_voxels.fill(NULL_VOXEL_ID); - m_biome = BIOME_VOID; -} - -const world::Voxel* world::Chunk::get_voxel(const local_pos& lpos) const -{ - return get_voxel(coord::to_index(lpos)); -} - -const world::Voxel* world::Chunk::get_voxel(const std::size_t index) const -{ - if(index >= CHUNK_VOLUME) { - return nullptr; - } - - return voxel_registry::find(m_voxels[index]); -} - -void world::Chunk::set_voxel(const Voxel* voxel, const local_pos& lpos) -{ - set_voxel(voxel, coord::to_index(lpos)); -} - -void world::Chunk::set_voxel(const Voxel* voxel, const std::size_t index) -{ - if(index < CHUNK_VOLUME) { - m_voxels[index] = voxel ? voxel->get_id() : NULL_VOXEL_ID; - return; - } -} - -const world::VoxelStorage& world::Chunk::get_voxels(void) const -{ - return m_voxels; -} - -void world::Chunk::set_voxels(const VoxelStorage& voxels) -{ - m_voxels = voxels; -} - -unsigned int world::Chunk::get_biome(void) const -{ - return m_biome; -} - -void world::Chunk::set_biome(unsigned int biome) -{ - m_biome = biome; -} - -entt::entity world::Chunk::get_entity(void) const -{ - return m_entity; -} - -world::Dimension* world::Chunk::get_dimension(void) const -{ - return m_dimension; -} diff --git a/game/shared/world/chunk.hh b/game/shared/world/chunk.hh deleted file mode 100644 index 4a1e557..0000000 --- a/game/shared/world/chunk.hh +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "shared/world/voxel_storage.hh" - -#include "shared/types.hh" - -constexpr static unsigned int BIOME_VOID = 0U; - -namespace world -{ -class Dimension; -class Voxel; -} // namespace world - -namespace world -{ -class Chunk final { -public: - explicit Chunk(entt::entity entity, Dimension* dimension); - virtual ~Chunk(void) = default; - - const Voxel* get_voxel(const local_pos& lpos) const; - const Voxel* get_voxel(const std::size_t index) const; - - void set_voxel(const Voxel* voxel, const local_pos& lpos); - void set_voxel(const Voxel* voxel, const std::size_t index); - - const VoxelStorage& get_voxels(void) const; - void set_voxels(const VoxelStorage& voxels); - - unsigned int get_biome(void) const; - void set_biome(unsigned int biome); - - entt::entity get_entity(void) const; - Dimension* get_dimension(void) const; - -private: - entt::entity m_entity; - Dimension* m_dimension; - VoxelStorage m_voxels; - unsigned int m_biome; -}; -} // namespace world diff --git a/game/shared/world/chunk_aabb.hh b/game/shared/world/chunk_aabb.hh deleted file mode 100644 index d926b55..0000000 --- a/game/shared/world/chunk_aabb.hh +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "core/math/aabb.hh" - -#include "shared/types.hh" - -namespace world -{ -using ChunkAABB = math::AABB; -} // namespace world diff --git a/game/shared/world/dimension.cc b/game/shared/world/dimension.cc deleted file mode 100644 index 31a19af..0000000 --- a/game/shared/world/dimension.cc +++ /dev/null @@ -1,187 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/dimension.hh" - -#include "shared/world/chunk.hh" -#include "shared/world/voxel_registry.hh" - -#include "shared/coord.hh" -#include "shared/globals.hh" - -world::Dimension::Dimension(std::string_view name, float gravity) -{ - m_name = name; - m_gravity = gravity; -} - -world::Dimension::~Dimension(void) -{ - for(const auto it : m_chunkmap) - delete it.second; - entities.clear(); - chunks.clear(); -} - -std::string_view world::Dimension::get_name(void) const -{ - return m_name; -} - -float world::Dimension::get_gravity(void) const -{ - return m_gravity; -} - -world::Chunk* world::Dimension::create_chunk(const chunk_pos& cpos) -{ - auto it = m_chunkmap.find(cpos); - - if(it != m_chunkmap.cend()) { - // Chunk already exists - return it->second; - } - - auto entity = chunks.create(); - auto chunk = new Chunk(entity, this); - - auto& component = chunks.emplace(entity); - component.chunk = chunk; - component.cpos = cpos; - - ChunkCreateEvent event; - event.dimension = this; - event.chunk = chunk; - event.cpos = cpos; - - globals::dispatcher.trigger(event); - - return m_chunkmap.insert_or_assign(cpos, std::move(chunk)).first->second; -} - -world::Chunk* world::Dimension::find_chunk(entt::entity entity) const -{ - if(chunks.valid(entity)) { - return chunks.get(entity).chunk; - } - else { - return nullptr; - } -} - -world::Chunk* world::Dimension::find_chunk(const chunk_pos& cpos) const -{ - auto it = m_chunkmap.find(cpos); - - if(it != m_chunkmap.cend()) { - return it->second; - } - else { - return nullptr; - } -} - -void world::Dimension::remove_chunk(entt::entity entity) -{ - if(chunks.valid(entity)) { - auto& component = chunks.get(entity); - m_chunkmap.erase(component.cpos); - chunks.destroy(entity); - } -} - -void world::Dimension::remove_chunk(const chunk_pos& cpos) -{ - auto it = m_chunkmap.find(cpos); - - if(it != m_chunkmap.cend()) { - chunks.destroy(it->second->get_entity()); - m_chunkmap.erase(it); - } -} - -void world::Dimension::remove_chunk(Chunk* chunk) -{ - if(chunk) { - const auto& component = chunks.get(chunk->get_entity()); - m_chunkmap.erase(component.cpos); - chunks.destroy(chunk->get_entity()); - } -} - -const world::Voxel* world::Dimension::get_voxel(const voxel_pos& vpos) const -{ - auto cpos = coord::to_chunk(vpos); - auto lpos = coord::to_local(vpos); - - if(auto chunk = find_chunk(cpos)) { - return chunk->get_voxel(lpos); - } - - return nullptr; -} - -const world::Voxel* world::Dimension::get_voxel(const chunk_pos& cpos, const local_pos& lpos) const -{ - // This allows accessing get_voxel with negative - // local coordinates that usually would result in an - // out-of-range values; this is useful for per-voxel update logic - return get_voxel(coord::to_voxel(cpos, lpos)); -} - -bool world::Dimension::set_voxel(const Voxel* voxel, const voxel_pos& vpos) -{ - auto cpos = coord::to_chunk(vpos); - auto lpos = coord::to_local(vpos); - - if(auto chunk = find_chunk(cpos)) { - if(auto old_voxel = chunk->get_voxel(lpos)) { - if(old_voxel != voxel) { - // Notify the old voxel that it is - // being replaced with a different voxel - old_voxel->on_remove(this, vpos); - } - } - - chunk->set_voxel(voxel, lpos); - - if(voxel) { - // If we're not placing air, notify the - // new voxel that it has been placed - voxel->on_place(this, vpos); - } - - VoxelSetEvent event; - event.dimension = this; - event.voxel = voxel; - event.cpos = cpos; - event.lpos = lpos; - event.chunk = chunk; - - globals::dispatcher.trigger(event); - - return true; - } - - return false; -} - -bool world::Dimension::set_voxel(const Voxel* voxel, const chunk_pos& cpos, const local_pos& lpos) -{ - // This allows accessing set_voxel with negative - // local coordinates that usually would result in an - // out-of-range values; this is useful for per-voxel update logic - return set_voxel(voxel, coord::to_voxel(cpos, lpos)); -} - -void world::Dimension::init(io::ConfigMap& config) -{ -} - -void world::Dimension::init_late(std::uint64_t global_seed) -{ -} - -bool world::Dimension::generate(const chunk_pos& cpos, VoxelStorage& voxels) -{ - return false; -} diff --git a/game/shared/world/dimension.hh b/game/shared/world/dimension.hh deleted file mode 100644 index 58e0765..0000000 --- a/game/shared/world/dimension.hh +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include "shared/const.hh" -#include "shared/types.hh" - -namespace io -{ -class ConfigMap; -} // namespace io - -namespace world -{ -class Chunk; -class Voxel; -class VoxelStorage; -} // namespace world - -namespace world -{ -using dimension_entropy_map = std::array; -using dimension_height_map = std::array; -} // namespace world - -namespace world -{ -class Dimension { -public: - explicit Dimension(std::string_view name, float gravity); - virtual ~Dimension(void); - - std::string_view get_name(void) const; - float get_gravity(void) const; - -public: - Chunk* create_chunk(const chunk_pos& cpos); - Chunk* find_chunk(entt::entity entity) const; - Chunk* find_chunk(const chunk_pos& cpos) const; - - void remove_chunk(entt::entity entity); - void remove_chunk(const chunk_pos& cpos); - void remove_chunk(Chunk* chunk); - -public: - const Voxel* get_voxel(const voxel_pos& vpos) const; - const Voxel* get_voxel(const chunk_pos& cpos, const local_pos& lpos) const; - - bool set_voxel(const Voxel* voxel, const voxel_pos& vpos); - bool set_voxel(const Voxel* voxel, const chunk_pos& cpos, const local_pos& lpos); - -public: - virtual void init(io::ConfigMap& config); - virtual void init_late(std::uint64_t global_seed); - virtual bool generate(const chunk_pos& cpos, VoxelStorage& voxels); - -public: - entt::registry chunks; - entt::registry entities; - -private: - std::string m_name; - emhash8::HashMap m_chunkmap; - float m_gravity; -}; -} // namespace world - -namespace world -{ -struct ChunkComponent final { - chunk_pos cpos; - Chunk* chunk; -}; -} // namespace world - -namespace world -{ -struct ChunkCreateEvent final { - Dimension* dimension; - chunk_pos cpos; - Chunk* chunk; -}; - -struct ChunkDestroyEvent final { - Dimension* dimension; - chunk_pos cpos; - Chunk* chunk; -}; - -struct ChunkUpdateEvent final { - Dimension* dimension; - chunk_pos cpos; - Chunk* chunk; -}; - -struct VoxelSetEvent final { - Dimension* dimension; - const Voxel* voxel; - chunk_pos cpos; - local_pos lpos; - Chunk* chunk; -}; -} // namespace world diff --git a/game/shared/world/feature.cc b/game/shared/world/feature.cc deleted file mode 100644 index 8fe95f1..0000000 --- a/game/shared/world/feature.cc +++ /dev/null @@ -1,75 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/feature.hh" - -#include "shared/world/chunk.hh" -#include "shared/world/dimension.hh" -#include "shared/world/voxel.hh" - -#include "shared/coord.hh" - -void world::Feature::place(const voxel_pos& vpos, Dimension* dimension) const -{ - for(const auto [rpos, voxel, overwrite] : (*this)) { - auto it_vpos = vpos + rpos; - auto it_cpos = coord::to_chunk(it_vpos); - - if(auto chunk = dimension->create_chunk(it_cpos)) { - auto it_lpos = coord::to_local(it_vpos); - auto it_index = coord::to_index(it_lpos); - - if(chunk->get_voxel(it_index) && !overwrite) { - // There is something in the way - // and the called intentionally requested - // we do not force feature to overwrite voxels - continue; - } - - chunk->set_voxel(voxel, it_index); - } - } -} - -void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, Chunk& chunk) const -{ - for(const auto [rpos, voxel, overwrite] : (*this)) { - auto it_vpos = vpos + rpos; - auto it_cpos = coord::to_chunk(it_vpos); - - if(it_cpos == cpos) { - auto it_lpos = coord::to_local(it_vpos); - auto it_index = coord::to_index(it_lpos); - - if(chunk.get_voxel(it_index) && !overwrite) { - // There is something in the way - // and the called intentionally requested - // we do not force feature to overwrite voxels - continue; - } - - chunk.set_voxel(voxel, it_index); - } - } -} - -void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const -{ - for(const auto [rpos, voxel, overwrite] : (*this)) { - auto it_vpos = vpos + rpos; - auto it_cpos = coord::to_chunk(it_vpos); - - if(it_cpos == cpos) { - auto it_lpos = coord::to_local(it_vpos); - auto it_index = coord::to_index(it_lpos); - - if(voxels[it_index] && !overwrite) { - // There is something in the way - // and the called intentionally requested - // we do not force feature to overwrite voxels - continue; - } - - voxels[it_index] = voxel ? voxel->get_id() : NULL_VOXEL_ID; - } - } -} diff --git a/game/shared/world/feature.hh b/game/shared/world/feature.hh deleted file mode 100644 index a543632..0000000 --- a/game/shared/world/feature.hh +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "shared/types.hh" - -namespace world -{ -class Chunk; -class Dimension; -class Voxel; -class VoxelStorage; -} // namespace world - -namespace world -{ -class Feature final : public std::vector> { -public: - Feature(void) = default; - virtual ~Feature(void) = default; - -public: - void place(const voxel_pos& vpos, Dimension* dimension) const; - void place(const voxel_pos& vpos, const chunk_pos& cpos, Chunk& chunk) const; - void place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const; -}; -} // namespace world diff --git a/game/shared/world/item.cc b/game/shared/world/item.cc deleted file mode 100644 index 5e60609..0000000 --- a/game/shared/world/item.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/item.hh" - -#include "core/math/crc64.hh" - -#include "shared/world/voxel.hh" - -world::Item::Item(const Item& source, item_id id) noexcept : Item(source) -{ - m_id = id; -} - -void world::Item::set_cached_texture(resource_ptr texture) const noexcept -{ - m_cached_texture = std::move(texture); -} - -std::uint64_t world::Item::get_checksum(std::uint64_t combine) const -{ - combine = math::crc64(m_name.data(), m_name.size(), combine); - combine = math::crc64(m_texture.data(), m_texture.size(), combine); - - std::uint32_t id = m_place_voxel ? m_place_voxel->get_id() : NULL_VOXEL_ID; - combine = math::crc64(&id, sizeof(id), combine); - - return combine; -} - -world::ItemBuilder::ItemBuilder(std::string_view name) -{ - set_name(name); -} - -void world::ItemBuilder::set_name(std::string_view name) -{ - assert(name.size()); - - m_name = name; -} - -void world::ItemBuilder::set_texture(std::string_view texture) -{ - m_texture = texture; -} - -void world::ItemBuilder::set_place_voxel(const Voxel* place_voxel) -{ - m_place_voxel = place_voxel; -} - -std::unique_ptr world::ItemBuilder::build(item_id id) const -{ - return std::make_unique(*this, id); -} diff --git a/game/shared/world/item.hh b/game/shared/world/item.hh deleted file mode 100644 index ffa7f5c..0000000 --- a/game/shared/world/item.hh +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include "core/resource/resource.hh" - -#include "shared/types.hh" - -// This resource is only defined client-side and -// resource_ptr should remain set to null -// anywhere else in the shared and server code -struct TextureGUI; - -namespace world -{ -class Voxel; -} // namespace world - -namespace world -{ -class Item { -public: - Item(void) = default; - explicit Item(const Item& source, item_id id) noexcept; - - constexpr std::string_view get_name(void) const noexcept; - constexpr item_id get_id(void) const noexcept; - - constexpr std::string_view get_texture(void) const noexcept; - constexpr const Voxel* get_place_voxel(void) const noexcept; - - constexpr resource_ptr& get_cached_texture(void) const noexcept; - void set_cached_texture(resource_ptr texture) const noexcept; - - std::uint64_t get_checksum(std::uint64_t combine = 0U) const; - -protected: - std::string m_name; - item_id m_id { NULL_ITEM_ID }; - - std::string m_texture; - const Voxel* m_place_voxel { nullptr }; - - mutable resource_ptr m_cached_texture; // Client-side only -}; -} // namespace world - -namespace world -{ -class ItemBuilder final : public Item { -public: - explicit ItemBuilder(std::string_view name); - - void set_name(std::string_view name); - - void set_texture(std::string_view texture); - void set_place_voxel(const Voxel* place_voxel); - - std::unique_ptr build(item_id id) const; -}; -} // namespace world - -constexpr std::string_view world::Item::get_name(void) const noexcept -{ - return m_name; -} - -constexpr item_id world::Item::get_id(void) const noexcept -{ - return m_id; -} - -constexpr std::string_view world::Item::get_texture(void) const noexcept -{ - return m_texture; -} - -constexpr const world::Voxel* world::Item::get_place_voxel(void) const noexcept -{ - return m_place_voxel; -} - -constexpr resource_ptr& world::Item::get_cached_texture(void) const noexcept -{ - return m_cached_texture; -} diff --git a/game/shared/world/item_registry.cc b/game/shared/world/item_registry.cc deleted file mode 100644 index 4e0932c..0000000 --- a/game/shared/world/item_registry.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/item_registry.hh" - -#include "core/math/crc64.hh" - -#include "shared/world/voxel_registry.hh" - -static std::uint64_t registry_checksum = 0U; -std::unordered_map world::item_registry::names = {}; -std::vector> world::item_registry::items = {}; - -static void recalculate_checksum(void) -{ - registry_checksum = 0U; - - for(const auto& item : world::item_registry::items) { - registry_checksum = item->get_checksum(registry_checksum); - } -} - -world::Item* world::item_registry::register_item(const ItemBuilder& builder) -{ - assert(builder.get_name().size()); - assert(nullptr == find(builder.get_name())); - - const auto id = static_cast(1 + items.size()); - - std::unique_ptr item(builder.build(id)); - names.emplace(std::string(builder.get_name()), id); - items.push_back(std::move(item)); - - recalculate_checksum(); - - return items.back().get(); -} - -world::Item* world::item_registry::find(std::string_view name) -{ - const auto it = names.find(std::string(name)); - - if(it == names.end()) { - return nullptr; - } - - return items[it->second - 1].get(); -} - -world::Item* world::item_registry::find(const item_id item) -{ - if(item == NULL_ITEM_ID || item > items.size()) { - return nullptr; - } - - return items[item - 1].get(); -} - -void world::item_registry::purge(void) -{ - registry_checksum = 0U; - items.clear(); - names.clear(); -} - -std::uint64_t world::item_registry::get_checksum(void) -{ - return registry_checksum; -} diff --git a/game/shared/world/item_registry.hh b/game/shared/world/item_registry.hh deleted file mode 100644 index b4c9fda..0000000 --- a/game/shared/world/item_registry.hh +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "shared/world/item.hh" - -namespace world::item_registry -{ -extern std::unordered_map names; -extern std::vector> items; -} // namespace world::item_registry - -namespace world::item_registry -{ -Item* register_item(const ItemBuilder& builder); -Item* find(std::string_view name); -Item* find(const item_id item); -} // namespace world::item_registry - -namespace world::item_registry -{ -void purge(void); -} // namespace world::item_registry - -namespace world::item_registry -{ -std::uint64_t get_checksum(void); -} // namespace world::item_registry diff --git a/game/shared/world/ray_dda.cc b/game/shared/world/ray_dda.cc deleted file mode 100644 index af1ab3b..0000000 --- a/game/shared/world/ray_dda.cc +++ /dev/null @@ -1,107 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/ray_dda.hh" - -#include "shared/world/dimension.hh" - -#include "shared/coord.hh" - -world::RayDDA::RayDDA(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, - const glm::fvec3& direction) -{ - reset(dimension, start_chunk, start_fpos, direction); -} - -world::RayDDA::RayDDA(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, - const glm::fvec3& direction) -{ - reset(dimension, start_chunk, start_fpos, direction); -} - -void world::RayDDA::reset(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, - const glm::fvec3& direction) -{ - this->dimension = dimension; - this->start_chunk = start_chunk; - this->start_fpos = start_fpos; - this->direction = direction; - - this->delta_dist.x = direction.x ? glm::abs(1.0f / direction.x) : std::numeric_limits::max(); - this->delta_dist.y = direction.y ? glm::abs(1.0f / direction.y) : std::numeric_limits::max(); - this->delta_dist.z = direction.z ? glm::abs(1.0f / direction.z) : std::numeric_limits::max(); - - this->distance = 0.0f; - this->vpos = coord::to_voxel(start_chunk, start_fpos); - this->vnormal = voxel_pos(0, 0, 0); - - // Need this for initial direction calculations - auto lpos = coord::to_local(start_fpos); - - if(direction.x < 0.0f) { - this->side_dist.x = this->delta_dist.x * (start_fpos.x - lpos.x); - this->vstep.x = voxel_pos::value_type(-1); - } - else { - this->side_dist.x = this->delta_dist.x * (lpos.x + 1.0f - start_fpos.x); - this->vstep.x = voxel_pos::value_type(+1); - } - - if(direction.y < 0.0f) { - this->side_dist.y = this->delta_dist.y * (start_fpos.y - lpos.y); - this->vstep.y = voxel_pos::value_type(-1); - } - else { - this->side_dist.y = this->delta_dist.y * (lpos.y + 1.0f - start_fpos.y); - this->vstep.y = voxel_pos::value_type(+1); - } - - if(direction.z < 0.0f) { - this->side_dist.z = this->delta_dist.z * (start_fpos.z - lpos.z); - this->vstep.z = voxel_pos::value_type(-1); - } - else { - this->side_dist.z = this->delta_dist.z * (lpos.z + 1.0f - start_fpos.z); - this->vstep.z = voxel_pos::value_type(+1); - } -} - -void world::RayDDA::reset(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, - const glm::fvec3& direction) -{ - reset(&dimension, start_chunk, start_fpos, direction); -} - -const world::Voxel* world::RayDDA::step(void) -{ - if(side_dist.x < side_dist.z) { - if(side_dist.x < side_dist.y) { - vnormal = voxel_pos(-vstep.x, 0, 0); - distance = side_dist.x; - side_dist.x += delta_dist.x; - vpos.x += vstep.x; - } - else { - vnormal = voxel_pos(0, -vstep.y, 0); - distance = side_dist.y; - side_dist.y += delta_dist.y; - vpos.y += vstep.y; - } - } - else { - if(side_dist.z < side_dist.y) { - vnormal = voxel_pos(0, 0, -vstep.z); - distance = side_dist.z; - side_dist.z += delta_dist.z; - vpos.z += vstep.z; - } - else { - vnormal = voxel_pos(0, -vstep.y, 0); - distance = side_dist.y; - side_dist.y += delta_dist.y; - vpos.y += vstep.y; - } - } - - // This is slower than I want it to be - return dimension->get_voxel(vpos); -} diff --git a/game/shared/world/ray_dda.hh b/game/shared/world/ray_dda.hh deleted file mode 100644 index 110e3d4..0000000 --- a/game/shared/world/ray_dda.hh +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "shared/types.hh" - -namespace world -{ -class Dimension; -class Voxel; -} // namespace world - -namespace world -{ -class RayDDA final { -public: - RayDDA(void) = default; - explicit RayDDA(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - explicit RayDDA(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - - void reset(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - void reset(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - - const Voxel* step(void); - -public: - const Dimension* dimension; - chunk_pos start_chunk; - glm::fvec3 start_fpos; - glm::fvec3 direction; - - glm::fvec3 delta_dist; - glm::fvec3 side_dist; - voxel_pos vstep; - - double distance; - voxel_pos vnormal; - voxel_pos vpos; -}; -} // namespace world diff --git a/game/shared/world/voxel.cc b/game/shared/world/voxel.cc deleted file mode 100644 index 21fe62c..0000000 --- a/game/shared/world/voxel.cc +++ /dev/null @@ -1,149 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/voxel.hh" - -#include "core/math/crc64.hh" - -#include "shared/world/dimension.hh" - -world::Voxel::Voxel(const Voxel& source, voxel_id id) noexcept : Voxel(source) -{ - m_id = id; -} - -void world::Voxel::on_place(Dimension* dimension, const voxel_pos& vpos) const -{ - if(m_on_place) { - m_on_place(dimension, vpos); - } -} - -void world::Voxel::on_remove(Dimension* dimension, const voxel_pos& vpos) const -{ - if(m_on_remove) { - m_on_remove(dimension, vpos); - } -} - -void world::Voxel::on_tick(Dimension* dimension, const voxel_pos& vpos) const -{ - if(m_on_tick) { - m_on_tick(dimension, vpos); - } -} - -std::size_t world::Voxel::get_random_texture_index(VoxelFace face, const voxel_pos& vpos) const -{ - const auto& textures = get_face_textures(face); - - assert(textures.size()); - - std::uint64_t hash = 0U; - hash = math::crc64(&vpos.x, sizeof(vpos.x), hash); - hash = math::crc64(&vpos.y, sizeof(vpos.y), hash); - hash = math::crc64(&vpos.z, sizeof(vpos.z), hash); - - return static_cast(hash % textures.size()); -} - -void world::Voxel::set_face_cache(VoxelFace face, std::size_t offset, std::size_t plane) -{ - assert(face < m_cached_face_offsets.size()); - assert(face < m_cached_face_planes.size()); - - m_cached_face_offsets[face] = offset; - m_cached_face_planes[face] = plane; -} - -std::uint64_t world::Voxel::get_checksum(std::uint64_t combine) const -{ - combine = math::crc64(m_name.data(), m_name.size(), combine); - combine += static_cast(m_shape); - combine += static_cast(m_render_mode); - return combine; -} - -world::VoxelBuilder::VoxelBuilder(std::string_view name) -{ - set_name(name); -} - -void world::VoxelBuilder::set_on_place(VoxelOnPlaceFunc func) noexcept -{ - m_on_place = std::move(func); -} - -void world::VoxelBuilder::set_on_remove(VoxelOnRemoveFunc func) noexcept -{ - m_on_remove = std::move(func); -} - -void world::VoxelBuilder::set_on_tick(VoxelOnTickFunc func) noexcept -{ - m_on_tick = std::move(func); -} - -void world::VoxelBuilder::set_name(std::string_view name) noexcept -{ - assert(name.size()); - - m_name = name; -} - -void world::VoxelBuilder::set_render_mode(VoxelRender mode) noexcept -{ - m_render_mode = mode; -} - -void world::VoxelBuilder::set_shape(VoxelShape shape) noexcept -{ - m_shape = shape; -} - -void world::VoxelBuilder::set_animated(bool animated) noexcept -{ - m_animated = animated; -} - -void world::VoxelBuilder::set_touch_type(VoxelTouch type) noexcept -{ - m_touch_type = type; -} - -void world::VoxelBuilder::set_touch_values(const glm::fvec3& values) noexcept -{ - m_touch_values = values; -} - -void world::VoxelBuilder::set_surface_material(VoxelMaterial material) noexcept -{ - m_surface_material = material; -} - -void world::VoxelBuilder::set_collision(const math::AABBf& box) noexcept -{ - m_collision = box; -} - -void world::VoxelBuilder::add_default_texture(std::string_view path) -{ - assert(path.size()); - - m_default_textures.emplace_back(path); -} - -void world::VoxelBuilder::add_face_texture(VoxelFace face, std::string_view path) -{ - assert(face < m_face_textures.size()); - assert(path.size()); - - m_face_textures[face].emplace_back(path); -} - -std::unique_ptr world::VoxelBuilder::build(voxel_id id) const -{ - assert(m_name.size()); - assert(id); - - return std::make_unique(*this, id); -} diff --git a/game/shared/world/voxel.hh b/game/shared/world/voxel.hh deleted file mode 100644 index 6013962..0000000 --- a/game/shared/world/voxel.hh +++ /dev/null @@ -1,286 +0,0 @@ -#pragma once - -#include "core/math/aabb.hh" - -#include "shared/types.hh" - -namespace world -{ -class Dimension; -} // namespace world - -namespace world -{ -enum VoxelRender : unsigned int { - VRENDER_NONE = 0U, ///< The voxel is not rendered at all - VRENDER_OPAQUE, ///< The voxel is fully opaque - VRENDER_BLEND, ///< The voxel is blended (e.g. water, glass) -}; - -enum VoxelShape : unsigned int { - VSHAPE_CUBE = 0U, ///< Full cube shape - VSHAPE_CROSS, ///< TODO: Cross shape - VSHAPE_MODEL, ///< TODO: Custom model shape -}; - -enum VoxelFace : unsigned int { - VFACE_NORTH = 0U, ///< Positive Z face - VFACE_SOUTH, ///< Negative Z face - VFACE_EAST, ///< Positive X face - VFACE_WEST, ///< Negative X face - VFACE_TOP, ///< Positive Y face - VFACE_BOTTOM, ///< Negative Y face - VFACE_CROSS_NWSE, ///< Diagonal cross face northwest-southeast - VFACE_CROSS_NESW, ///< Diagonal cross face northeast-southwest - VFACE_COUNT -}; - -enum VoxelTouch : unsigned int { - VTOUCH_NONE = 0xFFFFU, - VTOUCH_SOLID = 0U, ///< The entity is stopped in its tracks - VTOUCH_BOUNCE, ///< The entity bounces back with some energy loss - VTOUCH_SINK, ///< The entity phases/sinks through the voxel -}; - -enum VoxelMaterial : unsigned int { - VMAT_UNKNOWN = 0xFFFFU, - VMAT_DEFAULT = 0U, - VMAT_STONE, - VMAT_DIRT, - VMAT_GLASS, - VMAT_GRASS, - VMAT_GRAVEL, - VMAT_METAL, - VMAT_SAND, - VMAT_WOOD, - VMAT_SLOSH, - VMAT_COUNT -}; - -enum VoxelVisBits : unsigned int { - VVIS_NORTH = 1U << VFACE_NORTH, ///< Positive Z - VVIS_SOUTH = 1U << VFACE_SOUTH, ///< Negative Z - VVIS_EAST = 1U << VFACE_EAST, ///< Positive X - VVIS_WEST = 1U << VFACE_WEST, ///< Negative X - VVIS_UP = 1U << VFACE_TOP, ///< Positive Y - VVIS_DOWN = 1U << VFACE_BOTTOM, ///< Negative Y -}; -} // namespace world - -namespace world -{ -using VoxelOnPlaceFunc = std::function; -using VoxelOnRemoveFunc = std::function; -using VoxelOnTickFunc = std::function; -} // namespace world - -namespace world -{ -class Voxel { -public: - Voxel(void) = default; - explicit Voxel(const Voxel& source, voxel_id id) noexcept; - - void on_place(Dimension* dimension, const voxel_pos& vpos) const; - void on_remove(Dimension* dimension, const voxel_pos& vpos) const; - void on_tick(Dimension* dimension, const voxel_pos& vpos) const; - - constexpr std::string_view get_name(void) const noexcept; - constexpr voxel_id get_id(void) const noexcept; - - constexpr VoxelRender get_render_mode(void) const noexcept; - constexpr VoxelShape get_shape(void) const noexcept; - constexpr bool is_animated(void) const noexcept; - - constexpr VoxelTouch get_touch_type(void) const noexcept; - constexpr const glm::fvec3& get_touch_values(void) const noexcept; - constexpr VoxelMaterial get_surface_material(void) const noexcept; - - constexpr const math::AABBf& get_collision(void) const noexcept; - - constexpr const std::vector& get_default_textures(void) const noexcept; - constexpr const std::vector& get_face_textures(VoxelFace face) const noexcept; - constexpr std::size_t get_cached_face_offset(VoxelFace face) const noexcept; - constexpr std::size_t get_cached_face_plane(VoxelFace face) const noexcept; - - template - constexpr bool is_render_mode(void) const noexcept; - template - constexpr bool is_shape(void) const noexcept; - template - constexpr bool is_touch_type(void) const noexcept; - template - constexpr bool is_surface_material(void) const noexcept; - - /// Non-model voxel shapes support texture variation based on the - /// voxel position on the world; this method handles the math behind this - /// @param face The face of the voxel to get the texture index for - /// @param vpos The absolute voxel position to get the texture index for - /// @return The index of the texture to use for the given face at the given position - /// @remarks On client-side: plane[get_cached_face_plane][get_cached_face_offset + thisFunctionResult] - std::size_t get_random_texture_index(VoxelFace face, const voxel_pos& vpos) const; - - /// Assign cached plane index and plane offset for a given face - /// @param face The face to assign the cache for - /// @param offset The offset to assign to the face - /// @param plane The plane index to assign to the face - void set_face_cache(VoxelFace face, std::size_t offset, std::size_t plane); - - /// Calculate a checksum for the voxel's properties - /// @param combine An optional initial checksum to combine with - /// @return The calculated checksum - std::uint64_t get_checksum(std::uint64_t combine = 0U) const; - -protected: - std::string m_name; - voxel_id m_id { NULL_VOXEL_ID }; - - VoxelRender m_render_mode { VRENDER_OPAQUE }; - VoxelShape m_shape { VSHAPE_CUBE }; - bool m_animated { false }; - - VoxelTouch m_touch_type { VTOUCH_SOLID }; - glm::fvec3 m_touch_values { 0.0f }; - VoxelMaterial m_surface_material { VMAT_DEFAULT }; - - math::AABBf m_collision { { 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f } }; - - std::vector m_default_textures; - std::array, VFACE_COUNT> m_face_textures; - std::array m_cached_face_offsets; - std::array m_cached_face_planes; - - VoxelOnPlaceFunc m_on_place; - VoxelOnRemoveFunc m_on_remove; - VoxelOnTickFunc m_on_tick; -}; -} // namespace world - -namespace world -{ -class VoxelBuilder final : public Voxel { -public: - VoxelBuilder(void) = default; - explicit VoxelBuilder(std::string_view name); - - void set_on_place(VoxelOnPlaceFunc func) noexcept; - void set_on_remove(VoxelOnRemoveFunc func) noexcept; - void set_on_tick(VoxelOnTickFunc func) noexcept; - - void set_name(std::string_view name) noexcept; - - void set_render_mode(VoxelRender mode) noexcept; - void set_shape(VoxelShape shape) noexcept; - void set_animated(bool animated) noexcept; - - void set_touch_type(VoxelTouch type) noexcept; - void set_touch_values(const glm::fvec3& values) noexcept; - void set_surface_material(VoxelMaterial material) noexcept; - - void set_collision(const math::AABBf& box) noexcept; - - void add_default_texture(std::string_view path); - void add_face_texture(VoxelFace face, std::string_view path); - - std::unique_ptr build(voxel_id id) const; -}; -} // namespace world - -constexpr std::string_view world::Voxel::get_name(void) const noexcept -{ - return m_name; -} - -constexpr voxel_id world::Voxel::get_id(void) const noexcept -{ - return m_id; -} - -constexpr world::VoxelRender world::Voxel::get_render_mode(void) const noexcept -{ - return m_render_mode; -} - -constexpr world::VoxelShape world::Voxel::get_shape(void) const noexcept -{ - return m_shape; -} - -constexpr bool world::Voxel::is_animated(void) const noexcept -{ - return m_animated; -} - -constexpr world::VoxelTouch world::Voxel::get_touch_type(void) const noexcept -{ - return m_touch_type; -} - -constexpr const glm::fvec3& world::Voxel::get_touch_values(void) const noexcept -{ - return m_touch_values; -} - -constexpr world::VoxelMaterial world::Voxel::get_surface_material(void) const noexcept -{ - return m_surface_material; -} - -constexpr const math::AABBf& world::Voxel::get_collision(void) const noexcept -{ - return m_collision; -} - -constexpr const std::vector& world::Voxel::get_default_textures(void) const noexcept -{ - return m_default_textures; -} - -constexpr const std::vector& world::Voxel::get_face_textures(VoxelFace face) const noexcept -{ - assert(face <= m_face_textures.size()); - - if(m_face_textures[face].empty()) { - return m_default_textures; - } - - return m_face_textures[face]; -} - -constexpr std::size_t world::Voxel::get_cached_face_offset(VoxelFace face) const noexcept -{ - assert(face <= m_cached_face_offsets.size()); - - return m_cached_face_offsets[face]; -} - -constexpr std::size_t world::Voxel::get_cached_face_plane(VoxelFace face) const noexcept -{ - assert(face <= m_cached_face_planes.size()); - - return m_cached_face_planes[face]; -} - -template -constexpr bool world::Voxel::is_render_mode(void) const noexcept -{ - return m_render_mode == RenderMode; -} - -template -constexpr bool world::Voxel::is_shape(void) const noexcept -{ - return m_shape == Shape; -} - -template -constexpr bool world::Voxel::is_touch_type(void) const noexcept -{ - return m_touch_type == TouchType; -} - -template -constexpr bool world::Voxel::is_surface_material(void) const noexcept -{ - return m_surface_material == Material; -} diff --git a/game/shared/world/voxel_registry.cc b/game/shared/world/voxel_registry.cc deleted file mode 100644 index 573a606..0000000 --- a/game/shared/world/voxel_registry.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/voxel_registry.hh" - -static std::uint64_t registry_checksum = 0U; -emhash8::HashMap world::voxel_registry::names; -std::vector> world::voxel_registry::voxels; - -static void recalculate_checksum(void) -{ - registry_checksum = 0U; - - for(const auto& voxel : world::voxel_registry::voxels) { - registry_checksum = voxel->get_checksum(registry_checksum); - } -} - -world::Voxel* world::voxel_registry::register_voxel(const VoxelBuilder& builder) -{ - assert(builder.get_name().size()); - assert(nullptr == find(builder.get_name())); - - const auto id = static_cast(1 + voxels.size()); - - std::unique_ptr voxel(builder.build(id)); - names.emplace(std::string(builder.get_name()), id); - voxels.push_back(std::move(voxel)); - - recalculate_checksum(); - - return voxels.back().get(); -} - -world::Voxel* world::voxel_registry::find(std::string_view name) -{ - const auto it = names.find(std::string(name)); - - if(it == names.end()) { - return nullptr; - } - - return voxels[it->second - 1].get(); -} - -world::Voxel* world::voxel_registry::find(voxel_id id) -{ - if(id == NULL_VOXEL_ID || id > voxels.size()) { - return nullptr; - } - - return voxels[id - 1].get(); -} - -void world::voxel_registry::purge(void) -{ - registry_checksum = 0U; - voxels.clear(); - names.clear(); -} - -std::uint64_t world::voxel_registry::get_checksum(void) -{ - return registry_checksum; -} diff --git a/game/shared/world/voxel_registry.hh b/game/shared/world/voxel_registry.hh deleted file mode 100644 index 5ba2aed..0000000 --- a/game/shared/world/voxel_registry.hh +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "shared/world/voxel.hh" - -namespace world::voxel_registry -{ -extern emhash8::HashMap names; -extern std::vector> voxels; -} // namespace world::voxel_registry - -namespace world::voxel_registry -{ -Voxel* register_voxel(const VoxelBuilder& builder); -Voxel* find(std::string_view name); -Voxel* find(voxel_id id); -} // namespace world::voxel_registry - -namespace world::voxel_registry -{ -void purge(void); -} // namespace world::voxel_registry - -namespace world::voxel_registry -{ -std::uint64_t get_checksum(void); -} // namespace world::voxel_registry diff --git a/game/shared/world/voxel_storage.cc b/game/shared/world/voxel_storage.cc deleted file mode 100644 index 75013b4..0000000 --- a/game/shared/world/voxel_storage.cc +++ /dev/null @@ -1,48 +0,0 @@ -#include "shared/pch.hh" - -#include "shared/world/voxel_storage.hh" - -#include "core/io/buffer.hh" - -void world::VoxelStorage::serialize(io::WriteBuffer& buffer) const -{ - auto bound = mz_compressBound(sizeof(VoxelStorage)); - auto zdata = std::vector(bound); - - VoxelStorage net_storage; - - for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { - // Convert voxel indices into network byte order; - // We're going to compress them but we still want - // the order to be consistent across all the platforms - net_storage[i] = ENET_HOST_TO_NET_16(at(i)); - } - - mz_compress(zdata.data(), &bound, reinterpret_cast(net_storage.data()), sizeof(VoxelStorage)); - - buffer.write(bound); - - // Write all the compressed data into the buffer - for(std::size_t i = 0; i < bound; buffer.write(zdata[i++])) { - // empty - } -} - -void world::VoxelStorage::deserialize(io::ReadBuffer& buffer) -{ - auto size = static_cast(sizeof(VoxelStorage)); - auto bound = static_cast(buffer.read()); - auto zdata = std::vector(bound); - - // Read all the compressed data from the buffer - for(std::size_t i = 0; i < bound; zdata[i++] = buffer.read()) { - // empty - } - - mz_uncompress(reinterpret_cast(data()), &size, zdata.data(), bound); - - for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { - // Convert voxel indices back into the host byte order - at(i) = ENET_NET_TO_HOST_16(at(i)); - } -} diff --git a/game/shared/world/voxel_storage.hh b/game/shared/world/voxel_storage.hh deleted file mode 100644 index 98e85a3..0000000 --- a/game/shared/world/voxel_storage.hh +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "shared/const.hh" -#include "shared/types.hh" - -namespace io -{ -class ReadBuffer; -class WriteBuffer; -} // namespace io - -namespace world -{ -class VoxelStorage final : public std::array { -public: - using std::array::array; - void serialize(io::WriteBuffer& buffer) const; - void deserialize(io::ReadBuffer& buffer); -}; -} // namespace world -- cgit