infinite height and removed height data

This commit is contained in:
Chewico 2026-11-03 21:10:44 +01:00
parent 535bc27c56
commit c828c656b7
8 changed files with 144 additions and 407 deletions

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <deerith/world/world_core.h> #include <deerith/world/world_core.h>
#include <deerith/world/environment.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
namespace deerith namespace deerith
@ -12,7 +13,7 @@ namespace deerith
bool is_world_running(); bool is_world_running();
void render_world(); void render_world();
void generate_cluster(glm::ivec2 cluster_id, size_t cluster_height_id); void generate_cluster(voxel_cluster_t *_cluster);
void load_clusters_to_gpu(); void load_clusters_to_gpu();
client_t *get_server_client(); client_t *get_server_client();

View File

@ -7,9 +7,7 @@
namespace deerith namespace deerith
{ {
cluster_voxel_type_id_data_t *cluster_data = nullptr; voxel_cluster_t *cluster = nullptr;
glm::ivec2 cluster_id;
size_t cluster_height_id;
void generate_voxel(int x, int y, int z); void generate_voxel(int x, int y, int z);
voxel_type_id_t get_cluster_voxel(int x, int y, int z); voxel_type_id_t get_cluster_voxel(int x, int y, int z);
@ -27,22 +25,19 @@ void deerith::load_clusters_to_gpu()
} }
} }
void deerith::generate_cluster(glm::ivec2 _cluster_id, size_t _cluster_height_id) void deerith::generate_cluster(voxel_cluster_t *_cluster)
{ {
if (build_data) if (build_data)
{ {
return; return;
} }
cluster = _cluster;
build_data = std::make_unique<mesh_3d_data_t>(); build_data = std::make_unique<mesh_3d_data_t>();
cluster_data = get_cluster_voxel_type_id_raw_ponter(_cluster_id, _cluster_height_id); if (cluster == nullptr)
cluster_id = _cluster_id;
cluster_height_id = _cluster_height_id;
if (cluster_data == nullptr)
{ {
deerith_error("cluster data is null and it should not generate_cluster"); deerith_error("cluster is null generate_cluster");
return; return;
} }
@ -56,11 +51,13 @@ void deerith::generate_cluster(glm::ivec2 _cluster_id, size_t _cluster_height_id
} }
} }
} }
cluster = nullptr;
} }
void deerith::generate_voxel(int x, int y, int z) void deerith::generate_voxel(int x, int y, int z)
{ {
voxel_type_id_t cur_type_id = (*cluster_data)[x][y][z]; voxel_type_id_t cur_type_id = cluster->data[x][y][z];
const voxel_type_t &cur_type = get_voxel_type(cur_type_id); const voxel_type_t &cur_type = get_voxel_type(cur_type_id);
if (!cur_type.is_solid) if (!cur_type.is_solid)
@ -123,12 +120,13 @@ deerith::voxel_type_id_t deerith::get_cluster_voxel(int x, int y, int z)
if (in_bounds_check) if (in_bounds_check)
{ {
return (*cluster_data)[x][y][z]; return cluster->data[x][y][z];
} }
glm::ivec3 coords(x + CLUSTER_SIZE * cluster_id.x, glm::ivec3 coords;
y + (cluster_height_id - STARTING_CLUSTER_HEIGHT) * CLUSTER_SIZE, coords.x = x + CLUSTER_SIZE * cluster->surface_id.x;
z + cluster_id.y * CLUSTER_SIZE); coords.y = y + CLUSTER_SIZE * cluster->layer;
coords.z = z + CLUSTER_SIZE * cluster->surface_id.y;
return get_voxel_id(coords); return get_voxel_id(coords);
} }

View File

@ -18,7 +18,6 @@ void deerith::setup_base_protocols()
router_add_packet_processor<packet_update_entities_coordinates_t>(); router_add_packet_processor<packet_update_entities_coordinates_t>();
router_add_packet_processor<packet_destroy_entity_t>(); router_add_packet_processor<packet_destroy_entity_t>();
router_add_packet_processor<packet_voxel_data_definition_t>(); router_add_packet_processor<packet_voxel_data_definition_t>();
router_add_packet_processor<packet_surface_data_t>();
router_add_packet_processor<packet_cluster_data_t>(); router_add_packet_processor<packet_cluster_data_t>();
} }
@ -94,15 +93,13 @@ void deerith::process_packet(deerith::packet_voxel_data_definition_t &packet, cl
set_voxel_types(packet.voxel_types); set_voxel_types(packet.voxel_types);
} }
template <>
void deerith::process_packet(deerith::packet_surface_data_t &packet, client_t *client)
{
set_surface_height_raw_data(*packet.__surface_data, packet.surface_id);
}
template <> template <>
void deerith::process_packet(deerith::packet_cluster_data_t &packet, client_t *client) void deerith::process_packet(deerith::packet_cluster_data_t &packet, client_t *client)
{ {
set_cluster_voxel_type_id_raw_data(*packet.__cluster_data, packet.surface_id, packet.cluster_height_id); surface_t *surface = get_create_surface(packet.surface_id);
generate_cluster(packet.surface_id, packet.cluster_height_id); voxel_cluster_t *cluster = surface->get_create_cluster(packet.layer);
cluster->data = *packet.__cluster_data;
generate_cluster(cluster);
} }

View File

@ -29,38 +29,13 @@ namespace deerith
} }
}; };
struct packet_surface_data_t struct packet_cluster_data_t
{ {
static constexpr uint16_t packet_id = 1002; static constexpr uint16_t packet_id = 1002;
static constexpr bool reliable = true; static constexpr bool reliable = true;
int layer;
glm::ivec2 surface_id; glm::ivec2 surface_id;
std::unique_ptr<surface_height_data_t> __surface_data;
template <typename Archive>
void save(Archive &archive) const
{
archive(surface_id);
archive(*__surface_data);
}
template <typename Archive>
void load(Archive &archive)
{
archive(surface_id);
__surface_data = std::make_unique<surface_height_data_t>();
archive(*__surface_data);
}
};
struct packet_cluster_data_t
{
static constexpr uint16_t packet_id = 1003;
static constexpr bool reliable = true;
glm::ivec2 surface_id;
size_t cluster_height_id;
std::unique_ptr<cluster_voxel_type_id_data_t> __cluster_data; std::unique_ptr<cluster_voxel_type_id_data_t> __cluster_data;
@ -68,7 +43,7 @@ namespace deerith
void save(Archive &archive) const void save(Archive &archive) const
{ {
archive(surface_id); archive(surface_id);
archive(cluster_height_id); archive(layer);
archive(*__cluster_data); archive(*__cluster_data);
} }
@ -76,7 +51,7 @@ namespace deerith
void load(Archive &archive) void load(Archive &archive)
{ {
archive(surface_id); archive(surface_id);
archive(cluster_height_id); archive(layer);
__cluster_data = std::make_unique<cluster_voxel_type_id_data_t>(); __cluster_data = std::make_unique<cluster_voxel_type_id_data_t>();
archive(*__cluster_data); archive(*__cluster_data);

View File

@ -1,47 +1,52 @@
#pragma once #pragma once
#include <deerith/engine.h> #include <deerith/engine.h>
#include <deerith/world/voxels.h> #include <deerith/world/voxels.h>
#include <deerith/world/world_core.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
namespace deerith namespace deerith
{ {
inline constexpr int CLUSTER_SIZE = 32; inline constexpr int CLUSTER_SIZE = 32;
inline constexpr int MAX_CLUSTER_IN_SURFACE = 16;
inline constexpr int STARTING_CLUSTER_HEIGHT = -8;
inline constexpr float VOXEL_SIZE = 0.5f; inline constexpr float VOXEL_SIZE = 0.5f;
using surface_height_t = int16_t;
using surface_height_data_t = std::array<std::array<surface_height_t, CLUSTER_SIZE>, CLUSTER_SIZE>;
using cluster_voxel_type_id_data_t = std::array<std::array<std::array<voxel_type_id_t, CLUSTER_SIZE>, CLUSTER_SIZE>, CLUSTER_SIZE>; using cluster_voxel_type_id_data_t = std::array<std::array<std::array<voxel_type_id_t, CLUSTER_SIZE>, CLUSTER_SIZE>, CLUSTER_SIZE>;
void set_surface_height(glm::ivec2 surface_pos, surface_height_t height); struct voxel_cluster_t
{
voxel_cluster_t() : last_update_tick_id(get_world_tick()) {}
int32_t layer;
glm::ivec2 surface_id;
uint32_t last_update_tick_id;
cluster_voxel_type_id_data_t data = {};
};
struct surface_t
{
glm::ivec2 surface_id;
std::vector<std::unique_ptr<voxel_cluster_t>> voxel_clusters;
voxel_cluster_t *get_cluster(int layer);
voxel_cluster_t *get_create_cluster(int layer);
};
}
namespace deerith
{
void set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates); void set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates);
voxel_type_id_t get_voxel_id(glm::ivec3 coordinates); voxel_type_id_t get_voxel_id(glm::ivec3 coordinates);
const voxel_type_t &get_voxel(glm::ivec3 coordinates); const voxel_type_t &get_voxel(glm::ivec3 coordinates);
void get_surface_height_raw_data(surface_height_data_t &data, glm::ivec2 surface_id); int32_t get_cluster_last_tick_update(glm::ivec2 surface_id, int layer);
void set_surface_height_raw_data(const surface_height_data_t &data, glm::ivec2 surface_id); surface_t *get_surface(glm::ivec2);
surface_t *get_create_surface(glm::ivec2);
void get_cluster_voxel_type_id_raw_data(cluster_voxel_type_id_data_t &data, glm::ivec2 surface_id, size_t cluster_height_id);
void set_cluster_voxel_type_id_raw_data(const cluster_voxel_type_id_data_t &data, glm::ivec2 surface_id, size_t cluster_height_id);
cluster_voxel_type_id_data_t *get_cluster_voxel_type_id_raw_ponter(glm::ivec2 surface_id, size_t cluster_height_id);
int32_t get_cluster_last_tick_update(glm::ivec2 surface_id, size_t height_id);
} }
// UTILS
namespace deerith namespace deerith
{ {
struct environment_settings_t struct ivec2_hash_t
{
voxel_type_id_t default_air = 0;
voxel_type_id_t default_surface = 1;
surface_height_t default_height = 0;
};
struct surface_pos_hash_t
{ {
std::size_t operator()(const glm::ivec2 &id) const noexcept std::size_t operator()(const glm::ivec2 &id) const noexcept
{ {
@ -52,7 +57,7 @@ namespace deerith
} }
}; };
struct world_pos_hash_t struct ivec3_hash_t
{ {
std::size_t operator()(const glm::ivec3 &pos) const noexcept std::size_t operator()(const glm::ivec3 &pos) const noexcept
{ {

View File

@ -10,121 +10,100 @@
namespace deerith namespace deerith
{ {
struct voxel_cluster_t std::unordered_map<glm::ivec2, std::unique_ptr<surface_t>, ivec2_hash_t> surface_map;
{
voxel_cluster_t() : last_update_tick_id(get_world_tick()) {}
uint32_t last_update_tick_id;
cluster_voxel_type_id_data_t data = {};
};
struct surface_t
{
glm::ivec2 surface_id;
surface_height_data_t __layer_height = {};
std::unique_ptr<voxel_cluster_t> voxel_clusters[MAX_CLUSTER_IN_SURFACE] = {};
};
std::vector<std::unique_ptr<surface_t>> surfaces;
std::unordered_map<glm::ivec2, size_t, surface_pos_hash_t> surface_id_index_map;
voxel_type_id_t get_default_voxel(glm::ivec3);
glm::ivec2 get_surface_id(glm::ivec3 coords); glm::ivec2 get_surface_id(glm::ivec3 coords);
glm::ivec2 get_surface_id(glm::ivec2 coords); glm::ivec2 get_surface_id(glm::ivec2 coords);
int get_layer(int y_coords);
glm::ivec3 get_internal_voxel_coords(glm::ivec3 coords); glm::ivec3 get_internal_voxel_coords(glm::ivec3 coords);
glm::ivec3 get_internal_voxel_coords(glm::ivec2 coords, int height = 0); glm::ivec3 get_internal_voxel_coords(glm::ivec2 coords, int height = 0);
size_t get_voxel_cluster_height_id(int height);
surface_t *create_surface(glm::ivec2); surface_t *get_surface(glm::ivec2);
voxel_cluster_t *create_cluster(glm::ivec2, size_t); surface_t *get_create_surface(glm::ivec2);
} }
deerith::surface_t *deerith::create_surface(glm::ivec2 surface_id) deerith::voxel_cluster_t *deerith::surface_t::get_cluster(int layer)
{ {
std::unique_ptr<surface_t> new_surface = std::make_unique<surface_t>(); for (std::unique_ptr<voxel_cluster_t> &cluster : voxel_clusters)
size_t surface_index = surfaces.size();
surfaces.push_back(std::move(new_surface));
surface_id_index_map[surface_id] = surface_index;
return surfaces.back().get();
}
deerith::voxel_cluster_t *deerith::create_cluster(glm::ivec2 surface_id, size_t cluster_height_id)
{ {
surface_t *surface = nullptr; if (cluster->layer == layer)
if (surface_id_index_map.contains(surface_id))
{ {
size_t surface_index = surface_id_index_map[surface_id]; return cluster.get();
surface = surfaces[surface_index].get();
}
surface->voxel_clusters[cluster_height_id] = std::make_unique<voxel_cluster_t>();
voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get();
for (int x = 0; x < CLUSTER_SIZE; x++)
{
for (int z = 0; z < CLUSTER_SIZE; z++)
{
int start_height = 0;
int end_height = surface->__layer_height[x][z] - ((int)cluster_height_id + STARTING_CLUSTER_HEIGHT) * CLUSTER_SIZE;
for (int y = start_height; y < end_height; y++)
{
cluster->data[x][y][z] = 1;
} }
} }
return nullptr;
} }
deerith::voxel_cluster_t *deerith::surface_t::get_create_cluster(int layer)
{
for (std::unique_ptr<voxel_cluster_t> &cluster : voxel_clusters)
{
if (cluster->layer == layer)
{
return cluster.get();
}
}
voxel_clusters.push_back(std::make_unique<voxel_cluster_t>());
voxel_cluster_t *cluster = voxel_clusters.back().get();
cluster->layer = layer;
cluster->surface_id = surface_id;
return cluster; return cluster;
} }
deerith::voxel_type_id_t deerith::get_default_voxel(glm::ivec3 coords) deerith::surface_t *deerith::get_surface(glm::ivec2 surface_id)
{ {
if (coords.y > 0) surface_t *surface = nullptr;
if (surface_map.contains(surface_id))
{ {
return 0; surface = surface_map[surface_id].get();
}
else
{
return 1;
}
} }
size_t deerith::get_voxel_cluster_height_id(int height) return surface;
{
// >= MAX_CLUSTER_IN_SURFACE means out of bounds
if (height < (STARTING_CLUSTER_HEIGHT)*CLUSTER_SIZE)
{
return MAX_CLUSTER_IN_SURFACE;
} }
int normalized_height = std::floor(static_cast<float>(height) / static_cast<float>(CLUSTER_SIZE)); deerith::surface_t *deerith::get_create_surface(glm::ivec2 surface_id)
size_t cluster_height_id = normalized_height - STARTING_CLUSTER_HEIGHT; {
surface_t *surface = nullptr;
if (surface_map.contains(surface_id))
{
surface = surface_map[surface_id].get();
return surface;
}
return cluster_height_id; surface_map[surface_id] = std::make_unique<surface_t>();
surface = surface_map[surface_id].get();
surface->surface_id = surface_id;
return surface;
}
int deerith::get_layer(int y_coord)
{
int layer = std::floor(static_cast<float>(y_coord) / static_cast<float>(CLUSTER_SIZE));
return layer;
} }
glm::ivec3 deerith::get_internal_voxel_coords(glm::ivec3 coords) glm::ivec3 deerith::get_internal_voxel_coords(glm::ivec3 coords)
{ {
// this will invert negatives coords but we don't mind
glm::ivec3 ic = {}; glm::ivec3 ic = {};
ic.x = std::abs(coords.x % (CLUSTER_SIZE)); ic.x = (coords.x % CLUSTER_SIZE + CLUSTER_SIZE) % CLUSTER_SIZE;
ic.y = std::abs(coords.y % (CLUSTER_SIZE)); ic.y = (coords.y % CLUSTER_SIZE + CLUSTER_SIZE) % CLUSTER_SIZE;
ic.z = std::abs(coords.z % (CLUSTER_SIZE)); ic.z = (coords.z % CLUSTER_SIZE + CLUSTER_SIZE) % CLUSTER_SIZE;
return ic; return ic;
} }
glm::ivec3 deerith::get_internal_voxel_coords(glm::ivec2 coords, int height) glm::ivec3 deerith::get_internal_voxel_coords(glm::ivec2 coords, int height)
{ {
// this will invert negatives coords but we don't mind
glm::ivec3 ic = {}; glm::ivec3 ic = {};
ic.x = std::abs(coords.x % (CLUSTER_SIZE)); ic.x = (coords.x % CLUSTER_SIZE + CLUSTER_SIZE) % CLUSTER_SIZE;
ic.y = std::abs(height % (CLUSTER_SIZE)); ic.y = (height % CLUSTER_SIZE + CLUSTER_SIZE) % CLUSTER_SIZE;
ic.z = std::abs(coords.y % (CLUSTER_SIZE)); ic.z = (coords.y % CLUSTER_SIZE + CLUSTER_SIZE) % CLUSTER_SIZE;
return ic; return ic;
} }
@ -147,57 +126,15 @@ glm::ivec2 deerith::get_surface_id(glm::ivec2 coords)
return surface_id; return surface_id;
} }
// This sets the terrain layer for default comosition y > height -> 0; y <= height -> 1
void deerith::set_surface_height(glm::ivec2 surface_pos, surface_height_t height)
{
glm::ivec2 surface_id = get_surface_id(surface_pos);
surface_t *surface = nullptr;
if (surface_id_index_map.contains(surface_id))
{
size_t surface_index = surface_id_index_map[surface_id];
surface = surfaces[surface_index].get();
}
if (surface == nullptr)
{
surface = create_surface(surface_id);
}
glm::ivec3 internal_voxel_id = get_internal_voxel_coords(surface_pos, height);
surface->__layer_height[internal_voxel_id.x][internal_voxel_id.z] = height;
}
void deerith::set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates) void deerith::set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates)
{ {
glm::ivec2 surface_id = get_surface_id(coordinates); glm::ivec2 surface_id = get_surface_id(coordinates);
surface_t *surface = get_create_surface(surface_id);
surface_t *surface = nullptr;
if (surface_id_index_map.contains(surface_id))
{
size_t surface_index = surface_id_index_map[surface_id];
surface = surfaces[surface_index].get();
}
if (surface == nullptr)
{
surface = create_surface(surface_id);
}
glm::ivec3 internal_voxel_id = get_internal_voxel_coords(coordinates); glm::ivec3 internal_voxel_id = get_internal_voxel_coords(coordinates);
int layer = get_layer(coordinates.y);
size_t cluster_height_id = get_voxel_cluster_height_id(coordinates.y); voxel_cluster_t *cluster = surface->get_create_cluster(layer);
if (cluster_height_id >= MAX_CLUSTER_IN_SURFACE)
{
deerith_warn("tried to build out of bounds set_voxel; pos {}.{}.{}", coordinates.x, coordinates.y, coordinates.z);
return;
}
voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get();
if (cluster == nullptr)
{
cluster = create_cluster(surface_id, cluster_height_id);
}
cluster->last_update_tick_id = get_world_tick(); cluster->last_update_tick_id = get_world_tick();
cluster->data[internal_voxel_id.x][internal_voxel_id.y][internal_voxel_id.z] = voxel_id; cluster->data[internal_voxel_id.x][internal_voxel_id.y][internal_voxel_id.z] = voxel_id;
@ -206,38 +143,21 @@ void deerith::set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates)
deerith::voxel_type_id_t deerith::get_voxel_id(glm::ivec3 coordinates) deerith::voxel_type_id_t deerith::get_voxel_id(glm::ivec3 coordinates)
{ {
glm::ivec2 surface_id = get_surface_id(coordinates); glm::ivec2 surface_id = get_surface_id(coordinates);
surface_t *surface = get_surface(surface_id);
if (!surface_id_index_map.contains(surface_id))
{
return get_default_voxel(coordinates);
}
size_t surface_index = surface_id_index_map[surface_id];
surface_t *surface = surfaces[surface_index].get();
if (surface == nullptr) if (surface == nullptr)
{
return get_default_voxel(coordinates);
}
size_t cluster_height_id = get_voxel_cluster_height_id(coordinates.y);
if (cluster_height_id >= MAX_CLUSTER_IN_SURFACE)
{
return get_default_voxel(coordinates);
}
glm::ivec3 internal_voxel_id = get_internal_voxel_coords(coordinates);
voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get();
if (cluster == nullptr)
{
if (coordinates.y <= surface->__layer_height[internal_voxel_id.x][internal_voxel_id.y])
{
return 1;
}
else
{ {
return 0; return 0;
} }
int layer = get_layer(coordinates.y);
glm::ivec3 internal_voxel_id = get_internal_voxel_coords(coordinates);
voxel_cluster_t *cluster = surface->get_cluster(layer);
if (cluster == nullptr)
{
return 0;
} }
return cluster->data[internal_voxel_id.x][internal_voxel_id.y][internal_voxel_id.z]; return cluster->data[internal_voxel_id.x][internal_voxel_id.y][internal_voxel_id.z];
@ -248,67 +168,18 @@ const deerith::voxel_type_t &deerith::get_voxel(glm::ivec3 coordinates)
return get_voxel_type(get_voxel_id(coordinates)); return get_voxel_type(get_voxel_id(coordinates));
} }
void deerith::get_surface_height_raw_data(surface_height_data_t &data, glm::ivec2 surface_pos) int32_t deerith::get_cluster_last_tick_update(glm::ivec2 surface_id, int layer)
{ {
glm::ivec2 surface_id = get_surface_id(surface_pos);
surface_t *surface = nullptr; surface_t *surface = get_surface(surface_id);
if (surface_id_index_map.contains(surface_id))
{
size_t surface_index = surface_id_index_map[surface_id];
surface = surfaces[surface_index].get();
}
if (surface == nullptr)
{
surface = create_surface(surface_id);
}
std::memcpy(data.data(), surface->__layer_height.data(), sizeof(data));
}
void deerith::set_surface_height_raw_data(const surface_height_data_t &data, glm::ivec2 surface_pos)
{
glm::ivec2 surface_id = get_surface_id(surface_pos);
surface_t *surface = nullptr;
if (surface_id_index_map.contains(surface_id))
{
size_t surface_index = surface_id_index_map[surface_id];
surface = surfaces[surface_index].get();
}
if (surface == nullptr)
{
surface = create_surface(surface_id);
}
std::memcpy(surface->__layer_height.data(), data.data(), sizeof(data));
}
int32_t deerith::get_cluster_last_tick_update(glm::ivec2 surface_id, size_t height_id)
{
if (!surface_id_index_map.contains(surface_id))
{
return -1;
}
size_t surface_index = surface_id_index_map[surface_id];
surface_t *surface = surfaces[surface_index].get();
if (surface == nullptr) if (surface == nullptr)
{ {
return -1; return -1;
} }
if (height_id >= MAX_CLUSTER_IN_SURFACE) voxel_cluster_t *cluster = surface->get_cluster(layer);
{
return -1;
}
voxel_cluster_t *cluster = surface->voxel_clusters[height_id].get();
if (cluster == nullptr) if (cluster == nullptr)
{ {
return -1; return -1;
@ -316,88 +187,3 @@ int32_t deerith::get_cluster_last_tick_update(glm::ivec2 surface_id, size_t heig
return cluster->last_update_tick_id; return cluster->last_update_tick_id;
} }
void deerith::get_cluster_voxel_type_id_raw_data(cluster_voxel_type_id_data_t &data, glm::ivec2 surface_id, size_t cluster_height_id)
{
if (cluster_height_id >= MAX_CLUSTER_IN_SURFACE)
{
deerith_warn("tried to read voxel data out of bounds");
return;
}
surface_t *surface = nullptr;
if (surface_id_index_map.contains(surface_id))
{
size_t surface_index = surface_id_index_map[surface_id];
surface = surfaces[surface_index].get();
}
if (surface == nullptr)
{
surface = create_surface(surface_id);
}
voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get();
if (cluster == nullptr)
{
cluster = create_cluster(surface_id, cluster_height_id);
}
data = cluster->data;
}
void deerith::set_cluster_voxel_type_id_raw_data(const cluster_voxel_type_id_data_t &data, glm::ivec2 surface_id, size_t cluster_height_id)
{
if (cluster_height_id >= MAX_CLUSTER_IN_SURFACE)
{
deerith_warn("tried to write voxel data out of bounds");
return;
}
surface_t *surface = nullptr;
if (surface_id_index_map.contains(surface_id))
{
size_t surface_index = surface_id_index_map[surface_id];
surface = surfaces[surface_index].get();
}
if (surface == nullptr)
{
surface = create_surface(surface_id);
}
voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get();
if (cluster == nullptr)
{
cluster = create_cluster(surface_id, cluster_height_id);
}
cluster->data = data;
cluster->last_update_tick_id = get_world_tick();
}
deerith::cluster_voxel_type_id_data_t *deerith::get_cluster_voxel_type_id_raw_ponter(glm::ivec2 surface_id, size_t cluster_height_id)
{
if (cluster_height_id >= MAX_CLUSTER_IN_SURFACE)
{
deerith_warn("tried to write voxel data out of bounds");
return nullptr;
}
surface_t *surface = nullptr;
if (surface_id_index_map.contains(surface_id))
{
size_t surface_index = surface_id_index_map[surface_id];
surface = surfaces[surface_index].get();
}
if (surface == nullptr)
{
return nullptr;
}
voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get();
return &cluster->data;
}

View File

@ -9,15 +9,13 @@ namespace deerith
{ {
struct component_client_environment_knowledge_t struct component_client_environment_knowledge_t
{ {
std::unordered_map<glm::ivec2, bool, surface_pos_hash_t> surface_knowledge; std::unordered_map<glm::ivec3, int32_t, ivec3_hash_t> cluster_knowledge;
std::unordered_map<glm::ivec3, int32_t, world_pos_hash_t> cluster_knowledge;
}; };
void check_client_surface_knowledge(client_t *, component_client_environment_knowledge_t &knowledge, glm::ivec3 position); void check_client_surface_knowledge(client_t *, component_client_environment_knowledge_t &knowledge, glm::ivec3 position);
bool check_client_cluster_knowledge(client_t *, component_client_environment_knowledge_t &knowledge, glm::ivec2 position); bool check_client_cluster_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, surface_t *surface);
void send_surface_info_to_client(client_t *, glm::ivec2); void send_cluster_info_to_client(client_t *, voxel_cluster_t *);
void send_cluster_info_to_client(client_t *, glm::ivec2, size_t);
} }
void deerith::send_voxel_data_to_client(client_t *client) void deerith::send_voxel_data_to_client(client_t *client)
@ -59,58 +57,37 @@ void deerith::check_client_surface_knowledge(client_t *client, component_client_
for (int z = -SURFACE_RADIUS; z <= SURFACE_RADIUS; z++) for (int z = -SURFACE_RADIUS; z <= SURFACE_RADIUS; z++)
{ {
glm::ivec2 surface_id = {surface_x + x, surface_z + z}; glm::ivec2 surface_id = {surface_x + x, surface_z + z};
surface_t *surface = get_surface(surface_id);
if (knowledge.surface_knowledge.contains(surface_id) && knowledge.surface_knowledge[surface_id] == true) if (surface != nullptr)
{ {
if (check_client_cluster_knowledge(client, knowledge, surface_id)) if (check_client_cluster_knowledge(client, knowledge, surface))
{ {
return; return;
} }
} }
}
}
}
if (!knowledge.surface_knowledge.contains(surface_id) || knowledge.surface_knowledge[surface_id] == false) bool deerith::check_client_cluster_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, surface_t *surface)
{ {
knowledge.surface_knowledge[surface_id] = true; for (int i = 0; i < surface->voxel_clusters.size(); i++)
send_surface_info_to_client(client, surface_id);
return;
}
}
}
}
void deerith::send_surface_info_to_client(client_t *client, glm::ivec2 surface_id)
{ {
start_chrono(); voxel_cluster_t *cluster = surface->voxel_clusters[i].get();
packet_surface_data_t surface_data; int32_t cluster_last_update = cluster->last_update_tick_id;
surface_data.surface_id = surface_id;
surface_data.__surface_data = std::make_unique<surface_height_data_t>();
get_surface_height_raw_data(*surface_data.__surface_data, surface_id);
router_send_packet(surface_data, client);
}
bool deerith::check_client_cluster_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, glm::ivec2 position)
{
for (int y = 0; y < MAX_CLUSTER_IN_SURFACE; y++)
{
int32_t cluster_last_update = get_cluster_last_tick_update(position, y);
if (cluster_last_update < 0)
{
continue;
}
glm::ivec3 cluster_pos = glm::ivec3(position.x, y, position.y);
int32_t actual_cluster_kknowledge = -1; int32_t actual_cluster_kknowledge = -1;
if (knowledge.cluster_knowledge.contains(cluster_pos)) glm::ivec3 cluster_id = glm::ivec3(surface->surface_id.x, cluster->layer, surface->surface_id.y);
if (knowledge.cluster_knowledge.contains(cluster_id))
{ {
actual_cluster_kknowledge = knowledge.cluster_knowledge[cluster_pos]; actual_cluster_kknowledge = knowledge.cluster_knowledge[cluster_id];
} }
if (actual_cluster_kknowledge < cluster_last_update) if (actual_cluster_kknowledge < cluster_last_update)
{ {
knowledge.cluster_knowledge[cluster_pos] = cluster_last_update; knowledge.cluster_knowledge[cluster_id] = cluster_last_update;
send_cluster_info_to_client(client, position, y); send_cluster_info_to_client(client, cluster);
return true; return true;
} }
} }
@ -118,15 +95,15 @@ bool deerith::check_client_cluster_knowledge(client_t *client, component_client_
return false; return false;
} }
void deerith::send_cluster_info_to_client(client_t *client, glm::ivec2 surface_pos, size_t cluster_height_id) void deerith::send_cluster_info_to_client(client_t *client, voxel_cluster_t *cluster)
{ {
start_chrono(); start_chrono();
packet_cluster_data_t cluster_data; packet_cluster_data_t cluster_data;
cluster_data.surface_id = surface_pos; cluster_data.surface_id = cluster->surface_id;
cluster_data.cluster_height_id = cluster_height_id; cluster_data.layer = cluster->layer;
cluster_data.__cluster_data = std::make_unique<cluster_voxel_type_id_data_t>(); cluster_data.__cluster_data = std::make_unique<cluster_voxel_type_id_data_t>();
get_cluster_voxel_type_id_raw_data(*cluster_data.__cluster_data, surface_pos, cluster_height_id); *cluster_data.__cluster_data = cluster->data;
router_send_packet(cluster_data, client); router_send_packet(cluster_data, client);
deerith_trace("sent cluster data to client in {} ms", get_chrono_ms()); deerith_trace("sent cluster data to client in {} ms", get_chrono_ms());

View File

@ -9,9 +9,7 @@ namespace deerith
void sandbox::build_world() void sandbox::build_world()
{ {
deerith::set_surface_height(glm::ivec2(2, 2), 5); deerith::set_voxel(1, glm::vec3(0, 0, 0));
deerith::set_surface_height(glm::ivec2(2, 3), 7);
deerith::set_surface_height(glm::ivec2(2, 1), 6);
deerith::set_voxel(1, glm::vec3(2, 2, 2));
deerith::set_voxel(1, glm::vec3(3, 4, 1)); deerith::set_voxel(1, glm::vec3(3, 4, 1));
deerith::set_voxel(1, glm::vec3(2, 4, 1));
} }