void ChunkManager::UnloadChunk(Chunk* pChunk) { ChunkCoordKeys coordKeys; coordKeys.x = pChunk->GetGridX(); coordKeys.y = pChunk->GetGridY(); coordKeys.z = pChunk->GetGridZ(); Chunk* pChunkXMinus = GetChunk(coordKeys.x - 1, coordKeys.y, coordKeys.z); Chunk* pChunkXPlus = GetChunk(coordKeys.x + 1, coordKeys.y, coordKeys.z); Chunk* pChunkYMinus = GetChunk(coordKeys.x, coordKeys.y - 1, coordKeys.z); Chunk* pChunkYPlus = GetChunk(coordKeys.x, coordKeys.y + 1, coordKeys.z); Chunk* pChunkZMinus = GetChunk(coordKeys.x, coordKeys.y, coordKeys.z - 1); Chunk* pChunkZPlus = GetChunk(coordKeys.x, coordKeys.y, coordKeys.z + 1); if (pChunkXMinus) { if (pChunkXMinus->GetxPlus()) { pChunkXMinus->SetNumNeighbours(pChunkXMinus->GetNumNeighbours() - 1); pChunkXMinus->SetxPlus(NULL); } } if (pChunkXPlus) { if (pChunkXPlus->GetxMinus()) { pChunkXPlus->SetNumNeighbours(pChunkXPlus->GetNumNeighbours() - 1); pChunkXPlus->SetxMinus(NULL); } } if (pChunkYMinus) { if (pChunkYMinus->GetyPlus()) { pChunkYMinus->SetNumNeighbours(pChunkYMinus->GetNumNeighbours() - 1); pChunkYMinus->SetyPlus(NULL); } } if (pChunkYPlus) { if (pChunkYPlus->GetyMinus()) { pChunkYPlus->SetNumNeighbours(pChunkYPlus->GetNumNeighbours() - 1); pChunkYPlus->SetyMinus(NULL); } } if (pChunkZMinus) { if (pChunkZMinus->GetzPlus()) { pChunkZMinus->SetNumNeighbours(pChunkZMinus->GetNumNeighbours() - 1); pChunkZMinus->SetzPlus(NULL); } } if (pChunkZPlus) { if (pChunkZPlus->GetzMinus()) { pChunkZPlus->SetNumNeighbours(pChunkZPlus->GetNumNeighbours() - 1); pChunkZPlus->SetzMinus(NULL); } } // Remove from map m_ChunkMapMutexLock.lock(); map<ChunkCoordKeys, Chunk*>::iterator it = m_chunksMap.find(coordKeys); if (it != m_chunksMap.end()) { m_chunksMap.erase(coordKeys); } m_ChunkMapMutexLock.unlock(); // Clear chunk linkage if (m_pPlayer != NULL) { m_pPlayer->ClearChunkCacheForChunk(pChunk); } // Unload and delete pChunk->Unload(); delete pChunk; }
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; }
void ChunkManager::UpdateChunkNeighbours(Chunk* pChunk, int x, int y, int z) { pChunk->SetNumNeighbours(0); Chunk* pChunkXMinus = GetChunk(x - 1, y, z); Chunk* pChunkXPlus = GetChunk(x + 1, y, z); Chunk* pChunkYMinus = GetChunk(x, y - 1, z); Chunk* pChunkYPlus = GetChunk(x, y + 1, z); Chunk* pChunkZMinus = GetChunk(x, y, z - 1); Chunk* pChunkZPlus = GetChunk(x, y, z + 1); if (pChunkXMinus) { pChunk->SetNumNeighbours(pChunk->GetNumNeighbours() + 1); pChunk->SetxMinus(pChunkXMinus); if (pChunkXMinus->GetxPlus() == NULL) { pChunkXMinus->SetNumNeighbours(pChunkXMinus->GetNumNeighbours() + 1); pChunkXMinus->SetxPlus(pChunk); } } if (pChunkXPlus) { pChunk->SetNumNeighbours(pChunk->GetNumNeighbours() + 1); pChunk->SetxPlus(pChunkXPlus); if (pChunkXPlus->GetxMinus() == NULL) { pChunkXPlus->SetNumNeighbours(pChunkXPlus->GetNumNeighbours() + 1); pChunkXPlus->SetxMinus(pChunk); } } if (pChunkYMinus) { pChunk->SetNumNeighbours(pChunk->GetNumNeighbours() + 1); pChunk->SetyMinus(pChunkYMinus); if (pChunkYMinus->GetyPlus() == NULL) { pChunkYMinus->SetNumNeighbours(pChunkYMinus->GetNumNeighbours() + 1); pChunkYMinus->SetyPlus(pChunk); } } if (pChunkYPlus) { pChunk->SetNumNeighbours(pChunk->GetNumNeighbours() + 1); pChunk->SetyPlus(pChunkYPlus); if (pChunkYPlus->GetyMinus() == NULL) { pChunkYPlus->SetNumNeighbours(pChunkYPlus->GetNumNeighbours() + 1); pChunkYPlus->SetyMinus(pChunk); } } if (pChunkZMinus) { pChunk->SetNumNeighbours(pChunk->GetNumNeighbours() + 1); pChunk->SetzMinus(pChunkZMinus); if (pChunkZMinus->GetzPlus() == NULL) { pChunkZMinus->SetNumNeighbours(pChunkZMinus->GetNumNeighbours() + 1); pChunkZMinus->SetzPlus(pChunk); } } if (pChunkZPlus) { pChunk->SetNumNeighbours(pChunk->GetNumNeighbours() + 1); pChunk->SetzPlus(pChunkZPlus); if (pChunkZPlus->GetzMinus() == NULL) { pChunkZPlus->SetNumNeighbours(pChunkZPlus->GetNumNeighbours() + 1); pChunkZPlus->SetzMinus(pChunk); } } }