bool Chunk::operator<(const Chunk &w) const { glm::vec3 cameraPos = m_renderer->GetCamera().GetPosition(); int cameraX = cameraPos.x / (Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE); int cameraY = cameraPos.y / (Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE); int cameraZ = cameraPos.z / (Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE); int distance = abs(cameraX - m_grid.x) + abs(cameraY - m_grid.y) + abs(cameraZ - m_grid.z); int wDistance = abs(cameraX - w.GetGridX()) + abs(cameraY - w.GetGridY()) + abs(cameraZ - w.GetGridZ()); return(distance < wDistance); }
// < Operator (Used for chunk sorting, closest to camera) bool Chunk::operator<(const Chunk &w) const { int playerX = 0; int playerY = 0; int playerZ = 0; if (m_pPlayer != NULL) { playerX = m_pPlayer->GetGridX(); playerY = m_pPlayer->GetGridY(); playerZ = m_pPlayer->GetGridZ(); } int distance = abs(playerX - m_gridX) + abs(playerY - m_gridY) + abs(playerZ - m_gridZ); int wDistance = abs(playerX - w.GetGridX()) + abs(playerY - w.GetGridY()) + abs(playerZ - w.GetGridZ()); return(distance < wDistance); }
void ChunkManager::UpdatingChunksThread() { while (m_updateThreadActive) { while (m_pPlayer == NULL) { #ifdef _WIN32 Sleep(100); #else usleep(100000); #endif } while (m_stepLockEnabled == true && m_updateStepLock == true) { #ifdef _WIN32 Sleep(100); #else usleep(100000); #endif } ChunkList updateChunkList; ChunkCoordKeysList addChunkList; ChunkList rebuildChunkList; ChunkList unloadChunkList; m_ChunkMapMutexLock.lock(); typedef map<ChunkCoordKeys, Chunk*>::iterator it_type; for (it_type iterator = m_chunksMap.begin(); iterator != m_chunksMap.end(); iterator++) { Chunk* pChunk = iterator->second; updateChunkList.push_back(pChunk); } m_ChunkMapMutexLock.unlock(); // Updating chunks int numAddedChunks = 0; int MAX_NUM_CHUNKS_ADD = 10; sort(updateChunkList.begin(), updateChunkList.end(), Chunk::ClosestToCamera); for (unsigned int i = 0; i < (int)updateChunkList.size(); i++) { Chunk* pChunk = updateChunkList[i]; if (pChunk != NULL) { pChunk->Update(0.01f); int gridX = pChunk->GetGridX(); int gridY = pChunk->GetGridY(); int gridZ = pChunk->GetGridZ(); float xPos = gridX * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float yPos = gridY * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float zPos = gridZ * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; vec3 chunkCenter = vec3(xPos, yPos, zPos) + vec3(Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE); vec3 distanceVec = chunkCenter - m_pPlayer->GetCenter(); float lengthValue = length(distanceVec); if (lengthValue > m_loaderRadius) { unloadChunkList.push_back(pChunk); } else { if (numAddedChunks < MAX_NUM_CHUNKS_ADD) { // Check neighbours if (pChunk->GetNumNeighbours() < 6 && (pChunk->IsEmpty() == false) || (gridY == 0)) { if (pChunk->GetxMinus() == NULL) { ChunkCoordKeys coordKey; coordKey.x = gridX - 1; coordKey.y = gridY; coordKey.z = gridZ; float xPos = coordKey.x * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float yPos = coordKey.y * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float zPos = coordKey.z * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; vec3 chunkCenter = vec3(xPos, yPos, zPos) + vec3(Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE); vec3 distanceVec = chunkCenter - m_pPlayer->GetCenter(); float lengthValue = length(distanceVec); if (lengthValue <= m_loaderRadius) { addChunkList.push_back(coordKey); numAddedChunks++; } } if (pChunk->GetxPlus() == NULL) { ChunkCoordKeys coordKey; coordKey.x = gridX + 1; coordKey.y = gridY; coordKey.z = gridZ; float xPos = coordKey.x * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float yPos = coordKey.y * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float zPos = coordKey.z * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; vec3 chunkCenter = vec3(xPos, yPos, zPos) + vec3(Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE); vec3 distanceVec = chunkCenter - m_pPlayer->GetCenter(); float lengthValue = length(distanceVec); if (lengthValue <= m_loaderRadius) { addChunkList.push_back(coordKey); numAddedChunks++; } } if (pChunk->GetyMinus() == NULL) { ChunkCoordKeys coordKey; coordKey.x = gridX; coordKey.y = gridY - 1; coordKey.z = gridZ; float xPos = coordKey.x * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float yPos = coordKey.y * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float zPos = coordKey.z * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; vec3 chunkCenter = vec3(xPos, yPos, zPos) + vec3(Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE); vec3 distanceVec = chunkCenter - m_pPlayer->GetCenter(); float lengthValue = length(distanceVec); if (lengthValue <= m_loaderRadius) { addChunkList.push_back(coordKey); numAddedChunks++; } } if (pChunk->GetyPlus() == NULL) { ChunkCoordKeys coordKey; coordKey.x = gridX; coordKey.y = gridY + 1; coordKey.z = gridZ; float xPos = coordKey.x * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float yPos = coordKey.y * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float zPos = coordKey.z * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; vec3 chunkCenter = vec3(xPos, yPos, zPos) + vec3(Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE); vec3 distanceVec = chunkCenter - m_pPlayer->GetCenter(); float lengthValue = length(distanceVec); if (lengthValue <= m_loaderRadius) { addChunkList.push_back(coordKey); numAddedChunks++; } } if (pChunk->GetzMinus() == NULL) { ChunkCoordKeys coordKey; coordKey.x = gridX; coordKey.y = gridY; coordKey.z = gridZ - 1; float xPos = coordKey.x * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float yPos = coordKey.y * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float zPos = coordKey.z * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; vec3 chunkCenter = vec3(xPos, yPos, zPos) + vec3(Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE); vec3 distanceVec = chunkCenter - m_pPlayer->GetCenter(); float lengthValue = length(distanceVec); if (lengthValue <= m_loaderRadius) { addChunkList.push_back(coordKey); numAddedChunks++; } } if (pChunk->GetzPlus() == NULL) { ChunkCoordKeys coordKey; coordKey.x = gridX; coordKey.y = gridY; coordKey.z = gridZ + 1; float xPos = coordKey.x * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float yPos = coordKey.y * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; float zPos = coordKey.z * Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f; vec3 chunkCenter = vec3(xPos, yPos, zPos) + vec3(Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE, Chunk::CHUNK_SIZE*Chunk::BLOCK_RENDER_SIZE); vec3 distanceVec = chunkCenter - m_pPlayer->GetCenter(); float lengthValue = length(distanceVec); if (lengthValue <= m_loaderRadius) { addChunkList.push_back(coordKey); numAddedChunks++; } } } } } } } updateChunkList.clear(); // Adding chunks for (unsigned int i = 0; i < (int)addChunkList.size(); i++) { ChunkCoordKeys coordKey = addChunkList[i]; Chunk* pChunk = GetChunk(coordKey.x, coordKey.y, coordKey.z); if (pChunk == NULL) { CreateNewChunk(coordKey.x, coordKey.y, coordKey.z); } else { UpdateChunkNeighbours(pChunk, coordKey.x, coordKey.y, coordKey.z); } } addChunkList.clear(); // Unloading chunks for (unsigned int i = 0; i < (int)unloadChunkList.size(); i++) { Chunk* pChunk = unloadChunkList[i]; UnloadChunk(pChunk); } unloadChunkList.clear(); // Check for rebuild chunks m_ChunkMapMutexLock.lock(); for (it_type iterator = m_chunksMap.begin(); iterator != m_chunksMap.end(); iterator++) { Chunk* pChunk = iterator->second; if (pChunk != NULL) { if (pChunk->NeedsRebuild()) { rebuildChunkList.push_back(pChunk); } } } m_ChunkMapMutexLock.unlock(); // Rebuilding chunks int numRebuildChunks = 0; int MAX_NUM_CHUNKS_REBUILD = 30; for (unsigned int i = 0; i < (int)rebuildChunkList.size() && numRebuildChunks < MAX_NUM_CHUNKS_REBUILD; i++) { Chunk* pChunk = rebuildChunkList[i]; pChunk->SwitchToCachedMesh(); pChunk->RebuildMesh(); pChunk->CompleteMesh(); pChunk->UndoCachedMesh(); numRebuildChunks++; } rebuildChunkList.clear(); if (m_stepLockEnabled == true && m_updateStepLock == false) { m_updateStepLock = true; } #ifdef _WIN32 Sleep(10); #else usleep(10000); #endif } m_updateThreadFinished = true; }