Fix crash when a VoxelTerrain is used without a stream

This commit is contained in:
Marc Gilleron 2020-05-07 21:13:47 +01:00
parent 5ed58995d5
commit 600942564c

View File

@ -36,7 +36,7 @@ VoxelTerrain::VoxelTerrain() {
VoxelTerrain::~VoxelTerrain() { VoxelTerrain::~VoxelTerrain() {
print_line("Destroying VoxelTerrain"); print_line("Destroying VoxelTerrain");
if (_stream_thread) { if (_stream_thread != nullptr) {
// Schedule saving of all modified blocks, // Schedule saving of all modified blocks,
// without copy because we are destroying the map anyways // without copy because we are destroying the map anyways
save_all_modified_blocks(false); save_all_modified_blocks(false);
@ -51,7 +51,7 @@ VoxelTerrain::~VoxelTerrain() {
String VoxelTerrain::get_configuration_warning() const { String VoxelTerrain::get_configuration_warning() const {
if (_stream.is_valid()) { if (_stream.is_valid()) {
if (! (_stream->get_used_channels_mask() & ((1<<VoxelBuffer::CHANNEL_TYPE) | (1<<VoxelBuffer::CHANNEL_SDF)))) { if (!(_stream->get_used_channels_mask() & ((1 << VoxelBuffer::CHANNEL_TYPE) | (1 << VoxelBuffer::CHANNEL_SDF)))) {
return TTR("VoxelTerrain supports only stream channels \"Type\" or \"Sdf\"."); return TTR("VoxelTerrain supports only stream channels \"Type\" or \"Sdf\".");
} }
} }
@ -710,6 +710,8 @@ void VoxelTerrain::get_viewer_pos_and_direction(Vector3 &out_pos, Vector3 &out_d
void VoxelTerrain::send_block_data_requests() { void VoxelTerrain::send_block_data_requests() {
ERR_FAIL_COND(_stream_thread == nullptr);
VoxelDataLoader::Input input; VoxelDataLoader::Input input;
Vector3 viewer_pos; Vector3 viewer_pos;
@ -736,7 +738,6 @@ void VoxelTerrain::send_block_data_requests() {
} }
void VoxelTerrain::_process() { void VoxelTerrain::_process() {
// TODO Should be able to run without library, tho! // TODO Should be able to run without library, tho!
if (_library.is_null()) { if (_library.is_null()) {
return; return;
@ -791,13 +792,17 @@ void VoxelTerrain::_process() {
_last_view_distance_blocks = _view_distance_blocks; _last_view_distance_blocks = _view_distance_blocks;
_last_viewer_block_pos = viewer_block_pos; _last_viewer_block_pos = viewer_block_pos;
// It's possible the user didn't set a stream yet
if (_stream_thread != nullptr) {
send_block_data_requests(); send_block_data_requests();
}
_stats.time_request_blocks_to_load = profiling_clock.restart(); _stats.time_request_blocks_to_load = profiling_clock.restart();
// Get block loading responses // Get block loading responses
// Note: if block loading is too fast, this can cause stutters. It should only happen on first load, though. // Note: if block loading is too fast, this can cause stutters. It should only happen on first load, though.
{ if (_stream_thread != nullptr) {
VoxelDataLoader::Output output; VoxelDataLoader::Output output;
_stream_thread->pop(output); _stream_thread->pop(output);
//print_line(String("Receiving {0} blocks").format(varray(output.emerged_blocks.size()))); //print_line(String("Receiving {0} blocks").format(varray(output.emerged_blocks.size())));
@ -893,6 +898,8 @@ void VoxelTerrain::_process() {
// Send mesh updates // Send mesh updates
{ {
ERR_FAIL_COND(_block_updater == nullptr);
VoxelMeshUpdater::Input input; VoxelMeshUpdater::Input input;
input.priority_position = viewer_block_pos; input.priority_position = viewer_block_pos;
input.priority_direction = viewer_direction; input.priority_direction = viewer_direction;
@ -904,7 +911,7 @@ void VoxelTerrain::_process() {
// Smooth meshing works on more neighbors, so checking a single block isn't enough to ignore it, // Smooth meshing works on more neighbors, so checking a single block isn't enough to ignore it,
// but that will slow down meshing a lot. // but that will slow down meshing a lot.
// TODO This is one reason to separate terrain systems between blocky and smooth (other reason is LOD) // TODO This is one reason to separate terrain systems between blocky and smooth (other reason is LOD)
if (! (_stream->get_used_channels_mask() & (1<<VoxelBuffer::CHANNEL_SDF))) { if (!(_stream->get_used_channels_mask() & (1 << VoxelBuffer::CHANNEL_SDF))) {
VoxelBlock *block = _map->get_block(block_pos); VoxelBlock *block = _map->get_block(block_pos);
if (block == nullptr) { if (block == nullptr) {
continue; continue;
@ -1072,7 +1079,7 @@ void VoxelTerrain::_process() {
Ref<VoxelTool> VoxelTerrain::get_voxel_tool() { Ref<VoxelTool> VoxelTerrain::get_voxel_tool() {
Ref<VoxelTool> vt = memnew(VoxelToolTerrain(this, _map)); Ref<VoxelTool> vt = memnew(VoxelToolTerrain(this, _map));
if (_stream.is_valid()) { if (_stream.is_valid()) {
if(_stream->get_used_channels_mask() & (1<<VoxelBuffer::CHANNEL_SDF)) { if (_stream->get_used_channels_mask() & (1 << VoxelBuffer::CHANNEL_SDF)) {
vt->set_channel(VoxelBuffer::CHANNEL_SDF); vt->set_channel(VoxelBuffer::CHANNEL_SDF);
} else { } else {
vt->set_channel(VoxelBuffer::CHANNEL_TYPE); vt->set_channel(VoxelBuffer::CHANNEL_TYPE);