diff --git a/source/client/world/ClientChunk.cpp b/source/client/world/ClientChunk.cpp index b4a01936..95def3be 100644 --- a/source/client/world/ClientChunk.cpp +++ b/source/client/world/ClientChunk.cpp @@ -24,6 +24,7 @@ * * ===================================================================================== */ +#include #include #include "ClientChunk.hpp" @@ -33,6 +34,13 @@ u32 ClientChunk::chunkUpdatesPerSec = 0; u32 ClientChunk::chunkUpdateCounter = 0; u64 ClientChunk::chunkUpdateTime = 0; +bool ClientChunk::isMeshingTime() { + u32 currentTime = gk::GameClock::getInstance().getTicks(true); + if (m_lastMeshingTime == 0) + m_lastMeshingTime = currentTime; + return (currentTime - m_lastMeshingTime > 1000); // Only one chunk update every second +} + void ClientChunk::update() { u64 time = std::time(nullptr); if (time > ClientChunk::chunkUpdateTime) { @@ -41,13 +49,15 @@ void ClientChunk::update() { ClientChunk::chunkUpdateTime = time; } - if (m_lightmap.updateLights() || m_hasChanged || m_hasLightChanged) { + if (isMeshingTime() && (m_lightmap.updateLights() || m_hasChanged || m_hasLightChanged)) { m_hasChanged = false; m_hasLightChanged = false; m_verticesCount = m_builder.buildChunk(*this, m_vbo); ++ClientChunk::chunkUpdateCounter; + + m_lastMeshingTime = gk::GameClock::getInstance().getTicks(true); } } diff --git a/source/client/world/ClientChunk.hpp b/source/client/world/ClientChunk.hpp index 1716bab6..99658503 100644 --- a/source/client/world/ClientChunk.hpp +++ b/source/client/world/ClientChunk.hpp @@ -41,6 +41,8 @@ class ClientChunk : public Chunk { ClientChunk(s32 x, s32 y, s32 z, const Dimension &dimension, World &world, TextureAtlas &textureAtlas) : Chunk(x, y, z, world), m_dimension(dimension), m_textureAtlas(textureAtlas), m_builder{textureAtlas} {} + bool isMeshingTime(); + void update(); void drawLayer(gk::RenderTarget &target, gk::RenderStates states, u8 layer) const; @@ -75,6 +77,8 @@ class ClientChunk : public Chunk { bool m_isReadyForMeshing = false; bool m_isTooFar = false; bool m_hasBeenDrawn = false; + + u32 m_lastMeshingTime = 0; }; #endif // CLIENTCHUNK_HPP_ diff --git a/source/client/world/ClientWorld.cpp b/source/client/world/ClientWorld.cpp index 11710c71..d0c260f7 100644 --- a/source/client/world/ClientWorld.cpp +++ b/source/client/world/ClientWorld.cpp @@ -45,25 +45,17 @@ ClientWorld::ClientWorld() : m_textureAtlas(gk::ResourceHandler::getInstance().g } void ClientWorld::update(bool allowWorldReload) { + // Delete unused chunks + for (auto &it : m_chunksToRemove) + m_chunks.erase(it); + // Update loaded chunks - for (auto it = m_chunks.begin() ; it != m_chunks.end() ;) { - // If chunk is too far, remove it - if (it->second->isTooFar() && (it->second->isInitialized() || it->second->areAllNeighboursTooFar())) { - // gkDebug() << "Chunk removed at" << it->second->x() << it->second->y() << it->second->z() - // << "because" << (it->second->isInitialized() ? "too far and initialized" : "all neighbours are too far"); - m_client->sendChunkUnload(it->second->x(), it->second->y(), it->second->z()); - removeChunk(it); - } - // Otherwise, update the chunk - else { - if (World::isReloadRequested && allowWorldReload) - it->second->setChanged(true); + for (auto &it : m_chunks) { + if (World::isReloadRequested && allowWorldReload) + it.second->setChanged(true); - if (it->second->areAllNeighboursInitialized() && it->second->isReadyForMeshing()) - it->second->update(); - - ++it; - } + if (it.second->isReadyForMeshing()) + it.second->update(); } if (allowWorldReload) @@ -84,11 +76,9 @@ void ClientWorld::requestClosestChunkMeshing() { if (ud < 1000000.0) { ClientChunk *chunk = (ClientChunk *)getChunk(ux, uy, uz); if(chunk && !chunk->isReadyForMeshing()) { - // Send a chunk request to the server - // m_client->sendChunkRequest(ux, uy, uz); chunk->setReadyForMeshing(true); - // std::cout << "Chunk at (" << ux << ", " << uy << ", " << uz << ") requested" << std::endl; + // gkDebug() << "Chunk at" << ux << uy << uz << "is ready for meshing"; } } } @@ -288,9 +278,14 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const // Nope, too far, don't render it if(glm::length(center) > (Config::renderDistance + 1) * CHUNK_WIDTH) { // If it is way too far, mark it for deletion - if(glm::length(center) > (Config::renderDistance + 3) * CHUNK_WIDTH) - it.second->setTooFar(true); - // gkDebug() << "Chunk at" << it.second->x() << it.second->y() << it.second->z() << "is too far:" << glm::length(center) << ">" << ((Config::renderDistance + 1) * CHUNK_WIDTH); + if(floor(glm::length(center)) > (Config::renderDistance + 3) * CHUNK_WIDTH + && (it.second->isInitialized() || it.second->areAllNeighboursTooFar())) { + // gkDebug() << "Chunk at" << it.second->x() << it.second->y() << it.second->z() << "is too far:" << glm::length(center) << ">" << ((Config::renderDistance + 3) * CHUNK_WIDTH); + m_chunksToRemove.emplace(it.first); + } + + it.second->setTooFar(true); + continue; } diff --git a/source/client/world/ClientWorld.hpp b/source/client/world/ClientWorld.hpp index a9e15775..ec70d43f 100644 --- a/source/client/world/ClientWorld.hpp +++ b/source/client/world/ClientWorld.hpp @@ -28,6 +28,7 @@ #define CLIENTWORLD_HPP_ #include +#include #include #include @@ -92,6 +93,8 @@ class ClientWorld : public World, public gk::Drawable { mutable gk::Vector4d m_closestInitializedChunk{0, 0, 0, 1000000}; const Sky *m_sky = nullptr; + + mutable std::unordered_set m_chunksToRemove; }; #endif // CLIENTWORLD_HPP_