@@ -1366,6 +1366,11 @@ void VoxelLodTerrain::apply_main_thread_update_tasks() {
1366
1366
}
1367
1367
block->drop_visuals ();
1368
1368
remove_shader_material_from_block (*block, _shader_material_pool);
1369
+ // Also update the state in the threaded representation
1370
+ auto it = lod.mesh_map_state .map .find (bpos);
1371
+ if (it != lod.mesh_map_state .map .end ()) {
1372
+ it->second .visual_loaded = false ;
1373
+ }
1369
1374
}
1370
1375
lod.mesh_blocks_to_drop_visual .clear ();
1371
1376
@@ -1678,6 +1683,8 @@ void VoxelLodTerrain::apply_mesh_update(VoxelEngine::BlockMeshOutput &ob) {
1678
1683
bool collision_active;
1679
1684
bool first_collision_load = false ;
1680
1685
bool first_visual_load = false ;
1686
+ bool visual_expected = false ;
1687
+ bool collision_expected = false ;
1681
1688
{
1682
1689
VoxelLodTerrainUpdateData::Lod &lod = update_data.state .lods [ob.lod ];
1683
1690
RWLockRead rlock (lod.mesh_map_state .map_lock );
@@ -1707,21 +1714,23 @@ void VoxelLodTerrain::apply_mesh_update(VoxelEngine::BlockMeshOutput &ob) {
1707
1714
visual_active = mesh_block_state.visual_active ;
1708
1715
collision_active = mesh_block_state.collision_active ;
1709
1716
1710
- if (ob.visual_was_required ) {
1711
- if (!mesh_block_state.visual_loaded ) {
1712
- // First mesh load (note, no mesh being present counts as load too. Before that we would not know)
1713
- mesh_block_state.visual_loaded = true ;
1714
- first_visual_load = true ;
1715
- }
1717
+ visual_expected = mesh_block_state.mesh_viewers .get () > 0 ;
1718
+ collision_expected = mesh_block_state.collision_viewers .get () > 0 ;
1719
+
1720
+ if (visual_expected && ob.visual_was_required ) {
1721
+ // Mark visuals loaded for the streaming system to subdivide LODs.
1722
+ // First mesh load? (note, no mesh being present counts as load too. Before that we would not know)
1723
+ first_visual_load = (mesh_block_state.visual_loaded .exchange (true ) == false );
1716
1724
}
1717
- if (!mesh_block_state. collision_loaded ) {
1718
- // First mesh load (note, no mesh being present counts as load too. Before that we would not know)
1719
- mesh_block_state. collision_loaded = true ;
1720
- first_collision_load = true ;
1725
+ if (collision_expected ) {
1726
+ // Mark collisions loaded for the streaming system to subdivide LODs.
1727
+ // First mesh load? (note, no mesh being present counts as load too. Before that we would not know)
1728
+ first_collision_load = (mesh_block_state. collision_loaded . exchange ( true ) == false ) ;
1721
1729
}
1722
1730
}
1723
1731
if ((first_visual_load || first_collision_load) &&
1724
1732
_update_data->settings .streaming_system == VoxelLodTerrainUpdateData::STREAMING_SYSTEM_CLIPBOX) {
1733
+ // Notify streaming system so it can subdivide LODs as they load
1725
1734
VoxelLodTerrainUpdateData::ClipboxStreamingState &cs = _update_data->state .clipbox_streaming ;
1726
1735
MutexLock mlock (cs.loaded_mesh_blocks_mutex );
1727
1736
cs.loaded_mesh_blocks .push_back (VoxelLodTerrainUpdateData::LoadedMeshBlockEvent{
@@ -1737,7 +1746,7 @@ void VoxelLodTerrain::apply_mesh_update(VoxelEngine::BlockMeshOutput &ob) {
1737
1746
VoxelMesher::Output &mesh_data = ob.surfaces ;
1738
1747
1739
1748
Ref<ArrayMesh> mesh;
1740
- if (ob.visual_was_required ) {
1749
+ if (ob.visual_was_required && visual_expected ) {
1741
1750
if (ob.has_mesh_resource ) {
1742
1751
// The mesh was already built as part of the threaded task
1743
1752
mesh = ob.mesh ;
@@ -1797,7 +1806,7 @@ void VoxelLodTerrain::apply_mesh_update(VoxelEngine::BlockMeshOutput &ob) {
1797
1806
}
1798
1807
#endif
1799
1808
1800
- if (ob.visual_was_required ) {
1809
+ if (ob.visual_was_required && visual_expected ) {
1801
1810
// We consider a block having a "rendering" mesh as having loaded visuals.
1802
1811
if (!block->has_mesh ()) {
1803
1812
// Setup visuals
@@ -1864,7 +1873,7 @@ void VoxelLodTerrain::apply_mesh_update(VoxelEngine::BlockMeshOutput &ob) {
1864
1873
has_collision = ob.lod < _collision_lod_count;
1865
1874
}
1866
1875
1867
- if (has_collision) {
1876
+ if (has_collision && collision_expected ) {
1868
1877
const uint64_t now = get_ticks_msec ();
1869
1878
1870
1879
if (_collision_update_delay == 0 ||
@@ -1889,9 +1898,11 @@ void VoxelLodTerrain::apply_mesh_update(VoxelEngine::BlockMeshOutput &ob) {
1889
1898
}
1890
1899
}
1891
1900
1901
+ // This is done regardless in case a MeshInstance or collision body is created, because it will then set its
1902
+ // position
1892
1903
block->set_parent_transform (get_global_transform ());
1893
1904
1894
- if (ob.detail_textures != nullptr ) {
1905
+ if (ob.detail_textures != nullptr && visual_expected ) {
1895
1906
if (ob.detail_textures ->valid ) {
1896
1907
apply_detail_texture_update_to_block (*block, *ob.detail_textures , ob.lod );
1897
1908
} else {
0 commit comments