[ClientChunk] Added a timer to limit chunk updates. [ClientWorld] Improved the way cfar chunks are removed.
This commit is contained in:
parent
6bc5c79b32
commit
4f5c545883
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_
|
||||
|
Loading…
x
Reference in New Issue
Block a user