Skip to content

Commit

Permalink
Planet: Split chunk creation and chunk generation
Browse files Browse the repository at this point in the history
Allows to generate only empty chunks
  • Loading branch information
SirLynix committed Dec 13, 2024
1 parent 61c9cfb commit 86c0811
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 46 deletions.
1 change: 1 addition & 0 deletions include/CommonLib/Planet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace tsom
~Planet() = default;

Chunk& AddChunk(const BlockLibrary& blockLibrary, const ChunkIndices& indices, const Nz::FunctionRef<void(BlockIndex* blocks)>& initCallback = nullptr);
void AddChunks(const BlockLibrary& blockLibrary, const Nz::Vector3ui& chunkCount);

GravityForce ComputeGravity(const Nz::Vector3f& position) const override;
Nz::Vector3f ComputeUpDirection(const Nz::Vector3f& position) const;
Expand Down
97 changes: 54 additions & 43 deletions src/CommonLib/Planet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ namespace tsom
return *it->second.chunk;
}

void Planet::AddChunks(const BlockLibrary& blockLibrary, const Nz::Vector3ui& chunkCount)
{
for (int chunkZ = 0; chunkZ < chunkCount.z; ++chunkZ)
{
for (int chunkY = 0; chunkY < chunkCount.y; ++chunkY)
{
for (int chunkX = 0; chunkX < chunkCount.x; ++chunkX)
AddChunk(blockLibrary, { chunkX - int(chunkCount.x / 2), chunkY - int(chunkCount.y / 2), chunkZ - int(chunkCount.z / 2) });
}
}
}

auto Planet::ComputeGravity(const Nz::Vector3f& position) const -> GravityForce
{
constexpr float PlanetGravityCenterStartDecrease = 16.f;
Expand Down Expand Up @@ -488,62 +500,61 @@ namespace tsom
sol::protected_function generationFunction;
};

std::mutex threadMutex;
std::unordered_map<std::thread::id, std::unique_ptr<ThreadState>> threadStates;
struct GenerationContext
{
std::mutex threadMutex;
std::unordered_map<std::thread::id, std::unique_ptr<ThreadState>> threadStates;
};

auto context = std::make_shared<GenerationContext>();

for (int chunkZ = 0; chunkZ < chunkCount.z; ++chunkZ)
ForEachChunk([=, &taskScheduler](const ChunkIndices& chunkIndices, Chunk& chunk)
{
for (int chunkY = 0; chunkY < chunkCount.y; ++chunkY)
if (chunk.HasContent())
return;

taskScheduler.AddTask([=, &chunk]
{
for (int chunkX = 0; chunkX < chunkCount.x; ++chunkX)
ThreadState* currentThreadState = nullptr;
{
auto& chunk = AddChunk(blockLibrary, { chunkX - int(chunkCount.x / 2), chunkY - int(chunkCount.y / 2), chunkZ - int(chunkCount.z / 2) });
taskScheduler.AddTask([&]
std::unique_lock lock(context->threadMutex);
auto id = std::this_thread::get_id();
auto it = context->threadStates.find(id);
if (it == context->threadStates.end())
{
ThreadState* currentThreadState = nullptr;
{
std::unique_lock lock(threadMutex);
auto id = std::this_thread::get_id();
auto it = threadStates.find(id);
if (it == threadStates.end())
{
lock.unlock();
lock.unlock();

std::unique_ptr<ThreadState> threadState = std::make_unique<ThreadState>(m_app);
threadState->scriptingContext.RegisterLibrary<MathScriptingLibrary>();
threadState->scriptingContext.RegisterLibrary<ChunkScriptingLibrary>();
std::unique_ptr<ThreadState> threadState = std::make_unique<ThreadState>(m_app);
threadState->scriptingContext.RegisterLibrary<MathScriptingLibrary>();
threadState->scriptingContext.RegisterLibrary<ChunkScriptingLibrary>();

Nz::Result execResult = threadState->scriptingContext.LoadFile(fmt::format("scripts/planets/{}.lua", scriptName));
if (!execResult)
return;
Nz::Result execResult = threadState->scriptingContext.LoadFile(fmt::format("scripts/planets/{}.lua", scriptName));
if (!execResult)
return;

threadState->generationFunction = execResult.GetValue();
threadState->generationFunction = execResult.GetValue();

currentThreadState = threadState.get();
currentThreadState = threadState.get();

lock.lock();
threadStates.emplace(id, std::move(threadState));
}
else
currentThreadState = it->second.get();
}
lock.lock();
context->threadStates.emplace(id, std::move(threadState));
}
else
currentThreadState = it->second.get();
}

chunk.LockWrite();
NAZARA_DEFER({ chunk.UnlockWrite(); });
chunk.LockWrite();
NAZARA_DEFER({ chunk.UnlockWrite(); });

auto result = currentThreadState->generationFunction(chunk, seed, chunkCount);
if (!result.valid())
{
sol::error err = result;
fmt::print("chunk {};{};{} failed to generate: {}", chunkX, chunkY, chunkZ, err.what());
return;
}
});
auto result = currentThreadState->generationFunction(chunk, seed, chunkCount);
if (!result.valid())
{
sol::error err = result;
fmt::print("chunk {};{};{} failed to generate: {}", chunkIndices.x, chunkIndices.y, chunkIndices.z, err.what());
return;
}
}
}

taskScheduler.WaitForTasks();
});
});
}

void Planet::GeneratePlatform(const BlockLibrary& blockLibrary, Direction upDirection, const BlockIndices& platformCenter)
Expand Down
10 changes: 7 additions & 3 deletions src/ServerLib/ServerPlanetEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,19 @@ namespace tsom
auto& taskScheduler = app.GetComponent<Nz::TaskSchedulerAppComponent>();

auto& planetComponent = m_planetEntity.get<PlanetComponent>();
planetComponent.planet->AddChunks(blockLibrary, chunkCount);

if (!m_savePath.empty())
LoadFromDirectory();

planetComponent.planet->GenerateChunks(blockLibrary, taskScheduler, seed, chunkCount, "alice");
taskScheduler.WaitForTasks();

planetComponent.planet->GeneratePlatform(blockLibrary, tsom::Direction::Right, { 65, -18, -39 });
planetComponent.planet->GeneratePlatform(blockLibrary, tsom::Direction::Back, { -34, 2, 53 });
planetComponent.planet->GeneratePlatform(blockLibrary, tsom::Direction::Front, { 22, -35, -59 });
planetComponent.planet->GeneratePlatform(blockLibrary, tsom::Direction::Down, { 23, -62, 26 });

if (!m_savePath.empty())
LoadFromDirectory();

planetComponent.planet->OnChunkUpdated.Connect([this](ChunkContainer* /*planet*/, Chunk* chunk, DirectionMask /*neighborMask*/)
{
m_dirtyChunks.insert(chunk->GetIndices());
Expand Down

0 comments on commit 86c0811

Please sign in to comment.