[ClientChunk] Added a timer to limit chunk updates. [ClientWorld] Improved the way cfar chunks are removed.

This commit is contained in:
Quentin Bazin 2021-01-02 17:27:06 +01:00
parent 6bc5c79b32
commit 4f5c545883
4 changed files with 36 additions and 24 deletions

View File

@ -24,6 +24,7 @@
*
* =====================================================================================
*/
#include <gk/core/GameClock.hpp>
#include <gk/gl/GLCheck.hpp>
#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);
}
}

View File

@ -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_

View File

@ -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;
}

View File

@ -28,6 +28,7 @@
#define CLIENTWORLD_HPP_
#include <unordered_map>
#include <unordered_set>
#include <gk/core/Vector4.hpp>
#include <gk/core/EventHandler.hpp>
@ -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<gk::Vector3i> m_chunksToRemove;
};
#endif // CLIENTWORLD_HPP_