[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 <gk/gl/GLCheck.hpp>
|
||||||
|
|
||||||
#include "ClientChunk.hpp"
|
#include "ClientChunk.hpp"
|
||||||
@ -33,6 +34,13 @@ u32 ClientChunk::chunkUpdatesPerSec = 0;
|
|||||||
u32 ClientChunk::chunkUpdateCounter = 0;
|
u32 ClientChunk::chunkUpdateCounter = 0;
|
||||||
u64 ClientChunk::chunkUpdateTime = 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() {
|
void ClientChunk::update() {
|
||||||
u64 time = std::time(nullptr);
|
u64 time = std::time(nullptr);
|
||||||
if (time > ClientChunk::chunkUpdateTime) {
|
if (time > ClientChunk::chunkUpdateTime) {
|
||||||
@ -41,13 +49,15 @@ void ClientChunk::update() {
|
|||||||
ClientChunk::chunkUpdateTime = time;
|
ClientChunk::chunkUpdateTime = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_lightmap.updateLights() || m_hasChanged || m_hasLightChanged) {
|
if (isMeshingTime() && (m_lightmap.updateLights() || m_hasChanged || m_hasLightChanged)) {
|
||||||
m_hasChanged = false;
|
m_hasChanged = false;
|
||||||
m_hasLightChanged = false;
|
m_hasLightChanged = false;
|
||||||
|
|
||||||
m_verticesCount = m_builder.buildChunk(*this, m_vbo);
|
m_verticesCount = m_builder.buildChunk(*this, m_vbo);
|
||||||
|
|
||||||
++ClientChunk::chunkUpdateCounter;
|
++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)
|
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} {}
|
: Chunk(x, y, z, world), m_dimension(dimension), m_textureAtlas(textureAtlas), m_builder{textureAtlas} {}
|
||||||
|
|
||||||
|
bool isMeshingTime();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
void drawLayer(gk::RenderTarget &target, gk::RenderStates states, u8 layer) const;
|
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_isReadyForMeshing = false;
|
||||||
bool m_isTooFar = false;
|
bool m_isTooFar = false;
|
||||||
bool m_hasBeenDrawn = false;
|
bool m_hasBeenDrawn = false;
|
||||||
|
|
||||||
|
u32 m_lastMeshingTime = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLIENTCHUNK_HPP_
|
#endif // CLIENTCHUNK_HPP_
|
||||||
|
@ -45,25 +45,17 @@ ClientWorld::ClientWorld() : m_textureAtlas(gk::ResourceHandler::getInstance().g
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::update(bool allowWorldReload) {
|
void ClientWorld::update(bool allowWorldReload) {
|
||||||
|
// Delete unused chunks
|
||||||
|
for (auto &it : m_chunksToRemove)
|
||||||
|
m_chunks.erase(it);
|
||||||
|
|
||||||
// Update loaded chunks
|
// Update loaded chunks
|
||||||
for (auto it = m_chunks.begin() ; it != m_chunks.end() ;) {
|
for (auto &it : m_chunks) {
|
||||||
// If chunk is too far, remove it
|
if (World::isReloadRequested && allowWorldReload)
|
||||||
if (it->second->isTooFar() && (it->second->isInitialized() || it->second->areAllNeighboursTooFar())) {
|
it.second->setChanged(true);
|
||||||
// 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);
|
|
||||||
|
|
||||||
if (it->second->areAllNeighboursInitialized() && it->second->isReadyForMeshing())
|
if (it.second->isReadyForMeshing())
|
||||||
it->second->update();
|
it.second->update();
|
||||||
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowWorldReload)
|
if (allowWorldReload)
|
||||||
@ -84,11 +76,9 @@ void ClientWorld::requestClosestChunkMeshing() {
|
|||||||
if (ud < 1000000.0) {
|
if (ud < 1000000.0) {
|
||||||
ClientChunk *chunk = (ClientChunk *)getChunk(ux, uy, uz);
|
ClientChunk *chunk = (ClientChunk *)getChunk(ux, uy, uz);
|
||||||
if(chunk && !chunk->isReadyForMeshing()) {
|
if(chunk && !chunk->isReadyForMeshing()) {
|
||||||
// Send a chunk request to the server
|
|
||||||
// m_client->sendChunkRequest(ux, uy, uz);
|
|
||||||
chunk->setReadyForMeshing(true);
|
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
|
// Nope, too far, don't render it
|
||||||
if(glm::length(center) > (Config::renderDistance + 1) * CHUNK_WIDTH) {
|
if(glm::length(center) > (Config::renderDistance + 1) * CHUNK_WIDTH) {
|
||||||
// If it is way too far, mark it for deletion
|
// If it is way too far, mark it for deletion
|
||||||
if(glm::length(center) > (Config::renderDistance + 3) * CHUNK_WIDTH)
|
if(floor(glm::length(center)) > (Config::renderDistance + 3) * CHUNK_WIDTH
|
||||||
it.second->setTooFar(true);
|
&& (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 + 1) * CHUNK_WIDTH);
|
// 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#define CLIENTWORLD_HPP_
|
#define CLIENTWORLD_HPP_
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <gk/core/Vector4.hpp>
|
#include <gk/core/Vector4.hpp>
|
||||||
#include <gk/core/EventHandler.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};
|
mutable gk::Vector4d m_closestInitializedChunk{0, 0, 0, 1000000};
|
||||||
|
|
||||||
const Sky *m_sky = nullptr;
|
const Sky *m_sky = nullptr;
|
||||||
|
|
||||||
|
mutable std::unordered_set<gk::Vector3i> m_chunksToRemove;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLIENTWORLD_HPP_
|
#endif // CLIENTWORLD_HPP_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user