Skip to content

Commit 1ee0072

Browse files
committed
Planet: Load chunks as necessary when visibility mask updates
1 parent 6a9c93c commit 1ee0072

5 files changed

Lines changed: 49 additions & 15 deletions

File tree

include/CommonLib/Planet.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ namespace tsom
6262
Planet& operator=(const Planet&) = delete;
6363
Planet& operator=(Planet&&) = delete;
6464

65+
NazaraSignal(OnChunkVisibilityMaskUpdated, Planet* /*planet*/, Chunk* /*chunk*/, DirectionMask /*oldVisibilityMask*/, DirectionMask /*newVisibilityMask*/);
66+
6567
static constexpr unsigned int ChunkSize = 32;
6668

6769
protected:

include/ServerLib/ServerPlanetEnvironment.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <CommonLib/Chunk.hpp>
1212
#include <ServerLib/ServerAtmosphere.hpp>
1313
#include <ServerLib/ServerEnvironment.hpp>
14-
#include <tsl/hopscotch_set.h>
14+
#include <tsl/hopscotch_map.h>
1515
#include <atomic>
1616
#include <filesystem>
1717
#include <mutex>
@@ -63,9 +63,9 @@ namespace tsom
6363
std::mutex mutex;
6464
std::shared_ptr<Planet> planet;
6565
std::queue<ChunkIndices> remainingChunks;
66-
tsl::hopscotch_set<ChunkIndices> visitedChunks;
66+
tsl::hopscotch_map<ChunkIndices, bool> visitedChunks;
6767

68-
void HandleChunkLoaded(const ChunkIndices& chunkIndices);
68+
void HandleChunkLoaded(const ChunkIndices& chunkIndices, DirectionMask visibilityMask);
6969
};
7070

7171
ServerAtmosphere m_atmosphere;

scripts/planets/bob.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ return function (chunk, seed)
6363
table.insert(content, dirtBlock)
6464
end
6565
else
66-
table.insert(content, emptyBlock)
66+
table.insert(content, stoneBlock)
6767
end
6868
else
6969
local baseMountainous = perlin:normalizedOctave3D_01((blockPosNorm.x * moutainScale)+10, blockPosNorm.y * moutainScale, blockPosNorm.z * moutainScale, 4, 0.1)

src/CommonLib/Planet.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,17 @@ namespace tsom
110110
}
111111
}
112112

113+
DirectionMask oldVisibilityMask = chunkData.visibilityMask;
114+
chunkData.visibilityMask.Clear();
115+
113116
for (auto&& [direction, holeCount] : chunkData.directionHoleCount.iter_kv())
114117
{
115118
if (holeCount > 0)
116119
chunkData.visibilityMask |= direction;
117120
}
121+
122+
if (oldVisibilityMask != chunkData.visibilityMask)
123+
OnChunkVisibilityMaskUpdated(this, chunk, oldVisibilityMask, chunkData.visibilityMask);
118124
}
119125

120126
// FIXME: Nz::Signal operator() is not thread-safe!
@@ -196,6 +202,8 @@ namespace tsom
196202
NazaraAssert(chunkIt != m_chunks.end());
197203
ChunkData& chunkData = chunkIt.value();
198204

205+
DirectionMask oldVisibilityMask = chunkData.visibilityMask;
206+
199207
if (previousBlockData.isTransparent)
200208
{
201209
// We're putting an opaque block on a transparent one
@@ -215,6 +223,9 @@ namespace tsom
215223
chunkData.visibilityMask |= direction;
216224
}
217225
}
226+
227+
if (oldVisibilityMask != chunkData.visibilityMask)
228+
OnChunkVisibilityMaskUpdated(this, chunk, oldVisibilityMask, chunkData.visibilityMask);
218229
}
219230
}
220231

src/ServerLib/ServerPlanetEnvironment.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,20 @@ namespace tsom
5454

5555
auto& planetComponent = m_planetEntity.get<PlanetComponent>();
5656

57+
ChunkIndices firstChunkIndices(-int(m_chunkCount.x / 2), -int(m_chunkCount.y / 2), -int(m_chunkCount.z / 2));
58+
5759
m_chunkLoadingData = std::make_shared<ChunkLoadingData>();
5860
m_chunkLoadingData->chunkCount = m_chunkCount;
5961
m_chunkLoadingData->planet = planetComponent.planet;
60-
m_chunkLoadingData->remainingChunks.emplace(-int(m_chunkCount.x / 2), -int(m_chunkCount.y / 2), -int(m_chunkCount.z / 2));
62+
m_chunkLoadingData->remainingChunks.emplace(firstChunkIndices);
63+
m_chunkLoadingData->visitedChunks.emplace(firstChunkIndices, true);
64+
65+
GetPlanet().OnChunkVisibilityMaskUpdated.Connect([chunkLoadingData = m_chunkLoadingData](Planet* /*planet*/, Chunk* chunk, DirectionMask oldVisibilityMask, DirectionMask newVisibilityMask)
66+
{
67+
DirectionMask newDirectionMask = newVisibilityMask & ~oldVisibilityMask;
68+
chunkLoadingData->visitedChunks[chunk->GetIndices()] = true;
69+
chunkLoadingData->HandleChunkLoaded(chunk->GetIndices(), newDirectionMask);
70+
});
6171

6272
//planetComponent.planet->GeneratePlatform(blockLibrary, Direction::Right, { 65, -18, -39 });
6373
//planetComponent.planet->GeneratePlatform(blockLibrary, Direction::Back, { -34, 2, 53 });
@@ -264,7 +274,8 @@ namespace tsom
264274
if (!chunkFound)
265275
chunkLoadingData->planet->GenerateChunk(*chunk, seed, chunkCount, generatorName);
266276

267-
chunkLoadingData->HandleChunkLoaded(chunk->GetIndices());
277+
DirectionMask visibilityMask = chunkLoadingData->planet->GetChunkVisibilityMask(chunk->GetIndices());
278+
chunkLoadingData->HandleChunkLoaded(chunk->GetIndices(), visibilityMask);
268279

269280
if (--chunkLoadingData->chunkLoadingCount == 0 && chunkLoadingData->remainingChunks.empty())
270281
spdlog::debug("planet chunk loading finished, total chunks: {} (out of {})", chunkLoadingData->visitedChunks.size(), chunkCount.x * chunkCount.y * chunkCount.z);
@@ -344,26 +355,36 @@ namespace tsom
344355
});
345356
}
346357

347-
void ServerPlanetEnvironment::ChunkLoadingData::HandleChunkLoaded(const ChunkIndices& chunkIndices)
358+
void ServerPlanetEnvironment::ChunkLoadingData::HandleChunkLoaded(const ChunkIndices& chunkIndices, DirectionMask visibilityMask)
348359
{
349360
ChunkIndices minIndices(-int(chunkCount.x / 2), -int(chunkCount.y / 2), -int(chunkCount.z / 2));
350361
ChunkIndices maxIndices = minIndices + ChunkIndices(chunkCount) - ChunkIndices(1);
351362

352363
std::unique_lock lock(mutex);
353364

354-
DirectionMask visibilityMask = planet->GetChunkVisibilityMask(chunkIndices);
355-
for (Direction visibleNeighborDir : visibilityMask)
365+
// Direct neighbor can trigger indirect neighbor
366+
bool isPrimaryChunk = Nz::Retrieve(visitedChunks, chunkIndices);
367+
368+
for (Direction direction : DirectionMask_All)
356369
{
357-
ChunkIndices neighborIndices = chunkIndices + s_chunkDirOffset[visibleNeighborDir];
358-
if (neighborIndices.x < minIndices.x || neighborIndices.x > maxIndices.x ||
359-
neighborIndices.y < minIndices.y || neighborIndices.y > maxIndices.y ||
360-
neighborIndices.z < minIndices.z || neighborIndices.z > maxIndices.z)
370+
bool isNeighborPrimaryChunk = visibilityMask.Test(direction);
371+
if (!isPrimaryChunk && !isNeighborPrimaryChunk)
361372
continue;
362373

363-
if (visitedChunks.contains(neighborIndices))
374+
ChunkIndices neighborIndices = chunkIndices + s_chunkDirOffset[direction];
375+
if (neighborIndices.x < minIndices.x || neighborIndices.x > maxIndices.x
376+
|| neighborIndices.y < minIndices.y || neighborIndices.y > maxIndices.y
377+
|| neighborIndices.z < minIndices.z || neighborIndices.z > maxIndices.z)
364378
continue;
365379

366-
visitedChunks.insert(neighborIndices);
380+
auto it = visitedChunks.find(neighborIndices);
381+
if (it != visitedChunks.end())
382+
{
383+
it.value() |= isNeighborPrimaryChunk;
384+
continue;
385+
}
386+
387+
visitedChunks.emplace(neighborIndices, isNeighborPrimaryChunk);
367388
remainingChunks.push(neighborIndices);
368389
}
369390
}

0 commit comments

Comments
 (0)