2019-05-25 15:07:16 +01:00
|
|
|
#include "voxel_data_loader.h"
|
2019-05-25 16:16:03 +01:00
|
|
|
#include "../streams/voxel_stream.h"
|
2019-04-28 17:58:29 +01:00
|
|
|
#include "../util/utility.h"
|
|
|
|
|
2019-05-28 01:10:50 +01:00
|
|
|
VoxelDataLoader::VoxelDataLoader(int thread_count, Ref<VoxelStream> stream, int block_size_pow2) {
|
2018-09-25 00:54:07 +01:00
|
|
|
|
2019-05-28 01:17:28 +01:00
|
|
|
CRASH_COND(stream.is_null());
|
2019-05-28 00:40:09 +01:00
|
|
|
|
2019-05-20 20:48:58 +01:00
|
|
|
Processor processors[Mgr::MAX_JOBS];
|
2018-09-25 00:54:07 +01:00
|
|
|
|
2019-05-28 01:17:28 +01:00
|
|
|
if (stream->is_thread_safe()) {
|
2019-05-28 00:40:09 +01:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < thread_count; ++i) {
|
2019-05-28 01:17:28 +01:00
|
|
|
processors[i].stream = stream;
|
2019-05-28 00:40:09 +01:00
|
|
|
}
|
|
|
|
|
2019-05-28 01:17:28 +01:00
|
|
|
} else if (stream->is_cloneable()) {
|
2019-05-28 00:40:09 +01:00
|
|
|
|
|
|
|
// Note: more than one thread can make sense for generators,
|
|
|
|
// but won't be as useful for file and network streams
|
|
|
|
for (int i = 0; i < thread_count; ++i) {
|
|
|
|
Processor &p = processors[i];
|
|
|
|
p.block_size_pow2 = block_size_pow2;
|
|
|
|
if (i == 0) {
|
2019-05-28 01:17:28 +01:00
|
|
|
p.stream = stream;
|
2019-05-28 00:40:09 +01:00
|
|
|
} else {
|
2019-05-28 01:17:28 +01:00
|
|
|
p.stream = stream->duplicate();
|
2019-05-28 00:40:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (thread_count > 1) {
|
|
|
|
ERR_PRINT("Thread count set to higher than 1, but the stream is neither thread-safe nor cloneable. Capping back to 1 thread.");
|
|
|
|
thread_count = 1;
|
2019-05-12 16:33:25 +01:00
|
|
|
}
|
2019-05-28 01:17:28 +01:00
|
|
|
processors[0].stream = stream;
|
2018-09-25 00:54:07 +01:00
|
|
|
}
|
|
|
|
|
2019-05-20 20:48:58 +01:00
|
|
|
// TODO Re-enable duplicate rejection, was turned off to investigate some bugs
|
2019-05-25 14:31:01 +01:00
|
|
|
_mgr = memnew(Mgr(thread_count, 500, processors, true));
|
2018-09-25 00:54:07 +01:00
|
|
|
}
|
|
|
|
|
2019-05-20 20:48:58 +01:00
|
|
|
VoxelDataLoader::~VoxelDataLoader() {
|
|
|
|
if (_mgr) {
|
|
|
|
memdelete(_mgr);
|
2018-09-25 00:54:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-20 20:48:58 +01:00
|
|
|
void VoxelDataLoader::Processor::process_block(const InputBlockData &input, OutputBlockData &output, Vector3i block_position, unsigned int lod) {
|
2018-09-25 00:54:07 +01:00
|
|
|
|
2019-05-20 20:48:58 +01:00
|
|
|
int bs = 1 << block_size_pow2;
|
|
|
|
Ref<VoxelBuffer> buffer;
|
|
|
|
buffer.instance();
|
|
|
|
buffer->create(bs, bs, bs);
|
2019-05-12 16:33:25 +01:00
|
|
|
|
2019-05-20 20:48:58 +01:00
|
|
|
Vector3i block_origin_in_voxels = block_position * (bs << lod);
|
2019-05-28 01:10:50 +01:00
|
|
|
stream->emerge_block(buffer, block_origin_in_voxels, lod);
|
2019-05-05 01:09:12 +01:00
|
|
|
|
2019-05-20 20:48:58 +01:00
|
|
|
output.voxels_loaded = buffer;
|
2019-05-05 01:09:12 +01:00
|
|
|
}
|