Exemple #1
0
// Chunk Creation
void ChunkManager::CreateNewChunk(int x, int y, int z)
{
	ChunkCoordKeys coordKeys;
	coordKeys.x = x;
	coordKeys.y = y;
	coordKeys.z = z;

	// Create a new chunk at this grid position
	Chunk* pNewChunk = new Chunk(m_pRenderer, this, m_pVoxSettings);
	pNewChunk->SetPlayer(m_pPlayer);
	pNewChunk->SetSceneryManager(m_pSceneryManager);

	float xPos = x * (Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f);
	float yPos = y * (Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f);
	float zPos = z * (Chunk::CHUNK_SIZE * Chunk::BLOCK_RENDER_SIZE*2.0f);

	pNewChunk->SetPosition(vec3(xPos, yPos, zPos));
	pNewChunk->SetGrid(coordKeys.x, coordKeys.y, coordKeys.z);

	m_ChunkMapMutexLock.lock();
	m_chunksMap[coordKeys] = pNewChunk;
	m_ChunkMapMutexLock.unlock();

	pNewChunk->Setup();
	pNewChunk->SetNeedsRebuild(false, true);
	pNewChunk->RebuildMesh();
	pNewChunk->CompleteMesh();
	pNewChunk->SetCreated(true);

	UpdateChunkNeighbours(pNewChunk, x, y, z);
}
void ChunkManager::Update() {
	ChunkList unloadList;

	m_chunkMapMutex.lock();
	std::map<ChunkCoordKey, Chunk*>::iterator it;
	for (it = m_chunkMap.begin(); it != m_chunkMap.end(); ++it) {
		Chunk* chunk = it->second;
		if (chunk->IsUnloading()) {
			unloadList.push_back(chunk);
		}
		else if (chunk->IsRebuildComplete()) {
			chunk->CompleteMesh();
		}
	}
	m_chunkMapMutex.unlock();
	
	int numUnloadChunks = 0;
	const static int MAX_NUM_CHUNKS_UNLOAD = 1;
	for (unsigned int i = 0; i < unloadList.size() && numUnloadChunks < MAX_NUM_CHUNKS_UNLOAD; ++i) {
		Chunk* chunk = unloadList[i];
		UnloadChunk(chunk);
	}
}
Exemple #3
0
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;
}