2018-09-24 16:54:07 -07:00
|
|
|
#include "voxel_mesh_updater.h"
|
2019-12-31 08:48:46 -08:00
|
|
|
#include "../meshers/transvoxel/voxel_mesher_transvoxel.h"
|
2019-04-28 09:58:29 -07:00
|
|
|
#include "../util/utility.h"
|
2019-05-03 16:02:10 -07:00
|
|
|
#include "voxel_lod_terrain.h"
|
2019-04-23 17:29:47 -07:00
|
|
|
#include <core/os/os.h>
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-12-31 08:48:46 -08:00
|
|
|
static void scale_mesh_data(Vector<Array> &surfaces, float factor) {
|
2019-05-03 16:02:10 -07:00
|
|
|
|
2019-12-31 08:48:46 -08:00
|
|
|
for (int i = 0; i < surfaces.size(); ++i) {
|
|
|
|
Array &surface = surfaces.write[i]; // There is COW here too but should not happen, hopefully
|
2019-05-03 16:02:10 -07:00
|
|
|
|
|
|
|
if (surface.empty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
PoolVector3Array positions = surface[Mesh::ARRAY_VERTEX]; // Array of Variants here, implicit cast going on
|
|
|
|
|
|
|
|
// Now dear COW, let's make sure there is only ONE ref to that PoolVector,
|
|
|
|
// so you won't trash performance with pointless allocations
|
|
|
|
surface[Mesh::ARRAY_VERTEX] = Variant();
|
|
|
|
|
2019-05-12 08:33:25 -07:00
|
|
|
{
|
|
|
|
PoolVector3Array::Write w = positions.write();
|
|
|
|
int len = positions.size();
|
|
|
|
for (int j = 0; j < len; ++j) {
|
|
|
|
w[j] = w[j] * factor;
|
|
|
|
}
|
2019-05-03 16:02:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Thank you
|
|
|
|
surface[Mesh::ARRAY_VERTEX] = positions;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-19 10:27:49 -07:00
|
|
|
VoxelMeshUpdater::VoxelMeshUpdater(unsigned int thread_count, MeshingParams params) {
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-08-23 17:44:27 -07:00
|
|
|
print_line("Constructing VoxelMeshUpdater");
|
|
|
|
|
2019-05-19 10:27:49 -07:00
|
|
|
Ref<VoxelMesherBlocky> blocky_mesher;
|
2019-12-31 08:48:46 -08:00
|
|
|
Ref<VoxelMesherTransvoxel> smooth_mesher;
|
2019-04-27 17:32:23 -07:00
|
|
|
|
2019-12-31 08:48:46 -08:00
|
|
|
_minimum_padding = 0;
|
|
|
|
_maximum_padding = 0;
|
2019-08-16 12:56:07 -07:00
|
|
|
|
2019-05-19 10:27:49 -07:00
|
|
|
if (params.library.is_valid()) {
|
|
|
|
blocky_mesher.instance();
|
|
|
|
blocky_mesher->set_library(params.library);
|
|
|
|
blocky_mesher->set_occlusion_enabled(params.baked_ao);
|
|
|
|
blocky_mesher->set_occlusion_darkness(params.baked_ao_darkness);
|
2019-12-31 08:48:46 -08:00
|
|
|
_minimum_padding = max(_minimum_padding, blocky_mesher->get_minimum_padding());
|
|
|
|
_maximum_padding = max(_maximum_padding, blocky_mesher->get_maximum_padding());
|
2019-05-03 15:59:21 -07:00
|
|
|
}
|
2019-04-27 17:32:23 -07:00
|
|
|
|
2019-05-19 10:27:49 -07:00
|
|
|
if (params.smooth_surface) {
|
|
|
|
smooth_mesher.instance();
|
2019-12-31 08:48:46 -08:00
|
|
|
_minimum_padding = max(_minimum_padding, smooth_mesher->get_minimum_padding());
|
|
|
|
_maximum_padding = max(_maximum_padding, smooth_mesher->get_maximum_padding());
|
2019-04-27 17:32:23 -07:00
|
|
|
}
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-08-16 12:56:07 -07:00
|
|
|
Mgr::BlockProcessingFunc processors[Mgr::MAX_LOD];
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-06-17 22:24:56 -07:00
|
|
|
for (unsigned int i = 0; i < thread_count; ++i) {
|
2019-08-16 12:56:07 -07:00
|
|
|
|
|
|
|
if (i > 0) {
|
2019-05-27 16:40:09 -07:00
|
|
|
// Need to clone them because they are not thread-safe due to memory pooling.
|
2019-05-19 10:27:49 -07:00
|
|
|
// Also thanks to the wonders of ref_pointer() being private we trigger extra refs/unrefs for no reason
|
|
|
|
if (blocky_mesher.is_valid()) {
|
2019-08-16 12:56:07 -07:00
|
|
|
blocky_mesher = Ref<VoxelMesher>(blocky_mesher->clone());
|
2019-05-19 10:27:49 -07:00
|
|
|
}
|
|
|
|
if (smooth_mesher.is_valid()) {
|
2019-08-16 12:56:07 -07:00
|
|
|
smooth_mesher = Ref<VoxelMesher>(smooth_mesher->clone());
|
2019-05-19 10:27:49 -07:00
|
|
|
}
|
2019-05-12 08:19:08 -07:00
|
|
|
}
|
2019-08-16 12:56:07 -07:00
|
|
|
|
2019-08-16 16:46:24 -07:00
|
|
|
processors[i] = [this, blocky_mesher, smooth_mesher](const ArraySlice<InputBlock> inputs, ArraySlice<OutputBlock> outputs, Mgr::ProcessorStats &_) {
|
2019-12-31 08:48:46 -08:00
|
|
|
this->process_blocks_thread_func(inputs, outputs, blocky_mesher, smooth_mesher);
|
2019-08-16 12:56:07 -07:00
|
|
|
};
|
2018-09-24 16:54:07 -07:00
|
|
|
}
|
|
|
|
|
2019-05-19 10:27:49 -07:00
|
|
|
_mgr = memnew(Mgr(thread_count, 50, processors));
|
|
|
|
}
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-05-19 10:27:49 -07:00
|
|
|
VoxelMeshUpdater::~VoxelMeshUpdater() {
|
2019-06-01 17:59:39 -07:00
|
|
|
print_line("Destroying VoxelMeshUpdater");
|
2019-05-19 10:27:49 -07:00
|
|
|
if (_mgr) {
|
|
|
|
memdelete(_mgr);
|
2018-09-24 16:54:07 -07:00
|
|
|
}
|
2019-05-19 10:27:49 -07:00
|
|
|
}
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-08-16 12:56:07 -07:00
|
|
|
void VoxelMeshUpdater::process_blocks_thread_func(
|
|
|
|
const ArraySlice<InputBlock> inputs,
|
|
|
|
ArraySlice<OutputBlock> outputs,
|
|
|
|
Ref<VoxelMesher> blocky_mesher,
|
2019-12-31 08:48:46 -08:00
|
|
|
Ref<VoxelMesher> smooth_mesher) {
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-08-16 12:56:07 -07:00
|
|
|
CRASH_COND(inputs.size() != outputs.size());
|
2019-05-12 08:33:25 -07:00
|
|
|
|
2019-09-06 08:44:19 -07:00
|
|
|
for (unsigned int i = 0; i < inputs.size(); ++i) {
|
2019-05-12 08:33:25 -07:00
|
|
|
|
2019-08-16 12:56:07 -07:00
|
|
|
const InputBlock &ib = inputs[i];
|
|
|
|
const InputBlockData &block = ib.data;
|
|
|
|
OutputBlockData &output = outputs[i].data;
|
2019-05-12 08:33:25 -07:00
|
|
|
|
2019-08-16 12:56:07 -07:00
|
|
|
CRASH_COND(block.voxels.is_null());
|
|
|
|
|
|
|
|
if (blocky_mesher.is_valid()) {
|
2019-12-31 08:48:46 -08:00
|
|
|
blocky_mesher->build(output.blocky_surfaces, **block.voxels);
|
2019-08-16 12:56:07 -07:00
|
|
|
}
|
|
|
|
if (smooth_mesher.is_valid()) {
|
2019-12-31 08:48:46 -08:00
|
|
|
smooth_mesher->build(output.smooth_surfaces, **block.voxels);
|
2019-08-16 12:56:07 -07:00
|
|
|
}
|
2019-05-04 17:09:12 -07:00
|
|
|
|
2019-08-16 12:56:07 -07:00
|
|
|
if (ib.lod > 0) {
|
2019-12-31 08:48:46 -08:00
|
|
|
// TODO Make this optional if the mesher can factor in the upscale already
|
2019-08-16 12:56:07 -07:00
|
|
|
float factor = 1 << ib.lod;
|
2019-12-31 08:48:46 -08:00
|
|
|
scale_mesh_data(output.blocky_surfaces.surfaces, factor);
|
|
|
|
scale_mesh_data(output.smooth_surfaces.surfaces, factor);
|
|
|
|
for (int i = 0; i < output.smooth_surfaces.transition_surfaces.size(); ++i) {
|
|
|
|
scale_mesh_data(output.smooth_surfaces.transition_surfaces[i], factor);
|
|
|
|
}
|
2019-08-16 12:56:07 -07:00
|
|
|
}
|
2019-05-19 10:27:49 -07:00
|
|
|
}
|
2019-05-04 17:09:12 -07:00
|
|
|
}
|