From c75d1e78b2828ec1527c9c15832adb79f2859d89 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Mon, 2 Jan 2017 02:15:57 +0100 Subject: [PATCH] Voxels are loaded through VoxelProvider --- register_types.cpp | 2 ++ voxel_provider.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++ voxel_provider.h | 29 +++++++++++++++++++++++++ voxel_terrain.cpp | 26 +++++++++++++++------- voxel_terrain.h | 6 +++++- 5 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 voxel_provider.cpp create mode 100644 voxel_provider.h diff --git a/register_types.cpp b/register_types.cpp index 48734d0..c0a7f89 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -13,6 +13,8 @@ void register_voxel_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); } diff --git a/voxel_provider.cpp b/voxel_provider.cpp new file mode 100644 index 0000000..dcc37f8 --- /dev/null +++ b/voxel_provider.cpp @@ -0,0 +1,54 @@ +#include "voxel_provider.h" +#include "voxel_map.h" + + +void VoxelProvider::emerge_block(Ref out_buffer, Vector3i block_pos) { + ERR_FAIL_COND(out_buffer.is_null()); + ScriptInstance * script = get_script_instance(); + if(script) { + // Call script to generate buffer + Variant arg1 = out_buffer; + Variant arg2 = block_pos.to_vec3(); + const Variant * args[2] = { &arg1, &arg2 }; + //Variant::CallError err; // wut + script->call_multilevel("emerge_block", args, 2); + } +} + +void VoxelProvider::immerge_block(Ref buffer, Vector3i block_pos) { + ERR_FAIL_COND(buffer.is_null()); + ScriptInstance * script = get_script_instance(); + if(script) { + // Call script to save buffer + Variant arg1 = buffer; + Variant arg2 = block_pos.to_vec3(); + const Variant * args[2] = { &arg1, &arg2 }; + //Variant::CallError err; // wut + script->call_multilevel("immerge_block", args, 2); + } +} + +void VoxelProvider::_emerge_block(Ref out_buffer, Vector3 block_pos) { + emerge_block(out_buffer, Vector3i(block_pos)); +} + +void VoxelProvider::_immerge_block(Ref buffer, Vector3 block_pos) { + immerge_block(buffer, Vector3i(block_pos)); +} + +void VoxelProvider::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("emerge_block", "out_buffer:VoxelBuffer", "block_pos:Vector3"), &VoxelProvider::_emerge_block); + ObjectTypeDB::bind_method(_MD("immerge_block", "buffer:VoxelBuffer", "block_pos:Vector3"), &VoxelProvider::_immerge_block); + +} + + +void VoxelProviderTest::load_block(Ref out_buffer, Vector3i block_pos) { + ERR_FAIL_COND(out_buffer.is_null()); + //Vector3i voxel_pos = VoxelMap::block_to_voxel(block_pos); + if(block_pos.y < 0) { + out_buffer->fill(1); + } +} + diff --git a/voxel_provider.h b/voxel_provider.h new file mode 100644 index 0000000..b850106 --- /dev/null +++ b/voxel_provider.h @@ -0,0 +1,29 @@ +#ifndef VOXEL_PROVIDER_H +#define VOXEL_PROVIDER_H + +#include "reference.h" +#include "voxel_buffer.h" + + +class VoxelProvider : public Reference { + OBJ_TYPE(VoxelProvider, Reference) +public: + virtual void emerge_block(Ref out_buffer, Vector3i block_pos); + virtual void immerge_block(Ref buffer, Vector3i block_pos); + +protected: + static void _bind_methods(); + + void _emerge_block(Ref out_buffer, Vector3 block_pos); + void _immerge_block(Ref buffer, Vector3 block_pos); +}; + + +class VoxelProviderTest : public VoxelProvider { + OBJ_TYPE(VoxelProviderTest, VoxelProvider) +public: + virtual void load_block(Ref out_buffer, Vector3i block_pos); +}; + + +#endif // VOXEL_PROVIDER_H diff --git a/voxel_terrain.cpp b/voxel_terrain.cpp index d12ddf9..cfe241b 100644 --- a/voxel_terrain.cpp +++ b/voxel_terrain.cpp @@ -8,12 +8,22 @@ VoxelTerrain::VoxelTerrain(): Node(), _min_y(-4), _max_y(4) { _mesher = Ref(memnew(VoxelMesher)); } +// Sorts distance to world origin +// TODO Use distance to camera struct BlockUpdateComparator0 { inline bool operator()(const Vector3i & a, const Vector3i & b) const { return a.length_sq() > b.length_sq(); } }; +void VoxelTerrain::set_provider(Ref provider) { + _provider = provider; +} + +Ref VoxelTerrain::get_provider() { + return _provider; +} + void VoxelTerrain::force_load_blocks(Vector3i center, Vector3i extents) { //Vector3i min = center - extents; //Vector3i max = center + extents + Vector3i(1,1,1); @@ -88,14 +98,12 @@ void VoxelTerrain::update_blocks() { // Create buffer Ref buffer_ref = Ref(memnew(VoxelBuffer)); const Vector3i block_size(VoxelBlock::SIZE, VoxelBlock::SIZE, VoxelBlock::SIZE); - buffer_ref->create(block_size.x, block_size.y, block_size.y); + buffer_ref->create(block_size.x, block_size.y, block_size.z); - // Call script to generate buffer - Variant arg1 = buffer_ref; - Variant arg2 = block_pos.to_vec3(); - const Variant * args[2] = { &arg1, &arg2 }; - Variant::CallError err; // wut - script->call_multilevel("_generate_block", args, 2); + // Query voxel provider + if(!_provider.is_null()) { + _provider->emerge_block(buffer_ref, block_pos); + } // Check script return ERR_FAIL_COND(buffer_ref->get_size() != block_size); @@ -116,7 +124,6 @@ void VoxelTerrain::update_blocks() { } } //update_block_mesh(block_pos); - } // Pop request @@ -184,6 +191,9 @@ void VoxelTerrain::update_block_mesh(Vector3i block_pos) { void VoxelTerrain::_bind_methods() { + ObjectTypeDB::bind_method(_MD("set_provider", "provider:VoxelProvider"), &VoxelTerrain::set_provider); + ObjectTypeDB::bind_method(_MD("get_provider:VoxelProvider"), &VoxelTerrain::get_provider); + ObjectTypeDB::bind_method(_MD("get_block_update_count"), &VoxelTerrain::get_block_update_count); ObjectTypeDB::bind_method(_MD("get_mesher:VoxelMesher"), &VoxelTerrain::get_mesher); diff --git a/voxel_terrain.h b/voxel_terrain.h index 388f088..c813e85 100644 --- a/voxel_terrain.h +++ b/voxel_terrain.h @@ -4,6 +4,7 @@ #include #include "voxel_map.h" #include "voxel_mesher.h" +#include "voxel_provider.h" // Infinite static terrain made of voxels. // It is loaded around VoxelTerrainStreamers. @@ -19,12 +20,15 @@ class VoxelTerrain : public Node /*, public IVoxelMapObserver*/ { Vector _block_update_queue; Ref _mesher; + Ref _provider; public: VoxelTerrain(); - void force_load_blocks(Vector3i center, Vector3i extents); + void set_provider(Ref provider); + Ref get_provider(); + void force_load_blocks(Vector3i center, Vector3i extents); int get_block_update_count(); Ref get_mesher() { return _mesher; }