mirror of
https://github.com/Relintai/godot_voxel.git
synced 2025-01-09 04:59:40 +01:00
Added exclusive area parameter to block processors so they can remove blocks from their queue
This commit is contained in:
parent
561f95a506
commit
efe58f1af6
@ -527,6 +527,8 @@ void VoxelLodTerrain::_process() {
|
||||
VoxelProviderThread::InputData input;
|
||||
|
||||
input.priority_block_position = viewer_block_pos;
|
||||
input.use_exclusive_region = true;
|
||||
input.exclusive_region_extent = get_block_region_extent();
|
||||
|
||||
for (unsigned int lod_index = 0; lod_index < get_lod_count(); ++lod_index) {
|
||||
Lod &lod = _lods[lod_index];
|
||||
@ -598,6 +600,9 @@ void VoxelLodTerrain::_process() {
|
||||
// Send mesh updates
|
||||
{
|
||||
VoxelMeshUpdater::Input input;
|
||||
input.priority_position = viewer_block_pos;
|
||||
input.use_exclusive_region = true;
|
||||
input.exclusive_region_extent = get_block_region_extent();
|
||||
|
||||
for (unsigned int lod_index = 0; lod_index < get_lod_count(); ++lod_index) {
|
||||
Lod &lod = _lods[lod_index];
|
||||
|
@ -73,7 +73,7 @@ void VoxelMeshUpdater::push(const Input &input) {
|
||||
if (index) {
|
||||
// The block is already in the update queue, replace it
|
||||
++replaced_blocks;
|
||||
_shared_input.blocks.write[*index] = block;
|
||||
_shared_input.blocks[*index] = block;
|
||||
|
||||
} else {
|
||||
|
||||
@ -88,6 +88,12 @@ void VoxelMeshUpdater::push(const Input &input) {
|
||||
}
|
||||
|
||||
_shared_input.priority_position = input.priority_position;
|
||||
|
||||
if (input.use_exclusive_region) {
|
||||
_shared_input.use_exclusive_region = true;
|
||||
_shared_input.exclusive_region_extent = input.exclusive_region_extent;
|
||||
}
|
||||
|
||||
should_run = !_shared_input.is_empty();
|
||||
}
|
||||
|
||||
@ -209,11 +215,13 @@ static void scale_mesh_data(VoxelMesher::Output &data, float factor) {
|
||||
// so you won't trash performance with pointless allocations
|
||||
surface[Mesh::ARRAY_VERTEX] = Variant();
|
||||
|
||||
{
|
||||
PoolVector3Array::Write w = positions.write();
|
||||
int len = positions.size();
|
||||
for (int j = 0; j < len; ++j) {
|
||||
w[j] = w[j] * factor;
|
||||
}
|
||||
}
|
||||
|
||||
// Thank you
|
||||
surface[Mesh::ARRAY_VERTEX] = positions;
|
||||
@ -282,9 +290,15 @@ void VoxelMeshUpdater::thread_sync(int queue_index, Stats stats) {
|
||||
// Get input
|
||||
MutexLock lock(_input_mutex);
|
||||
|
||||
_input.blocks.append_array(_shared_input.blocks);
|
||||
append_array(_input.blocks, _shared_input.blocks);
|
||||
|
||||
_input.priority_position = _shared_input.priority_position;
|
||||
|
||||
if (_shared_input.use_exclusive_region) {
|
||||
_input.use_exclusive_region = true;
|
||||
_input.exclusive_region_extent = _shared_input.exclusive_region_extent;
|
||||
}
|
||||
|
||||
_shared_input.blocks.clear();
|
||||
|
||||
for (unsigned int lod_index = 0; lod_index < MAX_LOD; ++lod_index) {
|
||||
@ -307,12 +321,39 @@ void VoxelMeshUpdater::thread_sync(int queue_index, Stats stats) {
|
||||
_output.blocks.clear();
|
||||
}
|
||||
|
||||
// Cancel blocks outside exclusive region
|
||||
//int dropped_count = 0;
|
||||
if (_input.use_exclusive_region) {
|
||||
for (int i = 0; i < _input.blocks.size(); ++i) {
|
||||
const InputBlock &ib = _input.blocks[i];
|
||||
|
||||
Rect3i box = Rect3i::from_center_extents(_input.priority_position >> ib.lod, Vector3i(_input.exclusive_region_extent));
|
||||
|
||||
if (!box.contains(ib.position)) {
|
||||
|
||||
Vector3i shifted_block_pos = _input.blocks.back().position;
|
||||
|
||||
_input.blocks[i] = _input.blocks.back();
|
||||
_input.blocks.pop_back();
|
||||
|
||||
_block_indexes[ib.lod].erase(ib.position);
|
||||
_block_indexes[ib.lod][shifted_block_pos] = i;
|
||||
|
||||
//++dropped_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (dropped_count > 0) {
|
||||
// print_line(String("Dropped {0} blocks to mesh from thread").format(varray(dropped_count)));
|
||||
// }
|
||||
|
||||
if (!_input.blocks.empty() && needs_sort) {
|
||||
// Re-sort priority
|
||||
|
||||
SortArray<VoxelMeshUpdater::InputBlock, BlockUpdateComparator> sorter;
|
||||
sorter.compare.center = _input.priority_position;
|
||||
sorter.sort(_input.blocks.ptrw(), _input.blocks.size());
|
||||
sorter.sort(_input.blocks.data(), _input.blocks.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,10 @@ public:
|
||||
};
|
||||
|
||||
struct Input {
|
||||
Vector<InputBlock> blocks;
|
||||
Vector3i priority_position;
|
||||
std::vector<InputBlock> blocks;
|
||||
Vector3i priority_position; // In LOD0 block coordinates
|
||||
int exclusive_region_extent = 0;
|
||||
bool use_exclusive_region = false;
|
||||
|
||||
bool is_empty() const {
|
||||
return blocks.empty();
|
||||
|
@ -42,10 +42,15 @@ void VoxelProviderThread::push(const InputData &input) {
|
||||
|
||||
// TODO If the same request is sent twice, keep only the latest one
|
||||
|
||||
_shared_input.blocks_to_emerge.append_array(input.blocks_to_emerge);
|
||||
_shared_input.blocks_to_immerge.append_array(input.blocks_to_immerge);
|
||||
append_array(_shared_input.blocks_to_emerge, input.blocks_to_emerge);
|
||||
append_array(_shared_input.blocks_to_immerge, input.blocks_to_immerge);
|
||||
_shared_input.priority_block_position = input.priority_block_position;
|
||||
|
||||
if (input.use_exclusive_region) {
|
||||
_shared_input.use_exclusive_region = true;
|
||||
_shared_input.exclusive_region_extent = input.exclusive_region_extent;
|
||||
}
|
||||
|
||||
should_run = !_shared_input.is_empty();
|
||||
}
|
||||
|
||||
@ -112,11 +117,13 @@ void VoxelProviderThread::thread_func() {
|
||||
stats.min_time = time_taken;
|
||||
stats.max_time = time_taken;
|
||||
} else {
|
||||
if (time_taken < stats.min_time)
|
||||
if (time_taken < stats.min_time) {
|
||||
stats.min_time = time_taken;
|
||||
if (time_taken > stats.max_time)
|
||||
}
|
||||
if (time_taken > stats.max_time) {
|
||||
stats.max_time = time_taken;
|
||||
}
|
||||
}
|
||||
|
||||
EmergeOutput eo;
|
||||
eo.origin_in_voxels = block_origin_in_voxels;
|
||||
@ -137,8 +144,9 @@ void VoxelProviderThread::thread_func() {
|
||||
}
|
||||
}
|
||||
|
||||
if (_thread_exit)
|
||||
if (_thread_exit) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for future wake-up
|
||||
_semaphore->wait();
|
||||
@ -183,12 +191,18 @@ void VoxelProviderThread::thread_sync(int emerge_index, Stats stats) {
|
||||
// Get input
|
||||
MutexLock lock(_input_mutex);
|
||||
|
||||
_input.blocks_to_emerge.append_array(_shared_input.blocks_to_emerge);
|
||||
_input.blocks_to_immerge.append_array(_shared_input.blocks_to_immerge);
|
||||
append_array(_input.blocks_to_emerge, _shared_input.blocks_to_emerge);
|
||||
append_array(_input.blocks_to_immerge, _shared_input.blocks_to_immerge);
|
||||
_input.priority_block_position = _shared_input.priority_block_position;
|
||||
|
||||
if (_shared_input.use_exclusive_region) {
|
||||
_input.use_exclusive_region = true;
|
||||
_input.exclusive_region_extent = _shared_input.exclusive_region_extent;
|
||||
}
|
||||
|
||||
_shared_input.blocks_to_emerge.clear();
|
||||
_shared_input.blocks_to_immerge.clear();
|
||||
_shared_input.use_exclusive_region = false;
|
||||
}
|
||||
|
||||
stats.remaining_blocks = _input.blocks_to_emerge.size();
|
||||
@ -204,12 +218,32 @@ void VoxelProviderThread::thread_sync(int emerge_index, Stats stats) {
|
||||
_output.clear();
|
||||
}
|
||||
|
||||
// Cancel blocks outside exclusive region
|
||||
//int dropped_count = 0;
|
||||
if (_input.use_exclusive_region) {
|
||||
for (int i = 0; i < _input.blocks_to_emerge.size(); ++i) {
|
||||
const EmergeInput &ei = _input.blocks_to_emerge[i];
|
||||
|
||||
Rect3i box = Rect3i::from_center_extents(_input.priority_block_position >> ei.lod, Vector3i(_input.exclusive_region_extent));
|
||||
|
||||
if (!box.contains(ei.block_position)) {
|
||||
_input.blocks_to_emerge[i] = _input.blocks_to_emerge.back();
|
||||
_input.blocks_to_emerge.pop_back();
|
||||
//++dropped_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (dropped_count > 0) {
|
||||
// print_line(String("Dropped {0} blocks to load from thread").format(varray(dropped_count)));
|
||||
// }
|
||||
|
||||
if (!_input.blocks_to_emerge.empty()) {
|
||||
// Re-sort priority
|
||||
|
||||
SortArray<EmergeInput, BlockPositionComparator> sorter;
|
||||
sorter.compare.center = _input.priority_block_position;
|
||||
sorter.sort(_input.blocks_to_emerge.ptrw(), _input.blocks_to_emerge.size());
|
||||
sorter.sort(_input.blocks_to_emerge.data(), _input.blocks_to_emerge.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
#ifndef VOXEL_PROVIDER_THREAD_H
|
||||
#define VOXEL_PROVIDER_THREAD_H
|
||||
|
||||
#include "../math/vector3i.h"
|
||||
#include "../math/rect3i.h"
|
||||
#include <core/resource.h>
|
||||
#include <vector>
|
||||
|
||||
class VoxelProvider;
|
||||
class VoxelBuffer;
|
||||
@ -23,9 +24,11 @@ public:
|
||||
};
|
||||
|
||||
struct InputData {
|
||||
Vector<ImmergeInput> blocks_to_immerge;
|
||||
Vector<EmergeInput> blocks_to_emerge;
|
||||
Vector3i priority_block_position;
|
||||
std::vector<ImmergeInput> blocks_to_immerge;
|
||||
std::vector<EmergeInput> blocks_to_emerge;
|
||||
Vector3i priority_block_position; // In LOD0 block coordinates
|
||||
int exclusive_region_extent = 0;
|
||||
bool use_exclusive_region = false;
|
||||
|
||||
inline bool is_empty() {
|
||||
return blocks_to_emerge.empty() && blocks_to_immerge.empty();
|
||||
|
@ -103,4 +103,9 @@ inline bool is_mesh_empty(Ref<Mesh> mesh_ref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void append_array(std::vector<T> &dst, const std::vector<T> &src) {
|
||||
dst.insert(dst.end(), src.begin(), src.end());
|
||||
}
|
||||
|
||||
#endif // HEADER_VOXEL_UTILITY_H
|
||||
|
Loading…
Reference in New Issue
Block a user