Added lod
parameter to VoxelProvider
This commit is contained in:
parent
c80a24ef0b
commit
5851e4849f
@ -1,43 +1,47 @@
|
||||
#include "voxel_provider.h"
|
||||
#include <core/script_language.h>
|
||||
|
||||
void VoxelProvider::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels) {
|
||||
void VoxelProvider::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) {
|
||||
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 = origin_in_voxels.to_vec3();
|
||||
const Variant *args[2] = { &arg1, &arg2 };
|
||||
Variant arg3 = lod;
|
||||
const Variant *args[3] = { &arg1, &arg2, &arg3 };
|
||||
//Variant::CallError err; // wut
|
||||
script->call_multilevel("emerge_block", args, 2);
|
||||
script->call("emerge_block", args, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelProvider::immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels) {
|
||||
void VoxelProvider::immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod) {
|
||||
ERR_FAIL_COND(buffer.is_null());
|
||||
ScriptInstance *script = get_script_instance();
|
||||
if (script) {
|
||||
// Call script to save buffer
|
||||
Variant arg1 = buffer;
|
||||
Variant arg2 = origin_in_voxels.to_vec3();
|
||||
const Variant *args[2] = { &arg1, &arg2 };
|
||||
Variant arg3 = lod;
|
||||
const Variant *args[3] = { &arg1, &arg2, &arg3 };
|
||||
//Variant::CallError err; // wut
|
||||
script->call_multilevel("immerge_block", args, 2);
|
||||
script->call("immerge_block", args, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelProvider::_emerge_block(Ref<VoxelBuffer> out_buffer, Vector3 origin_in_voxels) {
|
||||
emerge_block(out_buffer, Vector3i(origin_in_voxels));
|
||||
void VoxelProvider::_emerge_block(Ref<VoxelBuffer> out_buffer, Vector3 origin_in_voxels, int lod) {
|
||||
ERR_FAIL_COND(lod < 0);
|
||||
emerge_block(out_buffer, Vector3i(origin_in_voxels), lod);
|
||||
}
|
||||
|
||||
void VoxelProvider::_immerge_block(Ref<VoxelBuffer> buffer, Vector3 origin_in_voxels) {
|
||||
immerge_block(buffer, Vector3i(origin_in_voxels));
|
||||
void VoxelProvider::_immerge_block(Ref<VoxelBuffer> buffer, Vector3 origin_in_voxels, int lod) {
|
||||
ERR_FAIL_COND(lod < 0);
|
||||
immerge_block(buffer, Vector3i(origin_in_voxels), lod);
|
||||
}
|
||||
|
||||
void VoxelProvider::_bind_methods() {
|
||||
// Note: C++ inheriting classes don't need to re-bind these, because they are bindings that call the actual virtual methods
|
||||
|
||||
ClassDB::bind_method(D_METHOD("emerge_block", "out_buffer", "origin_in_voxels"), &VoxelProvider::_emerge_block);
|
||||
ClassDB::bind_method(D_METHOD("immerge_block", "buffer", "origin_in_voxels"), &VoxelProvider::_immerge_block);
|
||||
ClassDB::bind_method(D_METHOD("emerge_block", "out_buffer", "origin_in_voxels", "lod"), &VoxelProvider::_emerge_block);
|
||||
ClassDB::bind_method(D_METHOD("immerge_block", "buffer", "origin_in_voxels", "lod"), &VoxelProvider::_immerge_block);
|
||||
}
|
||||
|
@ -7,14 +7,14 @@
|
||||
class VoxelProvider : public Resource {
|
||||
GDCLASS(VoxelProvider, Resource)
|
||||
public:
|
||||
virtual void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels);
|
||||
virtual void immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels);
|
||||
virtual void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod);
|
||||
virtual void immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
void _emerge_block(Ref<VoxelBuffer> out_buffer, Vector3 origin_in_voxels);
|
||||
void _immerge_block(Ref<VoxelBuffer> buffer, Vector3 origin_in_voxels);
|
||||
void _emerge_block(Ref<VoxelBuffer> out_buffer, Vector3 origin_in_voxels, int lod);
|
||||
void _immerge_block(Ref<VoxelBuffer> buffer, Vector3 origin_in_voxels, int lod);
|
||||
};
|
||||
|
||||
#endif // VOXEL_PROVIDER_H
|
||||
|
@ -41,7 +41,12 @@ inline float get_height_blurred(Image &im, int x, int y) {
|
||||
|
||||
} // namespace
|
||||
|
||||
void VoxelProviderImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels) {
|
||||
void VoxelProviderImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels, int lod) {
|
||||
|
||||
if (lod != 0) {
|
||||
// TODO Handle higher lods
|
||||
return;
|
||||
}
|
||||
|
||||
int ox = origin_in_voxels.x;
|
||||
int oy = origin_in_voxels.y;
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
void set_channel(VoxelBuffer::ChannelId channel);
|
||||
int get_channel() const;
|
||||
|
||||
void emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels);
|
||||
void emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels, int lod);
|
||||
|
||||
private:
|
||||
static void _bind_methods();
|
||||
|
@ -29,22 +29,27 @@ void VoxelProviderTest::set_pattern_offset(Vector3i offset) {
|
||||
_pattern_offset = offset;
|
||||
}
|
||||
|
||||
void VoxelProviderTest::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin) {
|
||||
void VoxelProviderTest::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin, int lod) {
|
||||
ERR_FAIL_COND(out_buffer.is_null());
|
||||
|
||||
if (lod != 0) {
|
||||
// TODO Handle higher lods
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_mode) {
|
||||
|
||||
case MODE_FLAT:
|
||||
generate_block_flat(**out_buffer, origin);
|
||||
generate_block_flat(**out_buffer, origin, lod);
|
||||
break;
|
||||
|
||||
case MODE_WAVES:
|
||||
generate_block_waves(**out_buffer, origin);
|
||||
generate_block_waves(**out_buffer, origin, lod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelProviderTest::generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin) {
|
||||
void VoxelProviderTest::generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
|
||||
|
||||
// TODO Don't expect a block pos, but a voxel pos!
|
||||
Vector3i size = out_buffer.get_size();
|
||||
@ -62,7 +67,7 @@ void VoxelProviderTest::generate_block_flat(VoxelBuffer &out_buffer, Vector3i or
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelProviderTest::generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin) {
|
||||
void VoxelProviderTest::generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
|
||||
|
||||
// TODO Don't expect a block pos, but a voxel pos!
|
||||
Vector3i size = out_buffer.get_size();
|
||||
|
@ -14,7 +14,7 @@ public:
|
||||
|
||||
VoxelProviderTest();
|
||||
|
||||
virtual void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin);
|
||||
virtual void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin, int lod);
|
||||
|
||||
void set_mode(Mode mode);
|
||||
Mode get_mode() const { return _mode; }
|
||||
@ -29,8 +29,8 @@ public:
|
||||
void set_pattern_offset(Vector3i offset);
|
||||
|
||||
protected:
|
||||
void generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin);
|
||||
void generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin);
|
||||
void generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin, int lod);
|
||||
void generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin, int lod);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -89,7 +89,7 @@ void VoxelProviderThread::thread_func() {
|
||||
|
||||
if (!_input.blocks_to_emerge.empty()) {
|
||||
|
||||
Vector3i block_pos = _input.blocks_to_emerge[emerge_index];
|
||||
EmergeInput block = _input.blocks_to_emerge[emerge_index];
|
||||
++emerge_index;
|
||||
|
||||
if (emerge_index >= _input.blocks_to_emerge.size()) {
|
||||
@ -101,9 +101,9 @@ void VoxelProviderThread::thread_func() {
|
||||
buffer->create(bs, bs, bs);
|
||||
|
||||
// Query voxel provider
|
||||
Vector3i block_origin_in_voxels = block_pos * bs;
|
||||
Vector3i block_origin_in_voxels = block.block_position * bs;
|
||||
uint64_t time_before = OS::get_singleton()->get_ticks_usec();
|
||||
_voxel_provider->emerge_block(buffer, block_origin_in_voxels);
|
||||
_voxel_provider->emerge_block(buffer, block_origin_in_voxels, block.lod);
|
||||
uint64_t time_taken = OS::get_singleton()->get_ticks_usec() - time_before;
|
||||
|
||||
// Do some stats
|
||||
@ -148,9 +148,12 @@ void VoxelProviderThread::thread_func() {
|
||||
// Sorts distance to viewer
|
||||
// The closest block will be the first one in the array
|
||||
struct BlockPositionComparator {
|
||||
// In LOD0 block coordinates
|
||||
Vector3i center;
|
||||
inline bool operator()(const Vector3i &a, const Vector3i &b) const {
|
||||
return a.distance_sq(center) < b.distance_sq(center);
|
||||
inline bool operator()(const VoxelProviderThread::EmergeInput &a, const VoxelProviderThread::EmergeInput &b) const {
|
||||
int da = (a.block_position * (1 << a.lod)).distance_sq(center);
|
||||
int db = (b.block_position * (1 << b.lod)).distance_sq(center);
|
||||
return da < db;
|
||||
}
|
||||
};
|
||||
|
||||
@ -197,7 +200,7 @@ void VoxelProviderThread::thread_sync(int emerge_index, Stats stats) {
|
||||
if (!_input.blocks_to_emerge.empty()) {
|
||||
// Re-sort priority
|
||||
|
||||
SortArray<Vector3i, BlockPositionComparator> sorter;
|
||||
SortArray<EmergeInput, BlockPositionComparator> sorter;
|
||||
sorter.compare.center = _input.priority_block_position;
|
||||
sorter.sort(_input.blocks_to_emerge.ptrw(), _input.blocks_to_emerge.size());
|
||||
}
|
||||
|
@ -14,11 +14,17 @@ public:
|
||||
struct ImmergeInput {
|
||||
Vector3i origin;
|
||||
Ref<VoxelBuffer> voxels;
|
||||
int lod = 0;
|
||||
};
|
||||
|
||||
struct EmergeInput {
|
||||
Vector3i block_position;
|
||||
int lod = 0;
|
||||
};
|
||||
|
||||
struct InputData {
|
||||
Vector<ImmergeInput> blocks_to_immerge;
|
||||
Vector<Vector3i> blocks_to_emerge;
|
||||
Vector<EmergeInput> blocks_to_emerge;
|
||||
Vector3i priority_block_position;
|
||||
|
||||
inline bool is_empty() {
|
||||
@ -29,19 +35,14 @@ public:
|
||||
struct EmergeOutput {
|
||||
Ref<VoxelBuffer> voxels;
|
||||
Vector3i origin_in_voxels;
|
||||
int lod = 0;
|
||||
};
|
||||
|
||||
struct Stats {
|
||||
bool first;
|
||||
uint64_t min_time;
|
||||
uint64_t max_time;
|
||||
int remaining_blocks;
|
||||
|
||||
Stats() :
|
||||
first(true),
|
||||
min_time(0),
|
||||
max_time(0),
|
||||
remaining_blocks(0) {}
|
||||
bool first = true;
|
||||
uint64_t min_time = 0;
|
||||
uint64_t max_time = 0;
|
||||
int remaining_blocks = 0;
|
||||
};
|
||||
|
||||
struct OutputData {
|
||||
|
@ -186,6 +186,7 @@ void VoxelTerrain::make_block_dirty(Vector3i bpos) {
|
||||
_dirty_blocks[bpos] = BLOCK_UPDATE_NOT_SENT;
|
||||
|
||||
} else {
|
||||
|
||||
_blocks_pending_load.push_back(bpos);
|
||||
_dirty_blocks[bpos] = BLOCK_LOAD;
|
||||
}
|
||||
@ -605,8 +606,13 @@ void VoxelTerrain::_process() {
|
||||
VoxelProviderThread::InputData input;
|
||||
|
||||
input.priority_block_position = viewer_block_pos;
|
||||
input.blocks_to_emerge.append_array(_blocks_pending_load);
|
||||
//input.blocks_to_immerge.append_array();
|
||||
|
||||
for (int i = 0; i < _blocks_pending_load.size(); ++i) {
|
||||
VoxelProviderThread::EmergeInput input_block;
|
||||
input_block.block_position = _blocks_pending_load[i];
|
||||
input_block.lod = 0;
|
||||
input.blocks_to_emerge.push_back(input_block);
|
||||
}
|
||||
|
||||
//print_line(String("Sending {0} block requests").format(varray(input.blocks_to_emerge.size())));
|
||||
_blocks_pending_load.clear();
|
||||
|
Loading…
x
Reference in New Issue
Block a user