builtin/voxelworld and things: Transmit VoxelRegistry over network and deserialize it in Lua

master
Perttu Ahola 2014-10-19 17:31:32 +03:00
parent 692c0d1418
commit bc4ac09c1a
14 changed files with 293 additions and 144 deletions

View File

@ -40,9 +40,6 @@ local end_of_update_processing_us = 0
local voxel_reg = buildat.createVoxelRegistry()
local atlas_reg = buildat.createAtlasRegistry()
log:info("voxel_reg type: "..dump(buildat.class_info(voxel_reg).name))
log:info("atlas_reg type: "..dump(buildat.class_info(atlas_reg).name))
M.chunk_size_voxels = nil
M.section_size_chunks = nil
M.section_size_voxels = nil
@ -87,6 +84,10 @@ function M.init()
M.chunk_size_voxels:mul_components(M.section_size_chunks)
end)
buildat.sub_packet("voxelworld:voxel_registry", function(data)
voxel_reg:deserialize(data)
end)
buildat.sub_packet("voxelworld:node_voxel_data_updated", function(data)
local values = cereal.binary_input(data, {"object",
{"node_id", "int32_t"},
@ -204,6 +205,9 @@ function M.init()
magic.SubscribeToEvent("Update", function(event_type, event_data)
buildat.profiler_block_begin("Buildat|voxelworld:update")
-- Required for handling device resets (eg. fullscreen toggle)
atlas_reg:update()
--local t0 = buildat.get_time_us()
--local dt = event_data:GetFloat("TimeStep")
update_counter = update_counter + 1

View File

@ -458,6 +458,8 @@ struct Module: public interface::Module, public voxelworld::Interface
}
network::access(m_server, [&](network::Interface *inetwork){
inetwork->send(peer, "voxelworld:init", os.str());
inetwork->send(peer, "voxelworld:voxel_registry",
m_voxel_reg->serialize());
});
}

View File

@ -12,11 +12,11 @@ buildat.safe.disconnect = __buildat_disconnect
buildat.safe.get_time_us = __buildat_get_time_us
buildat.safe.profiler_block_begin = __buildat_profiler_block_begin
buildat.safe.profiler_block_end = __buildat_profiler_block_end
buildat.safe.createVoxelRegistry = createVoxelRegistry
buildat.safe.createAtlasRegistry = createAtlasRegistry
buildat.safe.createVoxelRegistry = __buildat_createVoxelRegistry
buildat.safe.createAtlasRegistry = __buildat_createAtlasRegistry
-- NOTE: Maybe not actually safe
buildat.safe.class_info = class_info -- Luabind class_info()
--buildat.safe.class_info = class_info -- Luabind class_info()
buildat.safe.SpatialUpdateQueue = function()
local internal = __buildat_SpatialUpdateQueue()

View File

@ -6,3 +6,6 @@ Why not use protobuf?
Why not detect -DURHO3D_64BIT automatically in the build system?
- It's not possible
Why not use cereal's versioning system?
- It doesn't support forward compatibility

View File

@ -68,6 +68,106 @@ struct Module: public interface::Module
void init()
{
voxelworld::access(m_server, [&](voxelworld::Interface *ivoxelworld)
{
interface::VoxelRegistry *voxel_reg =
ivoxelworld->get_voxel_reg();
{
interface::VoxelDefinition vdef;
vdef.name.block_name = "air";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
interface::AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "";
seg.total_segments = magic::IntVector2(0, 0);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = interface::EDGEMATERIALID_EMPTY;
voxel_reg->add_voxel(vdef); // id 1
}
{
interface::VoxelDefinition vdef;
vdef.name.block_name = "rock";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
interface::AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/rock.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = interface::EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
voxel_reg->add_voxel(vdef); // id 2
}
{
interface::VoxelDefinition vdef;
vdef.name.block_name = "dirt";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
interface::AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/dirt.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = interface::EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
voxel_reg->add_voxel(vdef); // id 3
}
{
interface::VoxelDefinition vdef;
vdef.name.block_name = "grass";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
interface::AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/grass.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = interface::EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
voxel_reg->add_voxel(vdef); // id 4
}
{
interface::VoxelDefinition vdef;
vdef.name.block_name = "leaves";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
interface::AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/leaves.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = interface::EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
voxel_reg->add_voxel(vdef); // id 5
}
});
m_server->sub_event(this, Event::t("core:start"));
m_server->sub_event(this, Event::t("core:continue"));
m_server->sub_event(this, Event::t("core:tick"));

View File

@ -69,6 +69,9 @@ struct CAtlasRegistry: public AtlasRegistry
m_defs.resize(m_defs.size()+1);
atlas_def = &m_defs[m_defs.size()-1];
atlas_def->id = m_defs.size()-1;
if(segment_def.total_segments.x_ == 0 ||
segment_def.total_segments.y_ == 0)
throw Exception("segment_def.total_segments is zero");
// Calculate segment resolution
magic::IntVector2 seg_res(
seg_img_size.x_ / segment_def.total_segments.x_,

View File

@ -195,6 +195,10 @@ public:
m_voxel_reg->get_cached(back);
const interface::CachedVoxelDefinition *front_def =
m_voxel_reg->get_cached(front);
if(!back_def)
throw Exception(ss_()+"Undefined voxel: back="+itos(back.getId()));
if(!front_def)
throw Exception(ss_()+"Undefined voxel: front="+itos(front.getId()));
if(!back_def || !back_def->physically_solid)
return false;
if(!front_def || !front_def->physically_solid){
@ -300,9 +304,13 @@ public:
m_voxel_reg->get_cached(back);
const interface::CachedVoxelDefinition *front_def =
m_voxel_reg->get_cached(front);
if(!back_def){
if(!back_def)
throw Exception(ss_()+"Undefined voxel: back="+itos(back.getId()));
if(!front_def)
throw Exception(ss_()+"Undefined voxel: front="+itos(front.getId()));
/*if(!back_def){
return false;
}
}*/
else if(back_def->face_draw_type == interface::FaceDrawType::NEVER){
return false;
}
@ -414,7 +422,8 @@ void preload_textures(pv::RawVolume<VoxelInstance> &volume,
VoxelInstance v = volume.getVoxelAt(x, y, z);
const interface::CachedVoxelDefinition *def =
voxel_reg->get_cached(v, atlas_reg);
(void)def; // Unused
if(!def)
throw Exception(ss_()+"Undefined voxel: "+itos(v.getId()));
}
}
}

View File

@ -2,6 +2,9 @@
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
#include "interface/voxel.h"
#include "core/log.h"
#include "interface/voxel_cereal.h"
#include <cereal/archives/portable_binary.hpp>
#include <cereal/types/vector.hpp>
#define MODULE "voxel"
namespace std {
@ -24,9 +27,10 @@ ss_ VoxelName::dump() const
std::ostringstream os(std::ios::binary);
os<<"VoxelName(";
os<<"block_name="<<block_name;
os<<", segment=("<<segment_x<<","<<segment_y<<","<<segment_z<<")";
os<<", rotation_primary="<<rotation_primary;
os<<", rotation_secondary="<<rotation_secondary;
os<<", segment=("<<(int)segment_x<<","<<(int)segment_y<<","
<<(int)segment_z<<")";
os<<", rotation_primary="<<(int)rotation_primary;
os<<", rotation_secondary="<<(int)rotation_secondary;
os<<")";
return os.str();
}
@ -52,108 +56,30 @@ struct CVoxelRegistry: public VoxelRegistry
CVoxelRegistry()
{
m_defs.resize(1); // Id 0 is VOXELTYPEID_UNDEFINEDD
}
// Add test voxels
// TODO: Remove this from here
{
VoxelDefinition vdef;
vdef.name.block_name = "air";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "";
seg.total_segments = magic::IntVector2(0, 0);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = EDGEMATERIALID_EMPTY;
add_voxel(vdef); // id 1
}
{
VoxelDefinition vdef;
vdef.name.block_name = "rock";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/rock.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
add_voxel(vdef); // id 2
}
{
VoxelDefinition vdef;
vdef.name.block_name = "dirt";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/dirt.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
add_voxel(vdef); // id 3
}
{
VoxelDefinition vdef;
vdef.name.block_name = "grass";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/grass.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
add_voxel(vdef); // id 4
}
{
VoxelDefinition vdef;
vdef.name.block_name = "leaves";
vdef.name.segment_x = 0;
vdef.name.segment_y = 0;
vdef.name.segment_z = 0;
vdef.name.rotation_primary = 0;
vdef.name.rotation_secondary = 0;
vdef.handler_module = "";
for(size_t i = 0; i < 6; i++){
AtlasSegmentDefinition &seg = vdef.textures[i];
seg.resource_name = "main/leaves.png";
seg.total_segments = magic::IntVector2(1, 1);
seg.select_segment = magic::IntVector2(0, 0);
}
vdef.edge_material_id = EDGEMATERIALID_GROUND;
vdef.physically_solid = true;
add_voxel(vdef); // id 5
}
void clear()
{
m_defs.clear();
m_cached_defs.clear();
m_name_to_id.clear();
m_defs.resize(1); // Id 0 is VOXELTYPEID_UNDEFINEDD
}
sv_<VoxelDefinition> get_all()
{
sv_<VoxelDefinition> result;
result.insert(result.end(), m_defs.begin()+1, m_defs.end());
return result;
}
VoxelTypeId add_voxel(const VoxelDefinition &def)
{
VoxelTypeId id = m_defs.size();
if(def.id != VOXELTYPEID_UNDEFINED && id != def.id)
throw Exception(ss_()+"add_voxel(): def.id="+itos(def.id)+
"; should be "+itos(id));
// NOTE: This invalidates all previous pointers to cache entries that
// were given out
m_defs.resize(id + 1);
@ -272,29 +198,6 @@ struct CVoxelRegistry: public VoxelRegistry
}
// Caller sets cache.textures_valid = true
}
void serialize(std::ostream &os)
{
// TODO
}
void deserialize(std::istream &is)
{
// TODO
}
ss_ serialize()
{
std::ostringstream os(std::ios::binary);
serialize(os);
return os.str();
}
void deserialize(const ss_ &s)
{
std::istringstream is(s, std::ios::binary);
deserialize(is);
}
};
VoxelRegistry* createVoxelRegistry()
@ -302,5 +205,35 @@ VoxelRegistry* createVoxelRegistry()
return new CVoxelRegistry();
}
void VoxelRegistry::serialize(std::ostream &os)
{
sv_<VoxelDefinition> defs = get_all();
cereal::PortableBinaryOutputArchive archive(os);
archive(defs);
}
void VoxelRegistry::deserialize(std::istream &is)
{
sv_<VoxelDefinition> defs;
cereal::PortableBinaryInputArchive archive(is);
archive(defs);
clear();
for(auto &def : defs)
add_voxel(def);
}
ss_ VoxelRegistry::serialize()
{
std::ostringstream os(std::ios::binary);
serialize(os);
return os.str();
}
void VoxelRegistry::deserialize(const ss_ &s)
{
std::istringstream is(s, std::ios::binary);
deserialize(is);
}
} // interface
// vim: set noet ts=4 sw=4:

View File

@ -0,0 +1,24 @@
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
#pragma once
#include "core/types.h"
#include "interface/atlas.h"
#include "interface/urho3d_cereal.h"
#include <cereal/types/string.hpp>
namespace interface
{
template<class Archive>
void serialize(Archive &archive, AtlasSegmentDefinition &v)
{
uint8_t version = 1;
archive(
version,
v.resource_name,
v.total_segments,
v.select_segment,
v.lod_simulation
);
}
}
// vim: set noet ts=4 sw=4:

View File

@ -0,0 +1,26 @@
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
#pragma once
#include "core/types.h"
#include <cereal/cereal.hpp>
#include <Vector2.h>
#include <Ptr.h>
namespace cereal
{
template<class Archive>
void save(Archive &archive, const Urho3D::IntVector2 &v)
{
archive((int32_t)v.x_);
archive((int32_t)v.y_);
}
template<class Archive>
void load(Archive &archive, Urho3D::IntVector2 &v)
{
int32_t x, y;
archive(x, y);
v.x_ = x;
v.y_ = y;
}
}
// vim: set noet ts=4 sw=4:

View File

@ -16,11 +16,13 @@ namespace interface
struct VoxelName
{
ss_ block_name; // Name of the block this was instanced from
uint segment_x = 0; // Which segment of the block this was instanced from
uint segment_y = 0;
uint segment_z = 0;
uint rotation_primary = 0; // 4 possible rotations when looking at a face
uint rotation_secondary = 0; // 6 possible directions for a face to point to
uint8_t segment_x = 0; // Which segment of the block this was instanced from
uint8_t segment_y = 0;
uint8_t segment_z = 0;
// 4 possible rotations when looking at a face
uint8_t rotation_primary = 0;
// 6 possible directions for a face to point to
uint8_t rotation_secondary = 0;
ss_ dump() const;
bool operator==(const VoxelName &other) const;
@ -81,6 +83,9 @@ namespace interface
{
virtual ~VoxelRegistry(){}
virtual void clear() = 0;
virtual sv_<VoxelDefinition> get_all() = 0;
virtual VoxelTypeId add_voxel(const VoxelDefinition &def) = 0;
virtual const VoxelDefinition* get(const VoxelTypeId &id) = 0;
@ -92,10 +97,10 @@ namespace interface
virtual const CachedVoxelDefinition* get_cached(const VoxelInstance &v,
AtlasRegistry *atlas_reg = nullptr) = 0;
virtual void serialize(std::ostream &os) = 0;
virtual void deserialize(std::istream &is) = 0;
virtual ss_ serialize() = 0;
virtual void deserialize(const ss_ &s) = 0;
void serialize(std::ostream &os);
void deserialize(std::istream &is);
ss_ serialize();
void deserialize(const ss_ &s);
// TODO: Ability to track changes (just some kind of set_dirty()?)
};

View File

@ -0,0 +1,42 @@
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
#pragma once
#include "core/types.h"
#include "interface/voxel.h"
#include "interface/atlas_cereal.h"
#include <cereal/types/string.hpp>
namespace interface
{
template<class Archive>
void serialize(Archive &archive, VoxelName &v)
{
uint8_t version = 1;
archive(
version,
v.block_name,
v.segment_x,
v.segment_y,
v.segment_z,
v.rotation_primary,
v.rotation_secondary
);
}
template<class Archive>
void serialize(Archive &archive, VoxelDefinition &v)
{
uint8_t version = 1;
archive(
version,
v.name,
v.id,
v.textures,
v.handler_module,
v.face_draw_type,
v.edge_material_id,
v.physically_solid
);
}
}
// vim: set noet ts=4 sw=4:

View File

@ -37,7 +37,7 @@ void init_atlas(lua_State *L)
module(L)[
class_<AtlasRegistry, bases<>, sp_<AtlasRegistry>>("AtlasRegistry")
.def("update", &AtlasRegistry::update),
def("createAtlasRegistry", &createAtlasRegistry)
def("__buildat_createAtlasRegistry", &createAtlasRegistry)
];
}

View File

@ -4,8 +4,6 @@
#include "core/log.h"
#include "interface/voxel.h"
#include <luabind/luabind.hpp>
#include <luabind/adopt_policy.hpp>
#include <luabind/pointer_traits.hpp>
#define MODULE "lua_bindings"
using interface::VoxelInstance;
@ -29,7 +27,7 @@ void init_voxel(lua_State *L)
&VoxelRegistry::serialize)
.def("deserialize", (void(VoxelRegistry::*) (const ss_ &))
&VoxelRegistry::deserialize),
def("createVoxelRegistry", &createVoxelRegistry)
def("__buildat_createVoxelRegistry", &createVoxelRegistry)
];
}