created clusters to save data

This commit is contained in:
Chewico 2026-10-27 17:30:58 +01:00
parent cc890b56d1
commit 883184c98c
16 changed files with 258 additions and 18 deletions

View File

@ -0,0 +1,16 @@
#pragma once
#include <deerith/world/voxels.h>
#include <glm/glm.hpp>
namespace deerith
{
using voxel_coordinates_t = glm::ivec3;
using surface_coordinates_t = glm::ivec2;
// This sets the terrain layer for default comosition y > height -> 0; y <= height -> 1
void set_surface_height(surface_coordinates_t surface_pos, int height);
void set_voxel(voxel_type_id_t voxel_id, voxel_coordinates_t coordinates);
voxel_type_id_t get_voxel_id(voxel_coordinates_t coordinates);
const voxel_type_t &get_voxel(voxel_coordinates_t coordinates);
}

View File

@ -1,6 +0,0 @@
#include <deerith/world/voxels.h>
namespace deerith
{
void init_world();
}

View File

@ -12,7 +12,7 @@ namespace deerith
enum class voxel_material_type_t : int
{
AIR = 0,
OPAQUE_BOX = 1
SOLID = 1
};
struct voxel_material_t

View File

@ -39,4 +39,6 @@ namespace deerith
component_network_id_t &add_entity_network_with_id(entity_t ent, id_t id);
entity_t get_network_entity_with_id(id_t id);
bool exists_network_entity_with_id(id_t id);
void init_world();
}

View File

@ -1,5 +1,5 @@
#include "deerith/core/log.h"
#include "internal.h"
#include "../internal.h"
#include <memory>

View File

@ -0,0 +1,220 @@
#include <deerith/world/environment.h>
#include <array>
#include <glm/glm.hpp>
#include <memory>
#include <vector>
#include <math.h>
#define CLUSTER_SIZE 32
#define MAX_CLUSTER_IN_SURFACE 16
#define STARTING_CLUSTER_HEIGHT 8
namespace deerith
{
using surface_id_t = glm::ivec2;
using internal_voxel_id_t = glm::ivec3;
struct voxel_cluster_t
{
voxel_type_id_t data[CLUSTER_SIZE][CLUSTER_SIZE][CLUSTER_SIZE] = {};
};
struct surface_t
{
surface_id_t surface_id;
int layer_height[CLUSTER_SIZE][CLUSTER_SIZE] = {};
std::unique_ptr<voxel_cluster_t> voxel_clusters[MAX_CLUSTER_IN_SURFACE] = {};
};
std::vector<std::unique_ptr<surface_t>> surfaces;
std::unordered_map<surface_id_t, size_t> surface_id_index_map;
voxel_type_id_t get_default_voxel(voxel_coordinates_t);
surface_id_t get_surface_id(voxel_coordinates_t coords);
internal_voxel_id_t get_internal_voxel_coords(voxel_coordinates_t coords);
internal_voxel_id_t get_internal_voxel_coords(surface_coordinates_t coords, int height = 0);
size_t get_voxel_cluster_height_id(int height);
surface_t *create_surface(surface_id_t);
}
deerith::surface_t *deerith::create_surface(surface_id_t surface_id)
{
std::unique_ptr<surface_t> new_surface = std::make_unique<surface_t>();
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_type_id_t get_default_voxel(deerith::voxel_coordinates_t coords)
{
if (coords.y > 0)
{
return 0;
}
else
{
return 1;
}
}
size_t deerith::get_voxel_cluster_height_id(int height)
{
// >= 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));
size_t cluster_height_id = normalized_height - STARTING_CLUSTER_HEIGHT;
return cluster_height_id;
}
deerith::internal_voxel_id_t deerith::get_internal_voxel_coords(voxel_coordinates_t coords)
{
// this will invert negatives coords but we don't mind
internal_voxel_id_t ic = {};
ic.x = std::abs(coords.x % (CLUSTER_SIZE));
ic.y = std::abs(coords.y % (CLUSTER_SIZE));
ic.z = std::abs(coords.z % (CLUSTER_SIZE));
return ic;
}
deerith::internal_voxel_id_t deerith::get_internal_voxel_coords(surface_coordinates_t coords, int height = 0)
{
// this will invert negatives coords but we don't mind
internal_voxel_id_t ic = {};
ic.x = std::abs(coords.x % (CLUSTER_SIZE));
ic.y = std::abs(height % (CLUSTER_SIZE));
ic.z = std::abs(coords.y % (CLUSTER_SIZE));
return ic;
}
deerith::surface_id_t deerith::get_surface_id(voxel_coordinates_t coords)
{
surface_id_t surface_id = {};
surface_id.x = std::floor(static_cast<float>(coords.x) / static_cast<float>(CLUSTER_SIZE));
surface_id.y = std::floor(static_cast<float>(coords.z) / static_cast<float>(CLUSTER_SIZE));
return surface_id;
}
deerith::surface_id_t deerith::get_surface_id(surface_coordinates_t coords)
{
surface_id_t surface_id = {};
surface_id.x = std::floor(static_cast<float>(coords.x) / static_cast<float>(CLUSTER_SIZE));
surface_id.y = std::floor(static_cast<float>(coords.y) / static_cast<float>(CLUSTER_SIZE));
return surface_id;
}
// This sets the terrain layer for default comosition y > height -> 0; y <= height -> 1
void deerith::set_surface_height(surface_coordinates_t surface_pos, int height)
{
surface_id_t 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);
}
internal_voxel_id_t 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, voxel_coordinates_t coordinates)
{
surface_id_t surface_id = get_surface_id(coordinates);
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);
}
internal_voxel_id_t internal_voxel_id = get_internal_voxel_coords(coordinates);
size_t cluster_height_id = get_voxel_cluster_height_id(coordinates.y);
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)
{
surface->voxel_clusters[cluster_height_id] = std::make_unique<voxel_cluster_t>();
cluster = surface->voxel_clusters[cluster_height_id].get();
}
cluster->data[internal_voxel_id.x][internal_voxel_id.y][internal_voxel_id.z] = voxel_id;
}
deerith::voxel_type_id_t deerith::get_voxel_id(voxel_coordinates_t coordinates)
{
surface_id_t surface_id = get_surface_id(coordinates);
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)
{
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);
}
internal_voxel_id_t 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 cluster->data[internal_voxel_id.x][internal_voxel_id.y][internal_voxel_id.z];
}
const deerith::voxel_type_t &deerith::get_voxel(voxel_coordinates_t coordinates)
{
return get_voxel_type(get_voxel_id(coordinates));
}

View File

@ -32,19 +32,18 @@ void deerith::run_world(int port)
{
std::signal(SIGTERM, handle_signal);
if (init_server(port))
if (!init_server(port))
{
deerith_error("could not init server");
return;
}
deerith_trace("server init on port {}", port);
while (running)
{
world_simulation();
}
}
else
{
deerith_error("could not init server");
}
}
void deerith::world_simulation()
{

6
sandbox/include/world.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
namespace sandbox
{
void build_world();
}

View File

View File

@ -16,7 +16,7 @@ void sandbox::define_voxel_materials()
{
deerith::voxel_material_t voxel_material;
voxel_material.id = "rock";
voxel_material.material_type = deerith::voxel_material_type_t::OPAQUE_BOX;
voxel_material.material_type = deerith::voxel_material_type_t::SOLID;
// textures...

View File

@ -5,6 +5,7 @@
#include <args/argh.h>
#include "voxels.h"
#include "world.h"
int main(int argc, const char **argv)
{
@ -17,6 +18,8 @@ int main(int argc, const char **argv)
sandbox::define_voxel_materials();
sandbox::define_voxels_types();
// sandbox::build_world();
#ifdef DEBUG
if (cmdl[{"-s", "--single"}] && !deerith::execute_client("../deerith_client/DeerithClient", port))
{