diff --git a/builtin/voxelworld/client_lua/module.lua b/builtin/voxelworld/client_lua/module.lua index 14d8455..051aa0f 100644 --- a/builtin/voxelworld/client_lua/module.lua +++ b/builtin/voxelworld/client_lua/module.lua @@ -9,7 +9,11 @@ local dump = buildat.dump local M = {} local camera_node = nil -local update_counter = 0 +local update_counter = -1 + +M.chunk_size_voxels = nil +M.section_size_chunks = nil +M.section_size_voxels = nil function M.init() log:info("voxelworld.init()") @@ -28,36 +32,71 @@ function M.init() }}, }) log:info(dump(values)) + M.chunk_size_voxels = buildat.IntVector3(values.chunk_size_voxels) + M.section_size_chunks = buildat.IntVector3(values.section_size_chunks) + M.section_size_voxels = + M.chunk_size_voxels:mul_components(M.section_size_chunks) end) magic.SubscribeToEvent("Update", function(event_type, event_data) if camera_node then local p = camera_node.position - if update_counter % 60 == 0 then - --log:info("p: "..p.x..", "..p.y..", "..p.z) - local data = cereal.binary_output({ - p = { - x = p.x, - y = p.y, - z = p.z, - }, - }, {"object", - {"p", {"object", - {"x", "double"}, - {"y", "double"}, - {"z", "double"}, - }}, - }) - buildat.send_packet("voxelworld:camera_position", data) - end update_counter = update_counter + 1 + if update_counter % 60 == 0 then + local section_p = buildat.IntVector3(p):div_components( + M.section_size_voxels):floor() + log:info("p: "..p.x..", "..p.y..", "..p.z.." -> section_p: ".. + section_p.x..", "..section_p.y..", "..section_p.z) + --[[send_get_section(section_p + buildat.IntVector3( 0, 0, 0)) + send_get_section(section_p + buildat.IntVector3(-1, 0, 0)) + send_get_section(section_p + buildat.IntVector3( 1, 0, 0)) + send_get_section(section_p + buildat.IntVector3( 0, 1, 0)) + send_get_section(section_p + buildat.IntVector3( 0,-1, 0)) + send_get_section(section_p + buildat.IntVector3( 0, 0, 1)) + send_get_section(section_p + buildat.IntVector3( 0, 0,-1))]] + end end end) + + local function setup_buildat_voxel_data(node) + local data = node:GetVar("buildat_voxel_data"):GetString() + local w = node:GetVar("buildat_voxel_w"):GetInt() + local h = node:GetVar("buildat_voxel_h"):GetInt() + local d = node:GetVar("buildat_voxel_d"):GetInt() + log:info(dump(node:GetName()).." voxel data size: "..#data) + buildat.set_8bit_voxel_geometry(node, w, h, d, data) + node:SetScale(magic.Vector3(1, 1, 1)) + end + + replicate.sub_sync_node_added({}, function(node) + if not node:GetVar("buildat_voxel_data"):IsEmpty() then + setup_buildat_voxel_data(node) + end + local name = node:GetName() + end) end function M.set_camera(new_camera_node) camera_node = new_camera_node end +function send_get_section(p) + local data = cereal.binary_output({ + p = { + x = p.x, + y = p.y, + z = p.z, + }, + }, {"object", + {"p", {"object", + {"x", "int32_t"}, + {"y", "int32_t"}, + {"z", "int32_t"}, + }}, + }) + --log:info(dump(buildat.bytes(data))) + buildat.send_packet("voxelworld:get_section", data) +end + return M -- vim: set noet ts=4 sw=4: diff --git a/builtin/voxelworld/meta.json b/builtin/voxelworld/meta.json index 485ee75..cdea7a9 100644 --- a/builtin/voxelworld/meta.json +++ b/builtin/voxelworld/meta.json @@ -1,6 +1,7 @@ { "dependencies": [ {"module": "network"}, + {"module": "replicate"}, {"module": "client_lua"} ] } diff --git a/builtin/voxelworld/voxelworld.cpp b/builtin/voxelworld/voxelworld.cpp index 23d6f59..b8b563f 100644 --- a/builtin/voxelworld/voxelworld.cpp +++ b/builtin/voxelworld/voxelworld.cpp @@ -16,7 +16,11 @@ #pragma GCC diagnostic ignored "-Wstrict-aliasing" #include #include -//#include +#include +#include +#include +#include +#include #pragma GCC diagnostic pop #include @@ -44,13 +48,24 @@ void save(Archive &archive, const pv::Vector3DInt16 &v){ } template void load(Archive &archive, pv::Vector3DInt16 &v){ - int16_t x, y, z; - archive((int32_t)x, (int32_t)y, (int32_t)z); + int32_t x, y, z; + archive(x, y, z); v.setX(x); v.setY(y); v.setZ(z); } } +// PolyVox logging helpers +// TODO: Move to a header (core/types_polyvox.h or something) +template<> +ss_ dump(const pv::Vector3DInt16 &v){ + std::ostringstream os(std::ios::binary); + os<<"("<sub_event(this, Event::t("core:tick")); m_server->sub_event(this, Event::t("client_file:files_transmitted")); m_server->sub_event(this, Event::t( - "network:packet_received/voxelworld:camera_position")); + "network:packet_received/voxelworld:get_section")); m_server->access_scene([&](Scene *scene) { @@ -209,12 +224,61 @@ struct Module: public interface::Module, public voxelworld::Interface EVENT_TYPEN("core:tick", on_tick, interface::TickEvent) EVENT_TYPEN("client_file:files_transmitted", on_files_transmitted, client_file::FilesTransmitted) - EVENT_TYPEN("network:packet_received/voxelworld:camera_position", - on_camera_position, network::Packet) + EVENT_TYPEN("network:packet_received/voxelworld:get_section", + on_get_section, network::Packet) } void on_start() { + m_server->access_scene([&](Scene *scene) + { + Context *context = scene->GetContext(); + ResourceCache *cache = context->GetSubsystem(); + + { + Node *n = scene->CreateChild("Base"); + n->SetScale(Vector3(1.0f, 1.0f, 1.0f)); + n->SetPosition(Vector3(0.0f, 0.5f, 0.0f)); + + int w = 10, h = 3, d = 10; + ss_ data = + "222222222211211111211111111111" + "222222222211111111111111111111" + "222222222211111111111111111111" + "222222222211111111111111111111" + "222222222211122111111112111111" + "222233222211123111111112111111" + "222233222211111111111111111111" + "222222222211111111111111111111" + "222222222211111111111111111111" + "222222222211111111111111111111" + ; + + // Convert data to the actually usable voxel type id namespace + // starting from VOXELTYPEID_UNDEFINED=0 + for(size_t i = 0; i < data.size(); i++){ + data[i] = data[i] - '0'; + } + + // Crude way of dynamically defining a voxel model + n->SetVar(StringHash("buildat_voxel_data"), Variant( + magic::String(data.c_str(), data.size()))); + n->SetVar(StringHash("buildat_voxel_w"), Variant(w)); + n->SetVar(StringHash("buildat_voxel_h"), Variant(h)); + n->SetVar(StringHash("buildat_voxel_d"), Variant(d)); + + // Load the same model in here and give it to the physics + // subsystem so that it can be collided to + SharedPtr model(interface:: + create_8bit_voxel_physics_model(context, w, h, d, data, + m_voxel_reg.get())); + + RigidBody *body = n->CreateComponent(); + body->SetFriction(0.75f); + CollisionShape *shape = n->CreateComponent(); + shape->SetTriangleMesh(model, 0, Vector3::ONE); + } + }); } void on_unload() @@ -255,16 +319,17 @@ struct Module: public interface::Module, public voxelworld::Interface }); } - void on_camera_position(const network::Packet &packet) + // TODO: How should nodes be filtered for replication? + void on_get_section(const network::Packet &packet) { - double px, py, pz; + pv::Vector3DInt16 section_p; { std::istringstream is(packet.data, std::ios::binary); cereal::PortableBinaryInputArchive ar(is); - ar(px, py, pz); + ar(section_p); } - log_v(MODULE, "Camera position of C%i: (%f, %f, %f)", - packet.sender, px, py, pz); + log_v(MODULE, "C%i: on_get_section(): " PV3I_FORMAT, + packet.sender, PV3I_PARAMS(section_p)); } // Interface diff --git a/extensions/urho3d/safe_classes.lua b/extensions/urho3d/safe_classes.lua index 56e331d..bf14fb8 100644 --- a/extensions/urho3d/safe_classes.lua +++ b/extensions/urho3d/safe_classes.lua @@ -368,7 +368,9 @@ function M.define(dst, util) ), GetViewport = util.wrap_function({"Renderer", "number"}, function(self, index) - return util.wrap_instance("Viewport", self:GetViewport(index)) + local ret = self:GetViewport(index) + if ret == nil then return nil end + return util.wrap_instance("Viewport", ret) end ), }, diff --git a/games/digger/main/client_lua/init.lua b/games/digger/main/client_lua/init.lua index 193709e..06dc43e 100644 --- a/games/digger/main/client_lua/init.lua +++ b/games/digger/main/client_lua/init.lua @@ -42,32 +42,4 @@ function handle_keydown(event_type, event_data) end magic.SubscribeToEvent("KeyDown", "handle_keydown") -function setup_simple_voxel_data(node) - --buildat.set_simple_voxel_model(node, 3, 3, 3, "010111010111111111010111010") - --node:SetScale(magic.Vector3(0.5, 0.5, 0.5)) - --buildat.set_simple_voxel_model(node, 2, 2, 2, "11101111") - --node:SetScale(magic.Vector3(1, 1, 1)) - --buildat.set_simple_voxel_model(node, 1, 1, 1, "1") - --node:SetScale(magic.Vector3(2, 2, 2)) - - -- Should be something like "11101111" - local data = node:GetVar("simple_voxel_data"):GetString() - local w = node:GetVar("simple_voxel_w"):GetInt() - local h = node:GetVar("simple_voxel_h"):GetInt() - local d = node:GetVar("simple_voxel_d"):GetInt() - log:info(dump(node:GetName()).." voxel data size: "..#data) - buildat.set_8bit_voxel_geometry(node, w, h, d, data) - node:SetScale(magic.Vector3(1, 1, 1)) - - --local object = node:GetComponent("StaticModel") - --object.castShadows = true -end - -magic.sub_sync_node_added({}, function(node) - if not node:GetVar("simple_voxel_data"):IsEmpty() then - setup_simple_voxel_data(node) - end - local name = node:GetName() -end) - -- vim: set noet ts=4 sw=4: