diff --git a/register_types.cpp b/register_types.cpp index c0a7f89..9ca01c4 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -4,6 +4,7 @@ #include "voxel_library.h" #include "voxel_map.h" #include "voxel_terrain.h" +#include "voxel_provider_test.h" void register_voxel_types() { diff --git a/voxel_provider.cpp b/voxel_provider.cpp index dcc37f8..13d8885 100644 --- a/voxel_provider.cpp +++ b/voxel_provider.cpp @@ -44,11 +44,3 @@ void VoxelProvider::_bind_methods() { } -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 index b850106..8415888 100644 --- a/voxel_provider.h +++ b/voxel_provider.h @@ -19,11 +19,4 @@ protected: }; -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_provider_test.cpp b/voxel_provider_test.cpp new file mode 100644 index 0000000..7223853 --- /dev/null +++ b/voxel_provider_test.cpp @@ -0,0 +1,111 @@ +#include "voxel_provider_test.h" +#include "voxel_map.h" + +VARIANT_ENUM_CAST(VoxelProviderTest::Mode) + + +VoxelProviderTest::VoxelProviderTest() { + _mode = MODE_FLAT; + _voxel_type = 1; + _pattern_size = Vector3i(10, 10, 10); +} + +void VoxelProviderTest::set_mode(Mode mode) { + _mode = mode; +} + +void VoxelProviderTest::set_voxel_type(int t) { + _voxel_type = t; +} + +int VoxelProviderTest::get_voxel_type() const { + return _voxel_type; +} + +void VoxelProviderTest::set_pattern_size(Vector3i size) { + ERR_FAIL_COND(size.x < 1 || size.y < 1 || size.z < 1); + _pattern_size = size; +} + +void VoxelProviderTest::set_pattern_offset(Vector3i offset) { + _pattern_offset = offset; +} + +void VoxelProviderTest::emerge_block(Ref out_buffer, Vector3i block_pos) { + ERR_FAIL_COND(out_buffer.is_null()); + + switch(_mode) { + + case MODE_FLAT: + generate_block_flat(**out_buffer, block_pos); + break; + + case MODE_WAVES: + generate_block_waves(**out_buffer, block_pos); + break; + } +} + +void VoxelProviderTest::generate_block_flat(VoxelBuffer & out_buffer, Vector3i block_pos) { + + // TODO Don't expect a block pos, but a voxel pos! + Vector3i size = out_buffer.get_size(); + Vector3i origin = VoxelMap::block_to_voxel(block_pos); + + int rh = _pattern_offset.y - origin.y; + if(rh > size.y) + rh = size.y; + + for(int rz = 0; rz < size.z; ++rz) { + for(int rx = 0; rx < size.x; ++rx) { + for(int ry = 0; ry < rh; ++ry) { + out_buffer.set_voxel(_voxel_type, rx, ry, rz, 0); + } + } + } +} + +void VoxelProviderTest::generate_block_waves(VoxelBuffer & out_buffer, Vector3i block_pos) { + + Vector3i size = out_buffer.get_size(); + Vector3i origin = VoxelMap::block_to_voxel(block_pos) + _pattern_offset; + float amplitude = static_cast(_pattern_size.y); + float period_x = 1.f/static_cast(_pattern_size.x); + float period_z = 1.f/static_cast(_pattern_size.z); + + for(int rz = 0; rz < size.z; ++rz) { + for(int rx = 0; rx < size.x; ++rx) { + + float x = origin.x + rx; + float z = origin.z + rz; + + int h = _pattern_offset.y + amplitude * (Math::cos(x*period_x) + Math::sin(z*period_z)); + int rh = h - origin.y; + if(rh > size.y) + rh = size.y; + + for(int ry = 0; ry < rh; ++ry) { + out_buffer.set_voxel(_voxel_type, rx, ry, rz, 0); + } + } + } +} + +void VoxelProviderTest::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_mode", "mode"), &VoxelProviderTest::set_mode); + ObjectTypeDB::bind_method(_MD("get_mode"), &VoxelProviderTest::get_mode); + + ObjectTypeDB::bind_method(_MD("set_voxel_type", "id"), &VoxelProviderTest::set_voxel_type); + ObjectTypeDB::bind_method(_MD("get_voxel_type"), &VoxelProviderTest::get_voxel_type); + + ObjectTypeDB::bind_method(_MD("set_pattern_size", "size"), &VoxelProviderTest::_set_pattern_size); + ObjectTypeDB::bind_method(_MD("get_pattern_size"), &VoxelProviderTest::_get_pattern_size); + + ObjectTypeDB::bind_method(_MD("set_pattern_offset", "offset"), &VoxelProviderTest::_set_pattern_offset); + ObjectTypeDB::bind_method(_MD("get_pattern_offset"), &VoxelProviderTest::_get_pattern_offset); + + BIND_CONSTANT(MODE_FLAT); + BIND_CONSTANT(MODE_WAVES); +} + diff --git a/voxel_provider_test.h b/voxel_provider_test.h new file mode 100644 index 0000000..b241683 --- /dev/null +++ b/voxel_provider_test.h @@ -0,0 +1,53 @@ +#ifndef VOXEL_PROVIDER_TEST_H +#define VOXEL_PROVIDER_TEST_H + +#include "voxel_provider.h" + + +class VoxelProviderTest : public VoxelProvider { + OBJ_TYPE(VoxelProviderTest, VoxelProvider) + +public: + enum Mode { + MODE_FLAT, + MODE_WAVES + }; + + VoxelProviderTest(); + + virtual void emerge_block(Ref out_buffer, Vector3i block_pos); + + void set_mode(Mode mode); + Mode get_mode() const { return _mode; } + + void set_voxel_type(int t); + int get_voxel_type() const; + + Vector3i get_pattern_size() const { return _pattern_size; } + void set_pattern_size(Vector3i size); + + Vector3i get_pattern_offset() const { return _pattern_offset; } + void set_pattern_offset(Vector3i offset); + +protected: + void generate_block_flat(VoxelBuffer & out_buffer, Vector3i block_pos); + void generate_block_waves(VoxelBuffer & out_buffer, Vector3i block_pos); + + static void _bind_methods(); + + Vector3 _get_pattern_size() const { return get_pattern_size().to_vec3(); } + void _set_pattern_size(Vector3 size) { set_pattern_size(Vector3i(size)); } + + Vector3 _get_pattern_offset() const { return get_pattern_offset().to_vec3(); } + void _set_pattern_offset(Vector3 offset) { set_pattern_offset(Vector3i(offset)); } + +private: + Mode _mode; + int _voxel_type; + Vector3i _pattern_offset; + Vector3i _pattern_size; +}; + + +#endif // VOXEL_PROVIDER_TEST_H +