Voxels are loaded through VoxelProvider

This commit is contained in:
Marc Gilleron 2017-01-02 02:15:57 +01:00
parent 670f46b470
commit c75d1e78b2
5 changed files with 108 additions and 9 deletions

View File

@ -13,6 +13,8 @@ void register_voxel_types() {
ObjectTypeDB::register_type<VoxelLibrary>();
ObjectTypeDB::register_type<VoxelMap>();
ObjectTypeDB::register_type<VoxelTerrain>();
ObjectTypeDB::register_type<VoxelProvider>();
ObjectTypeDB::register_type<VoxelProviderTest>();
}

54
voxel_provider.cpp Normal file
View File

@ -0,0 +1,54 @@
#include "voxel_provider.h"
#include "voxel_map.h"
void VoxelProvider::emerge_block(Ref<VoxelBuffer> 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<VoxelBuffer> 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<VoxelBuffer> out_buffer, Vector3 block_pos) {
emerge_block(out_buffer, Vector3i(block_pos));
}
void VoxelProvider::_immerge_block(Ref<VoxelBuffer> 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<VoxelBuffer> 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);
}
}

29
voxel_provider.h Normal file
View File

@ -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<VoxelBuffer> out_buffer, Vector3i block_pos);
virtual void immerge_block(Ref<VoxelBuffer> buffer, Vector3i block_pos);
protected:
static void _bind_methods();
void _emerge_block(Ref<VoxelBuffer> out_buffer, Vector3 block_pos);
void _immerge_block(Ref<VoxelBuffer> buffer, Vector3 block_pos);
};
class VoxelProviderTest : public VoxelProvider {
OBJ_TYPE(VoxelProviderTest, VoxelProvider)
public:
virtual void load_block(Ref<VoxelBuffer> out_buffer, Vector3i block_pos);
};
#endif // VOXEL_PROVIDER_H

View File

@ -8,12 +8,22 @@ VoxelTerrain::VoxelTerrain(): Node(), _min_y(-4), _max_y(4) {
_mesher = Ref<VoxelMesher>(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<VoxelProvider> provider) {
_provider = provider;
}
Ref<VoxelProvider> 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<VoxelBuffer> buffer_ref = Ref<VoxelBuffer>(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);

View File

@ -4,6 +4,7 @@
#include <scene/main/node.h>
#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<Vector3i> _block_update_queue;
Ref<VoxelMesher> _mesher;
Ref<VoxelProvider> _provider;
public:
VoxelTerrain();
void force_load_blocks(Vector3i center, Vector3i extents);
void set_provider(Ref<VoxelProvider> provider);
Ref<VoxelProvider> get_provider();
void force_load_blocks(Vector3i center, Vector3i extents);
int get_block_update_count();
Ref<VoxelMesher> get_mesher() { return _mesher; }