voxels are transmited
This commit is contained in:
parent
883184c98c
commit
59e939a1ea
@ -23,17 +23,18 @@ void deerith::process_player_input()
|
||||
movment = glm::vec2(0, 0);
|
||||
}
|
||||
|
||||
component_player_sync_input_t &entity_sync_position = get_component<component_player_sync_input_t>(self_entity);
|
||||
component_client_sync_character_t &entity_sync_position = get_component<component_client_sync_character_t>(self_entity);
|
||||
|
||||
entity_sync_position.move_input = movment;
|
||||
entity_sync_position.position = entity_sync_position.position.read_value() + movment * 0.1f;
|
||||
glm::vec3 movment_3d = glm::vec3(movment.x, 0, movment.y);
|
||||
entity_sync_position.move_input = movment_3d;
|
||||
entity_sync_position.position = entity_sync_position.position.read_value() + movment_3d * 0.1f;
|
||||
}
|
||||
|
||||
void deerith::send_player_input()
|
||||
{
|
||||
if (self_entity == entt::null)
|
||||
return;
|
||||
component_player_sync_input_t &entity_sync_position = get_component<component_player_sync_input_t>(self_entity);
|
||||
component_client_sync_character_t &entity_sync_position = get_component<component_client_sync_character_t>(self_entity);
|
||||
|
||||
packet_update_player_input_t packet{};
|
||||
packet.input_transport.load(entity_sync_position.move_input);
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
#include <deerith/network/packets.h>
|
||||
#include <deerith/network/packets_voxel.h>
|
||||
#include <deerith/world/components.h>
|
||||
#include <deerith/world/environment.h>
|
||||
|
||||
#include <deerith/client/world.h>
|
||||
|
||||
#include <deerith/client/world/world_internals.h>
|
||||
@ -16,6 +18,8 @@ void deerith::setup_base_protocols()
|
||||
router_add_packet_processor<packet_update_entities_coordinates_t>();
|
||||
router_add_packet_processor<packet_destroy_entity_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>();
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -29,7 +33,7 @@ template <>
|
||||
void deerith::process_packet(deerith::packet_create_player_entity_t &packet, client_t *client)
|
||||
{
|
||||
self_entity = create_entity();
|
||||
add_component<component_player_sync_input_t>(self_entity);
|
||||
add_component<component_client_sync_character_t>(self_entity);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -88,4 +92,16 @@ void deerith::process_packet(deerith::packet_voxel_data_definition_t &packet, cl
|
||||
deerith_trace("recive voxel data definition with {} materials and {} types", packet.voxel_materials.size(), packet.voxel_types.size());
|
||||
set_voxel_materials(packet.voxel_materials);
|
||||
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 <>
|
||||
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);
|
||||
}
|
||||
@ -22,14 +22,14 @@ void deerith::render_world()
|
||||
set_transform_to_shader(glm::vec3(0, 0, 0), glm::identity<glm::quat>(), glm::vec3(1, 1, 1), get_lit_shader());
|
||||
get_grid_mesh()->draw_lines();
|
||||
|
||||
auto entities_view = get_entity_registry().view<component_sync_coordinates_t>(entt::exclude<component_player_sync_input_t>);
|
||||
auto entities_view = get_entity_registry().view<component_sync_coordinates_t>(entt::exclude<component_client_sync_character_t>);
|
||||
for (auto [entity, sync_coords] : entities_view.each())
|
||||
{
|
||||
glm::vec2 chords;
|
||||
glm::vec3 chords;
|
||||
if (sync_coords.position.read_synced(chords))
|
||||
{
|
||||
|
||||
glm::vec3 position = glm::vec3(chords.x, 0, chords.y);
|
||||
glm::vec3 position = chords;
|
||||
glm::quat rotation = glm::identity<glm::quat>();
|
||||
glm::vec3 scale = glm::vec3(1, 1, 1);
|
||||
|
||||
@ -42,7 +42,7 @@ void deerith::render_world()
|
||||
}
|
||||
|
||||
// we should expect only one registry
|
||||
auto self_view = get_entity_registry().view<component_sync_coordinates_t, component_player_sync_input_t>();
|
||||
auto self_view = get_entity_registry().view<component_sync_coordinates_t, component_client_sync_character_t>();
|
||||
for (auto [entity, sync_coords, client_sync_coords] : self_view.each())
|
||||
{
|
||||
|
||||
|
||||
@ -16,4 +16,7 @@ namespace deerith
|
||||
|
||||
bool execute_client(const char *server_executable_path, int port);
|
||||
void shutdown_executing_servers();
|
||||
|
||||
void start_chrono();
|
||||
float get_chrono_ms();
|
||||
}
|
||||
@ -31,8 +31,8 @@ namespace deerith
|
||||
static constexpr uint16_t packet_id = 3;
|
||||
static constexpr bool reliable = false;
|
||||
|
||||
sync_variable_transport_t<glm::vec2> position_transport;
|
||||
sync_variable_transport_t<glm::vec2> input_transport;
|
||||
sync_variable_transport_t<glm::vec3> position_transport;
|
||||
sync_variable_transport_t<glm::vec3> input_transport;
|
||||
|
||||
template <typename Archive>
|
||||
void serialize(Archive &archive)
|
||||
@ -80,7 +80,7 @@ namespace deerith
|
||||
static constexpr bool reliable = false;
|
||||
|
||||
std::vector<id_t> entities_ids;
|
||||
std::vector<sync_variable_transport_t<glm::vec2>> positions_to_update;
|
||||
std::vector<sync_variable_transport_t<glm::vec3>> positions_to_update;
|
||||
|
||||
template <typename Archive>
|
||||
void serialize(Archive &archive)
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
#pragma once
|
||||
#include <deerith/engine.h>
|
||||
#include <deerith/world/voxels.h>
|
||||
#include <deerith/world/environment.h>
|
||||
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
#include <cereal/types/array.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
// VOXEL SPECIFIC PACKETS 1xxx
|
||||
|
||||
@ -24,4 +28,58 @@ namespace deerith
|
||||
archive(voxel_types);
|
||||
}
|
||||
};
|
||||
|
||||
struct packet_surface_data_t
|
||||
{
|
||||
static constexpr uint16_t packet_id = 1002;
|
||||
static constexpr bool reliable = true;
|
||||
|
||||
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;
|
||||
|
||||
template <typename Archive>
|
||||
void save(Archive &archive) const
|
||||
{
|
||||
archive(surface_id);
|
||||
archive(cluster_height_id);
|
||||
archive(*__cluster_data);
|
||||
}
|
||||
|
||||
template <typename Archive>
|
||||
void load(Archive &archive)
|
||||
{
|
||||
archive(surface_id);
|
||||
archive(cluster_height_id);
|
||||
|
||||
__cluster_data = std::make_unique<cluster_voxel_type_id_data_t>();
|
||||
archive(*__cluster_data);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -15,4 +15,17 @@ namespace cereal
|
||||
{
|
||||
archive(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive &archive, glm::ivec3 &vec)
|
||||
{
|
||||
archive(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive &archive, glm::ivec2 &vec)
|
||||
{
|
||||
archive(vec.x, vec.y);
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,14 +16,14 @@ namespace deerith
|
||||
};
|
||||
|
||||
// struct for linking a entity to a client
|
||||
struct component_player_sync_input_t
|
||||
struct component_client_sync_character_t
|
||||
{
|
||||
sync_variable_t<glm::vec2> move_input;
|
||||
sync_variable_t<glm::vec2> position;
|
||||
sync_variable_t<glm::vec3> move_input;
|
||||
sync_variable_t<glm::vec3> position;
|
||||
};
|
||||
|
||||
struct component_sync_coordinates_t
|
||||
{
|
||||
sync_variable_t<glm::vec2> position;
|
||||
sync_variable_t<glm::vec3> position;
|
||||
};
|
||||
}
|
||||
@ -1,16 +1,67 @@
|
||||
#pragma once
|
||||
#include <deerith/engine.h>
|
||||
#include <deerith/world/voxels.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
using voxel_coordinates_t = glm::ivec3;
|
||||
using surface_coordinates_t = glm::ivec2;
|
||||
inline constexpr int CLUSTER_SIZE = 32;
|
||||
inline constexpr int MAX_CLUSTER_IN_SURFACE = 16;
|
||||
inline constexpr int STARTING_CLUSTER_HEIGHT = -8;
|
||||
|
||||
// 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);
|
||||
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>;
|
||||
|
||||
voxel_type_id_t get_voxel_id(voxel_coordinates_t coordinates);
|
||||
const voxel_type_t &get_voxel(voxel_coordinates_t coordinates);
|
||||
void set_surface_height(glm::ivec2 surface_pos, surface_height_t height);
|
||||
|
||||
void set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates);
|
||||
voxel_type_id_t get_voxel_id(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);
|
||||
void set_surface_height_raw_data(const surface_height_data_t &data, glm::ivec2 surface_id);
|
||||
|
||||
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);
|
||||
|
||||
int32_t get_cluster_last_tick_update(glm::ivec2 surface_id, size_t height_id);
|
||||
}
|
||||
|
||||
// UTILS
|
||||
namespace deerith
|
||||
{
|
||||
struct environment_settings_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
|
||||
{
|
||||
const std::size_t h1 = std::hash<int>{}(id.x);
|
||||
const std::size_t h2 = std::hash<int>{}(id.y);
|
||||
|
||||
return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
|
||||
}
|
||||
};
|
||||
|
||||
struct world_pos_hash_t
|
||||
{
|
||||
std::size_t operator()(const glm::ivec3 &pos) const noexcept
|
||||
{
|
||||
const std::size_t h1 = std::hash<int>{}(pos.x);
|
||||
const std::size_t h2 = std::hash<int>{}(pos.y);
|
||||
const std::size_t h3 = std::hash<int>{}(pos.z);
|
||||
|
||||
std::size_t seed = h1;
|
||||
seed ^= h2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
seed ^= h3 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -6,6 +6,8 @@
|
||||
namespace deerith
|
||||
{
|
||||
uint32_t tick_id = 0;
|
||||
|
||||
std::chrono::steady_clock::time_point __chrono_start;
|
||||
}
|
||||
|
||||
void deerith::set_tick(uint32_t v)
|
||||
@ -41,4 +43,14 @@ void deerith::wait_till_next_tick()
|
||||
|
||||
last_tick = clock::now();
|
||||
tick_id++;
|
||||
}
|
||||
|
||||
void deerith::start_chrono()
|
||||
{
|
||||
__chrono_start = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
float deerith::get_chrono_ms()
|
||||
{
|
||||
return std::chrono::duration<float, std::milli>(std::chrono::steady_clock::now() - __chrono_start).count();
|
||||
}
|
||||
@ -1,47 +1,46 @@
|
||||
#include <deerith/world/environment.h>
|
||||
#include <deerith/world/world_core.h>
|
||||
#include <array>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <unordered_map>
|
||||
#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] = {};
|
||||
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
|
||||
{
|
||||
surface_id_t surface_id;
|
||||
glm::ivec2 surface_id;
|
||||
|
||||
int layer_height[CLUSTER_SIZE][CLUSTER_SIZE] = {};
|
||||
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<surface_id_t, size_t> surface_id_index_map;
|
||||
std::unordered_map<glm::ivec2, size_t, surface_pos_hash_t> surface_id_index_map;
|
||||
|
||||
voxel_type_id_t get_default_voxel(voxel_coordinates_t);
|
||||
voxel_type_id_t get_default_voxel(glm::ivec3);
|
||||
|
||||
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);
|
||||
glm::ivec2 get_surface_id(glm::ivec3 coords);
|
||||
glm::ivec2 get_surface_id(glm::ivec2 coords);
|
||||
glm::ivec3 get_internal_voxel_coords(glm::ivec3 coords);
|
||||
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(surface_id_t);
|
||||
surface_t *create_surface(glm::ivec2);
|
||||
}
|
||||
|
||||
deerith::surface_t *deerith::create_surface(surface_id_t surface_id)
|
||||
deerith::surface_t *deerith::create_surface(glm::ivec2 surface_id)
|
||||
{
|
||||
std::unique_ptr<surface_t> new_surface = std::make_unique<surface_t>();
|
||||
size_t surface_index = surfaces.size();
|
||||
@ -52,7 +51,7 @@ deerith::surface_t *deerith::create_surface(surface_id_t surface_id)
|
||||
return surfaces.back().get();
|
||||
}
|
||||
|
||||
deerith::voxel_type_id_t get_default_voxel(deerith::voxel_coordinates_t coords)
|
||||
deerith::voxel_type_id_t deerith::get_default_voxel(glm::ivec3 coords)
|
||||
{
|
||||
if (coords.y > 0)
|
||||
{
|
||||
@ -78,10 +77,10 @@ size_t deerith::get_voxel_cluster_height_id(int height)
|
||||
return cluster_height_id;
|
||||
}
|
||||
|
||||
deerith::internal_voxel_id_t deerith::get_internal_voxel_coords(voxel_coordinates_t coords)
|
||||
glm::ivec3 deerith::get_internal_voxel_coords(glm::ivec3 coords)
|
||||
{
|
||||
// this will invert negatives coords but we don't mind
|
||||
internal_voxel_id_t ic = {};
|
||||
glm::ivec3 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));
|
||||
@ -89,10 +88,10 @@ deerith::internal_voxel_id_t deerith::get_internal_voxel_coords(voxel_coordinate
|
||||
return ic;
|
||||
}
|
||||
|
||||
deerith::internal_voxel_id_t deerith::get_internal_voxel_coords(surface_coordinates_t coords, int height = 0)
|
||||
glm::ivec3 deerith::get_internal_voxel_coords(glm::ivec2 coords, int height)
|
||||
{
|
||||
// this will invert negatives coords but we don't mind
|
||||
internal_voxel_id_t ic = {};
|
||||
glm::ivec3 ic = {};
|
||||
ic.x = std::abs(coords.x % (CLUSTER_SIZE));
|
||||
ic.y = std::abs(height % (CLUSTER_SIZE));
|
||||
ic.z = std::abs(coords.y % (CLUSTER_SIZE));
|
||||
@ -100,18 +99,18 @@ deerith::internal_voxel_id_t deerith::get_internal_voxel_coords(surface_coordina
|
||||
return ic;
|
||||
}
|
||||
|
||||
deerith::surface_id_t deerith::get_surface_id(voxel_coordinates_t coords)
|
||||
glm::ivec2 deerith::get_surface_id(glm::ivec3 coords)
|
||||
{
|
||||
surface_id_t surface_id = {};
|
||||
glm::ivec2 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)
|
||||
glm::ivec2 deerith::get_surface_id(glm::ivec2 coords)
|
||||
{
|
||||
surface_id_t surface_id = {};
|
||||
glm::ivec2 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));
|
||||
|
||||
@ -119,9 +118,9 @@ deerith::surface_id_t deerith::get_surface_id(surface_coordinates_t coords)
|
||||
}
|
||||
|
||||
// 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)
|
||||
void deerith::set_surface_height(glm::ivec2 surface_pos, surface_height_t height)
|
||||
{
|
||||
surface_id_t surface_id = get_surface_id(surface_pos);
|
||||
glm::ivec2 surface_id = get_surface_id(surface_pos);
|
||||
|
||||
surface_t *surface = nullptr;
|
||||
if (surface_id_index_map.contains(surface_id))
|
||||
@ -135,13 +134,13 @@ void deerith::set_surface_height(surface_coordinates_t surface_pos, int height)
|
||||
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;
|
||||
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, voxel_coordinates_t coordinates)
|
||||
void deerith::set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates)
|
||||
{
|
||||
surface_id_t surface_id = get_surface_id(coordinates);
|
||||
glm::ivec2 surface_id = get_surface_id(coordinates);
|
||||
|
||||
surface_t *surface = nullptr;
|
||||
if (surface_id_index_map.contains(surface_id))
|
||||
@ -155,7 +154,7 @@ void deerith::set_voxel(voxel_type_id_t voxel_id, voxel_coordinates_t coordinate
|
||||
surface = create_surface(surface_id);
|
||||
}
|
||||
|
||||
internal_voxel_id_t internal_voxel_id = get_internal_voxel_coords(coordinates);
|
||||
glm::ivec3 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)
|
||||
@ -171,12 +170,13 @@ void deerith::set_voxel(voxel_type_id_t voxel_id, voxel_coordinates_t coordinate
|
||||
cluster = surface->voxel_clusters[cluster_height_id].get();
|
||||
}
|
||||
|
||||
cluster->last_update_tick_id = get_world_tick();
|
||||
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)
|
||||
deerith::voxel_type_id_t deerith::get_voxel_id(glm::ivec3 coordinates)
|
||||
{
|
||||
surface_id_t surface_id = get_surface_id(coordinates);
|
||||
glm::ivec2 surface_id = get_surface_id(coordinates);
|
||||
|
||||
if (!surface_id_index_map.contains(surface_id))
|
||||
{
|
||||
@ -197,11 +197,11 @@ deerith::voxel_type_id_t deerith::get_voxel_id(voxel_coordinates_t coordinates)
|
||||
return get_default_voxel(coordinates);
|
||||
}
|
||||
|
||||
internal_voxel_id_t internal_voxel_id = get_internal_voxel_coords(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])
|
||||
if (coordinates.y <= surface->__layer_height[internal_voxel_id.x][internal_voxel_id.y])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -214,7 +214,138 @@ deerith::voxel_type_id_t deerith::get_voxel_id(voxel_coordinates_t coordinates)
|
||||
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)
|
||||
const deerith::voxel_type_t &deerith::get_voxel(glm::ivec3 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)
|
||||
{
|
||||
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(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)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (height_id >= MAX_CLUSTER_IN_SURFACE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
voxel_cluster_t *cluster = surface->voxel_clusters[height_id].get();
|
||||
if (cluster == nullptr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
surface->voxel_clusters[cluster_height_id] = std::make_unique<voxel_cluster_t>();
|
||||
cluster = surface->voxel_clusters[cluster_height_id].get();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
surface->voxel_clusters[cluster_height_id] = std::make_unique<voxel_cluster_t>();
|
||||
cluster = surface->voxel_clusters[cluster_height_id].get();
|
||||
}
|
||||
|
||||
cluster->data = data;
|
||||
cluster->last_update_tick_id = get_world_tick();
|
||||
}
|
||||
@ -1,14 +1,8 @@
|
||||
#pragma once
|
||||
#include <enet/enet.h>
|
||||
#include <vector>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
int init_network();
|
||||
void shutdown_network();
|
||||
|
||||
bool init_server(int port);
|
||||
void flush_network_events();
|
||||
|
||||
void load_base_protocols();
|
||||
}
|
||||
@ -4,17 +4,21 @@
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
void update_players_characters();
|
||||
// Client lifecycle
|
||||
void client_connects(client_t *client);
|
||||
void client_disconnects(client_t *client);
|
||||
|
||||
void send_entity_data();
|
||||
|
||||
void send_create_entity_to_all_clients(entity_t ent);
|
||||
// Entity management
|
||||
void send_create_entity_to_client(entity_t ent, client_t *client);
|
||||
void send_create_actual_entities_to_client(client_t *client);
|
||||
|
||||
void send_voxel_data_to_client(client_t *client);
|
||||
|
||||
void send_create_entity_to_all_clients(entity_t ent);
|
||||
void send_create_all_entities_to_client(client_t *client);
|
||||
void send_delete_entity_to_all_clients(entity_t ent);
|
||||
|
||||
// Player updates
|
||||
void update_players_characters();
|
||||
|
||||
// Data synchronization
|
||||
void send_entity_data();
|
||||
void send_voxel_data_to_client(client_t *client);
|
||||
void send_clients_environment_data();
|
||||
}
|
||||
7
deerith_engine_server/include/deerith/server/network.h
Normal file
7
deerith_engine_server/include/deerith/server/network.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
int init_network();
|
||||
void shutdown_network();
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
#include <deerith/engine.h>
|
||||
|
||||
#include <deerith/server/network/network_internals.h>
|
||||
#include <deerith/server/network.h>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
#include <deerith/core/log.h>
|
||||
#include <deerith/engine.h>
|
||||
|
||||
#include <deerith/network/client.h>
|
||||
#include <deerith/network/router.h>
|
||||
#include <deerith/network/packets.h>
|
||||
|
||||
#include <deerith/server/world.h>
|
||||
#include <deerith/server/network.h>
|
||||
#include <deerith/server/internals/network.h>
|
||||
#include <deerith/server/internals/world.h>
|
||||
|
||||
#include <enet/enet.h>
|
||||
|
||||
@ -11,33 +15,15 @@
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <deerith/server/network/network_internals.h>
|
||||
#include <deerith/server/world/world_internals.h>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
ENetHost *server;
|
||||
|
||||
std::vector<std::unique_ptr<client_t>> clients;
|
||||
|
||||
void create_client(ENetPeer *peer);
|
||||
void delete_client(client_t *client);
|
||||
}
|
||||
|
||||
void deerith::delete_client(client_t *client)
|
||||
{
|
||||
auto it = std::find_if(
|
||||
clients.begin(),
|
||||
clients.end(),
|
||||
[client](const std::unique_ptr<client_t> &ptr)
|
||||
{ return ptr.get() == client; });
|
||||
|
||||
if (it != clients.end())
|
||||
{
|
||||
clients.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
bool deerith::init_server(int port)
|
||||
{
|
||||
ENetAddress address = {0};
|
||||
@ -111,4 +97,16 @@ void deerith::create_client(ENetPeer *peer)
|
||||
|
||||
clients.push_back(std::move(client));
|
||||
client_connects((client_t *)peer->data);
|
||||
}
|
||||
|
||||
void deerith::delete_client(client_t *client)
|
||||
{
|
||||
for (auto it = clients.begin(); it != clients.end(); ++it)
|
||||
{
|
||||
if (it->get() == client)
|
||||
{
|
||||
clients.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
#include <deerith/server/world.h>
|
||||
|
||||
#include <deerith/server/network/network_internals.h>
|
||||
#include <deerith/server/world/world_internals.h>
|
||||
#include <deerith/server/network.h>
|
||||
#include <deerith/server/internals/world.h>
|
||||
|
||||
void deerith::client_connects(client_t *client)
|
||||
{
|
||||
@ -21,7 +21,7 @@ void deerith::client_connects(client_t *client)
|
||||
|
||||
// create entity player entity
|
||||
entity_t entity = create_entity();
|
||||
component_player_sync_input_t &position_sync = add_component<component_player_sync_input_t>(entity);
|
||||
component_client_sync_character_t &position_sync = add_component<component_client_sync_character_t>(entity);
|
||||
|
||||
packet_create_player_entity_t create_player_entity;
|
||||
router_send_packet(create_player_entity, client);
|
||||
@ -32,12 +32,12 @@ void deerith::client_connects(client_t *client)
|
||||
|
||||
send_create_entity_to_all_clients(entity);
|
||||
|
||||
// we do this the last to avoid send_create_entity_to_all_clients send_create_actual_entities_to_client create the same entity for the player
|
||||
// we do this the last to avoid send_create_entity_to_all_clients send_create_all_entities_to_client create the same entity for the player
|
||||
component_client_link_t &link = add_component<component_client_link_t>(entity);
|
||||
client->entity_id = entity;
|
||||
link.client = client;
|
||||
|
||||
send_create_actual_entities_to_client(client);
|
||||
send_create_all_entities_to_client(client);
|
||||
}
|
||||
|
||||
void deerith::client_disconnects(client_t *client)
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
#include <deerith/engine.h>
|
||||
|
||||
#include <deerith/world/components.h>
|
||||
#include <deerith/network/packets.h>
|
||||
#include <deerith/network/router.h>
|
||||
#include <deerith/network/client.h>
|
||||
|
||||
#include <deerith/server/world.h>
|
||||
#include <deerith/server/internals/world.h>
|
||||
#include <deerith/server/internals/network.h>
|
||||
|
||||
#include <deerith/server/network/network_internals.h>
|
||||
#include <deerith/server/world/world_internals.h>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
|
||||
}
|
||||
void deerith::load_base_protocols()
|
||||
{
|
||||
router_add_packet_processor<packet_update_player_input_t>();
|
||||
@ -22,7 +17,7 @@ template <>
|
||||
void deerith::process_packet(packet_update_player_input_t &packet, client_t *client)
|
||||
{
|
||||
entity_t entity = client->entity_id;
|
||||
component_player_sync_input_t &sync_client = get_component<component_player_sync_input_t>(entity);
|
||||
component_client_sync_character_t &sync_client = get_component<component_client_sync_character_t>(entity);
|
||||
|
||||
packet.input_transport.recive(sync_client.move_input);
|
||||
packet.position_transport.recive(sync_client.position);
|
||||
@ -74,7 +69,7 @@ void deerith::send_delete_entity_to_all_clients(entity_t ent)
|
||||
}
|
||||
}
|
||||
|
||||
void deerith::send_create_actual_entities_to_client(client_t *client)
|
||||
void deerith::send_create_all_entities_to_client(client_t *client)
|
||||
{
|
||||
auto entities_view = get_entity_registry().view<component_network_id_t>();
|
||||
|
||||
|
||||
@ -1,10 +1,23 @@
|
||||
#include <deerith/server/world/world_internals.h>
|
||||
#include <deerith/server/internals/world.h>
|
||||
|
||||
#include <deerith/world/environment.h>
|
||||
#include <deerith/network/packets_voxel.h>
|
||||
#include <deerith/network/router.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
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, world_pos_hash_t> cluster_knowledge;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
void send_surface_info_to_client(client_t *, glm::ivec2);
|
||||
void send_cluster_info_to_client(client_t *, glm::ivec2, size_t);
|
||||
}
|
||||
|
||||
void deerith::send_voxel_data_to_client(client_t *client)
|
||||
@ -14,4 +27,107 @@ void deerith::send_voxel_data_to_client(client_t *client)
|
||||
voxel_data_definition.voxel_types = get_voxel_type_vector();
|
||||
|
||||
router_send_packet(voxel_data_definition, client);
|
||||
}
|
||||
|
||||
void deerith::send_clients_environment_data()
|
||||
{
|
||||
// temp solution to assign this component to clients that don't have it
|
||||
{
|
||||
auto no_surface_knowledge_component_clients = get_entity_registry().view<component_client_link_t>(entt::exclude<component_client_environment_knowledge_t>);
|
||||
for (auto [entity, client_link] : no_surface_knowledge_component_clients.each())
|
||||
{
|
||||
add_component<component_client_environment_knowledge_t>(entity);
|
||||
}
|
||||
}
|
||||
|
||||
auto update_surface_knowledge_to_clients = get_entity_registry().view<component_client_link_t, component_sync_coordinates_t, component_client_environment_knowledge_t>();
|
||||
for (auto [entity, client_link, entity_position, surface_knowledge] : update_surface_knowledge_to_clients.each())
|
||||
{
|
||||
check_client_surface_knowledge(client_link.client, surface_knowledge, entity_position.position.read_value());
|
||||
}
|
||||
}
|
||||
|
||||
void deerith::check_client_surface_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, glm::ivec3 position)
|
||||
{
|
||||
const int surface_x = static_cast<int>(std::floor(position.x / CLUSTER_SIZE));
|
||||
const int surface_z = static_cast<int>(std::floor(position.z / CLUSTER_SIZE));
|
||||
|
||||
const int SURFACE_RADIUS = 4;
|
||||
|
||||
for (int x = -SURFACE_RADIUS; x <= SURFACE_RADIUS; x++)
|
||||
{
|
||||
for (int z = -SURFACE_RADIUS; z <= SURFACE_RADIUS; z++)
|
||||
{
|
||||
glm::ivec2 surface_id = {surface_x + x, surface_z + z};
|
||||
|
||||
if (knowledge.surface_knowledge.contains(surface_id) && knowledge.surface_knowledge[surface_id] == true)
|
||||
{
|
||||
if (check_client_cluster_knowledge(client, knowledge, surface_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!knowledge.surface_knowledge.contains(surface_id) || knowledge.surface_knowledge[surface_id] == false)
|
||||
{
|
||||
knowledge.surface_knowledge[surface_id] = true;
|
||||
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();
|
||||
packet_surface_data_t surface_data;
|
||||
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;
|
||||
if (knowledge.cluster_knowledge.contains(cluster_pos))
|
||||
{
|
||||
actual_cluster_kknowledge = knowledge.cluster_knowledge[cluster_pos];
|
||||
}
|
||||
|
||||
if (actual_cluster_kknowledge < cluster_last_update)
|
||||
{
|
||||
knowledge.cluster_knowledge[cluster_pos] = cluster_last_update;
|
||||
send_cluster_info_to_client(client, position, y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void deerith::send_cluster_info_to_client(client_t *client, glm::ivec2 surface_pos, size_t cluster_height_id)
|
||||
{
|
||||
start_chrono();
|
||||
packet_cluster_data_t cluster_data;
|
||||
cluster_data.surface_id = surface_pos;
|
||||
cluster_data.cluster_height_id = cluster_height_id;
|
||||
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);
|
||||
|
||||
router_send_packet(cluster_data, client);
|
||||
deerith_trace("sent cluster data to client in {}ms", get_chrono_ms());
|
||||
}
|
||||
@ -1,37 +1,16 @@
|
||||
#include <deerith/engine.h>
|
||||
#include <deerith/server/world.h>
|
||||
#include <deerith/core/log.h>
|
||||
#include <deerith/network/router.h>
|
||||
|
||||
#include <deerith/server/network/network_internals.h>
|
||||
#include <deerith/server/world/world_internals.h>
|
||||
|
||||
#include <deerith/world/components.h>
|
||||
#include <deerith/network/packets.h>
|
||||
|
||||
#include <csignal>
|
||||
#include <atomic>
|
||||
#include <deerith/server/internals/world.h>
|
||||
#include <deerith/server/internals/network.h>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
int world_tick = 0;
|
||||
void world_simulation();
|
||||
|
||||
std::atomic<bool> running = true;
|
||||
|
||||
void create_client(ENetPeer *peer);
|
||||
void handle_signal(int signal);
|
||||
}
|
||||
|
||||
void deerith::handle_signal(int signal)
|
||||
{
|
||||
if (signal == SIGTERM)
|
||||
running = false;
|
||||
void server_loop();
|
||||
}
|
||||
|
||||
void deerith::run_world(int port)
|
||||
{
|
||||
std::signal(SIGTERM, handle_signal);
|
||||
|
||||
if (!init_server(port))
|
||||
{
|
||||
deerith_error("could not init server");
|
||||
@ -39,13 +18,13 @@ void deerith::run_world(int port)
|
||||
}
|
||||
|
||||
deerith_trace("server init on port {}", port);
|
||||
while (running)
|
||||
while (true)
|
||||
{
|
||||
world_simulation();
|
||||
server_loop();
|
||||
}
|
||||
}
|
||||
|
||||
void deerith::world_simulation()
|
||||
void deerith::server_loop()
|
||||
{
|
||||
flush_network_events();
|
||||
|
||||
@ -54,6 +33,8 @@ void deerith::world_simulation()
|
||||
|
||||
if (get_world_tick() % 2 == 0)
|
||||
{
|
||||
send_clients_environment_data();
|
||||
|
||||
send_entity_data();
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
#include <deerith/server/world/world_internals.h>
|
||||
#include <deerith/server/internals/world.h>
|
||||
|
||||
#include <deerith/server/world.h>
|
||||
#include <deerith/world/components.h>
|
||||
#include <deerith/network/packets.h>
|
||||
#include <deerith/network/router.h>
|
||||
|
||||
void deerith::update_players_characters()
|
||||
{
|
||||
auto view = get_entity_registry().view<component_player_sync_input_t, component_client_link_t, component_sync_coordinates_t>();
|
||||
auto view = get_entity_registry().view<component_client_sync_character_t, component_client_link_t, component_sync_coordinates_t>();
|
||||
|
||||
for (auto [entity, position_input, client, sync_coords] : view.each())
|
||||
{
|
||||
glm::vec2 ps{};
|
||||
glm::vec3 ps{};
|
||||
if (position_input.position.read_synced(ps))
|
||||
{
|
||||
sync_coords.position = ps;
|
||||
@ -32,7 +31,7 @@ void deerith::send_entity_data()
|
||||
{
|
||||
sync_entities_coordinates.entities_ids.push_back(network_id.network_id);
|
||||
sync_entities_coordinates.positions_to_update.push_back({});
|
||||
sync_variable_transport_t<glm::vec2> &position_trasport = sync_entities_coordinates.positions_to_update.back();
|
||||
sync_variable_transport_t<glm::vec3> &position_trasport = sync_entities_coordinates.positions_to_update.back();
|
||||
position_trasport.load(sync_coords.position);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
#include "world.h"
|
||||
|
||||
#include <deerith/world/environment.h>
|
||||
|
||||
namespace deerith
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sandbox::build_world()
|
||||
{
|
||||
deerith::set_surface_height(glm::ivec2(2, 2), 5);
|
||||
deerith::set_voxel(1, glm::vec3(2, 2, 2));
|
||||
}
|
||||
@ -18,7 +18,7 @@ int main(int argc, const char **argv)
|
||||
sandbox::define_voxel_materials();
|
||||
sandbox::define_voxels_types();
|
||||
|
||||
// sandbox::build_world();
|
||||
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