created clusters to save data
This commit is contained in:
parent
cc890b56d1
commit
883184c98c
16
deerith_engine_core/include/deerith/world/environment.h
Normal file
16
deerith_engine_core/include/deerith/world/environment.h
Normal 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);
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
#include <deerith/world/voxels.h>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
void init_world();
|
||||
}
|
||||
@ -12,7 +12,7 @@ namespace deerith
|
||||
enum class voxel_material_type_t : int
|
||||
{
|
||||
AIR = 0,
|
||||
OPAQUE_BOX = 1
|
||||
SOLID = 1
|
||||
};
|
||||
|
||||
struct voxel_material_t
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "deerith/core/log.h"
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
220
deerith_engine_core/src/world/environment.cpp
Normal file
220
deerith_engine_core/src/world/environment.cpp
Normal 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));
|
||||
}
|
||||
@ -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
6
sandbox/include/world.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace sandbox
|
||||
{
|
||||
void build_world();
|
||||
}
|
||||
0
sandbox/src/build_world.cpp
Normal file
0
sandbox/src/build_world.cpp
Normal 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...
|
||||
|
||||
|
||||
@ -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))
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user