Exemplo n.º 1
0
bool Chunk::UpdateSurroundedFlag()
{
	if (m_pChunkManager == NULL)
	{
		return false;
	}

	Chunk* pChunkXMinus = m_pChunkManager->GetChunk(m_gridX - 1, m_gridY, m_gridZ);
	Chunk* pChunkXPlus = m_pChunkManager->GetChunk(m_gridX + 1, m_gridY, m_gridZ);
	Chunk* pChunkYMinus = m_pChunkManager->GetChunk(m_gridX, m_gridY - 1, m_gridZ);
	Chunk* pChunkYPlus = m_pChunkManager->GetChunk(m_gridX, m_gridY + 1, m_gridZ);
	Chunk* pChunkZMinus = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ - 1);
	Chunk* pChunkZPlus = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ + 1);

	// Check our neighbor chunks
	if (pChunkXMinus != NULL && pChunkXMinus->IsSetup() == true && pChunkXMinus->m_x_plus_full &&
		pChunkXPlus != NULL && pChunkXPlus->IsSetup() == true && pChunkXPlus->m_x_minus_full &&
		pChunkYMinus != NULL && pChunkYMinus->IsSetup() == true && pChunkYMinus->m_y_plus_full &&
		pChunkYPlus != NULL && pChunkYPlus->IsSetup() == true && pChunkYPlus->m_y_minus_full &&
		pChunkZMinus != NULL && pChunkZMinus->IsSetup() == true && pChunkZMinus->m_z_plus_full &&
		pChunkZPlus != NULL && pChunkZPlus->IsSetup() == true && pChunkZPlus->m_z_minus_full)
	{
		m_surroundedChunk = true;
	}
	else
	{
		m_surroundedChunk = false;
	}

	return true;
}
Exemplo n.º 2
0
void Chunk::Unload()
{
	m_isUnloading = true;

	if (m_pMesh != NULL)
	{
		m_pRenderer->ClearMesh(m_pMesh);
		m_pMesh = NULL;
	}

	if (m_setup == true)
	{
		Chunk* pChunkXMinus = m_pChunkManager->GetChunk(m_gridX - 1, m_gridY, m_gridZ);
		Chunk* pChunkXPlus = m_pChunkManager->GetChunk(m_gridX + 1, m_gridY, m_gridZ);
		Chunk* pChunkYMinus = m_pChunkManager->GetChunk(m_gridX, m_gridY - 1, m_gridZ);
		Chunk* pChunkYPlus = m_pChunkManager->GetChunk(m_gridX, m_gridY + 1, m_gridZ);
		Chunk* pChunkZMinus = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ - 1);
		Chunk* pChunkZPlus = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ + 1);

		if (pChunkXMinus != NULL && pChunkXMinus->IsSetup() == true)
			pChunkXMinus->UpdateSurroundedFlag();
		if (pChunkXPlus != NULL && pChunkXPlus->IsSetup() == true)
			pChunkXPlus->UpdateSurroundedFlag();
		if (pChunkYMinus != NULL && pChunkYMinus->IsSetup() == true)
			pChunkYMinus->UpdateSurroundedFlag();
		if (pChunkYPlus != NULL && pChunkYPlus->IsSetup() == true)
			pChunkYPlus->UpdateSurroundedFlag();
		if (pChunkZMinus != NULL && pChunkZMinus->IsSetup() == true)
			pChunkZMinus->UpdateSurroundedFlag();
		if (pChunkZPlus != NULL && pChunkZPlus->IsSetup() == true)
			pChunkZPlus->UpdateSurroundedFlag();
	}
}
Exemplo n.º 3
0
bool ItemSpawner::GetSpawnPosition(vec3* pSpawnPosition)
{
	bool lLocationGood = false;
	int numTries = 0;
	while (lLocationGood == false && numTries < 10)
	{
		vec3 spawnPos = m_position;
		vec3 randomOffset;

		if (m_spawnFullLoaderRange)
		{
			float loaderRadius = m_pChunkManager->GetLoaderRadius();
			randomOffset = vec3(GetRandomNumber(-100, 100, 2)*0.01f*loaderRadius, GetRandomNumber(-100, 100, 2)*0.01f*loaderRadius, GetRandomNumber(-100, 100, 2)*0.01f*loaderRadius);
		}
		else
		{
			randomOffset = vec3(GetRandomNumber(-100, 100, 2)*0.01f*(m_spawnRandomOffset.x - 8.0f), GetRandomNumber(-100, 100, 2)*0.01f*(m_spawnRandomOffset.y - 8.0f), GetRandomNumber(-100, 100, 2)*0.01f*(m_spawnRandomOffset.z - 8.0f));
		}

		spawnPos += randomOffset;

		int blockX, blockY, blockZ;
		vec3 blockPos;
		Chunk* pChunk = NULL;
		bool active = m_pChunkManager->GetBlockActiveFrom3DPosition(spawnPos.x, spawnPos.y, spawnPos.z, &blockPos, &blockX, &blockY, &blockZ, &pChunk);
		if (pChunk != NULL && pChunk->IsSetup() && active == false)
		{
			if (m_shouldSpawnOnGround)
			{
				vec3 floorPosition;
				if (m_pChunkManager->FindClosestFloor(spawnPos, &floorPosition))
				{
					spawnPos = floorPosition + vec3(0.0f, 0.01f, 0.0f);
					spawnPos += m_groundSpawnOffset;

					Biome biome = VoxGame::GetInstance()->GetBiomeManager()->GetBiome(spawnPos);
					if (biome == m_biomeSpawn)
					{
						*pSpawnPosition = spawnPos;
						lLocationGood = true;
					}
				}
			}
		}
		
		numTries++;
	}

	return lLocationGood;
}
Exemplo n.º 4
0
// Collision
bool Player::CheckCollisions(vec3 positionCheck, vec3 previousPosition, vec3 *pNormal, vec3 *pMovement, bool *pStepUpBlock)
{
	vec3 movementCache = *pMovement;

	// World collision
	bool worldCollision = false;
	float radius = GetRadius();

	int blockX, blockY, blockZ;
	vec3 blockPos;
	int blockXAbove, blockYAbove, blockZAbove;
	vec3 blockPosAbove;
	int numChecks = 1 + (int)(radius / (Chunk::BLOCK_RENDER_SIZE* 2.0f));
	bool canAllStepUp = false;
	bool firstStepUp = true;
	for (int x = -numChecks; x <= numChecks; x++)
	{
		for (int y = -numChecks; y <= numChecks; y++)
		{
			for (int z = -numChecks; z <= numChecks; z++)
			{
				bool isStepUp = false;
				*pNormal = vec3(0.0f, 0.0f, 0.0f);

				Chunk* pChunk = GetCachedGridChunkOrFromPosition(positionCheck + vec3((Chunk::BLOCK_RENDER_SIZE*2.0f)*x, (Chunk::BLOCK_RENDER_SIZE*2.0f)*y, (Chunk::BLOCK_RENDER_SIZE*2.0f)*z));
				bool active = m_pChunkManager->GetBlockActiveFrom3DPosition(positionCheck.x + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*x), positionCheck.y + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*y), positionCheck.z + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*z), &blockPos, &blockX, &blockY, &blockZ, &pChunk);
				bool activeAbove = false;
				bool activeAbove2 = false;

				if (active == false)
				{
					if (pChunk == NULL || pChunk->IsSetup() == false)
					{
						*pMovement = vec3(0.0f, 0.0f, 0.0f);
						worldCollision = true;
					}
				}
				else if (active == true)
				{
					Plane3D planes[6];
					planes[0] = Plane3D(vec3(-1.0f, 0.0f, 0.0f), vec3(Chunk::BLOCK_RENDER_SIZE, 0.0f, 0.0f));
					planes[1] = Plane3D(vec3(1.0f, 0.0f, 0.0f), vec3(-Chunk::BLOCK_RENDER_SIZE, 0.0f, 0.0f));
					planes[2] = Plane3D(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, Chunk::BLOCK_RENDER_SIZE, 0.0f));
					planes[3] = Plane3D(vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, -Chunk::BLOCK_RENDER_SIZE, 0.0f));
					planes[4] = Plane3D(vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, 0.0f, Chunk::BLOCK_RENDER_SIZE));
					planes[5] = Plane3D(vec3(0.0f, 0.0f, 1.0f), vec3(0.0f, 0.0f, -Chunk::BLOCK_RENDER_SIZE));

					float distance;
					int inside = 0;
					bool insideCache[6];

					for (int i = 0; i < 6; i++)
					{
						vec3 pointToCheck = blockPos - previousPosition;
						distance = planes[i].GetPointDistance(pointToCheck);

						if (distance < -radius)
						{
							// Outside...
							insideCache[i] = false;
						}
						else if (distance < radius)
						{
							// Intersecting..
							insideCache[i] = true;
						}
						else
						{
							// Inside...
							insideCache[i] = true;
						}
					}

					for (int i = 0; i < 6; i++)
					{
						vec3 pointToCheck = blockPos - positionCheck;
						distance = planes[i].GetPointDistance(pointToCheck);

						if (distance < -radius)
						{
							// Outside...
						}
						else if (distance < radius)
						{
							// Intersecting..
							inside++;
							if (insideCache[i] == false)
							{
								*pNormal += planes[i].mNormal;
							}
						}
						else
						{
							// Inside...
							inside++;
							if (insideCache[i] == false)
							{
								*pNormal += planes[i].mNormal;
							}
						}
					}

					if (inside == 6)
					{
						if (y == 0) // We only want to check on the same y-level as the players position.
						{
							vec3 posCheck1 = vec3(positionCheck.x + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*x), positionCheck.y + (Chunk::BLOCK_RENDER_SIZE*2.0f), positionCheck.z + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*z));
							vec3 posCheck2 = vec3(positionCheck.x + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*x), positionCheck.y + (Chunk::BLOCK_RENDER_SIZE*4.0f), positionCheck.z + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*z));

							Chunk* pChunkAbove = GetCachedGridChunkOrFromPosition(vec3(posCheck1.x, posCheck1.y, posCheck1.z));
							activeAbove = m_pChunkManager->GetBlockActiveFrom3DPosition(posCheck1.x, posCheck1.y, posCheck1.z, &blockPosAbove, &blockXAbove, &blockYAbove, &blockZAbove, &pChunkAbove);
							Chunk* pChunkAbove2 = GetCachedGridChunkOrFromPosition(vec3(posCheck2.x, posCheck2.y, posCheck2.z));
							activeAbove2 = m_pChunkManager->GetBlockActiveFrom3DPosition(posCheck2.x, posCheck2.y, posCheck2.z, &blockPosAbove, &blockXAbove, &blockYAbove, &blockZAbove, &pChunkAbove2);

							if ((activeAbove == false) && (activeAbove2 == false))
							{
								if (firstStepUp)
								{
									canAllStepUp = true;
								}

								isStepUp = true;
							}
							else
							{
								canAllStepUp = false;
							}

							firstStepUp = false;
						}

						if (length(*pNormal) <= 1.0f)
						{
							if (length(*pNormal) > 0.0f)
							{
								*pNormal = normalize(*pNormal);
							}

							float dotResult = dot(*pNormal, *pMovement);
							*pNormal *= dotResult;

							*pMovement -= *pNormal;

							worldCollision = true;
						}
					}
				}
			}
		}
	}

	*pStepUpBlock = canAllStepUp;

	if (worldCollision)
		return true;

	*pMovement = movementCache;

	return false;
}
Exemplo n.º 5
0
// Create mesh
void Chunk::CreateMesh()
{
	if (m_pMesh == NULL)
	{
		m_pMesh = m_pRenderer->CreateMesh(OGLMeshType_Textured);
	}

	int *l_merged;
	l_merged = new int[CHUNK_SIZE_CUBED];

	for (unsigned int j = 0; j < CHUNK_SIZE_CUBED; j++)
	{
		l_merged[j] = MergedSide_None;
	}

	float r = 1.0f;
	float g = 1.0f;
	float b = 1.0f;
	float a = 1.0f;

	for (int x = 0; x < CHUNK_SIZE; x++)
	{
		for (int y = 0; y < CHUNK_SIZE; y++)
		{
			for (int z = 0; z < CHUNK_SIZE; z++)
			{
				if (GetActive(x, y, z) == false)
				{
					continue;
				}
				else
				{
					GetColour(x, y, z, &r, &g, &b, &a);

					a = 1.0f;

					vec3 p1(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					vec3 p2(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					vec3 p3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					vec3 p4(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					vec3 p5(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					vec3 p6(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					vec3 p7(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					vec3 p8(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);

					vec3 n1;
					unsigned int v1, v2, v3, v4;
					unsigned int t1, t2, t3, t4;

					bool doXPositive = (IsMergedXPositive(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE) == false);
					bool doXNegative = (IsMergedXNegative(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE) == false);
					bool doYPositive = (IsMergedYPositive(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE) == false);
					bool doYNegative = (IsMergedYNegative(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE) == false);
					bool doZPositive = (IsMergedZPositive(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE) == false);
					bool doZNegative = (IsMergedZNegative(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE) == false);

					// Front
					if (doZPositive && ((z == CHUNK_SIZE - 1) || z < CHUNK_SIZE - 1 && GetActive(x, y, z + 1) == false))
					{
						bool addSide = true;

						if ((z == CHUNK_SIZE - 1))
						{
							Chunk* pChunk = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ + 1);
							if (pChunk == NULL || pChunk->IsSetup())
							{
								addSide = pChunk != NULL && (pChunk->GetActive(x, y, 0) == false);
							}
						}

						if (addSide)
						{
							int endX = (x / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;
							int endY = (y / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;

							if (m_pChunkManager->GetFaceMerging())
							{
								UpdateMergedSide(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE, &p1, &p2, &p3, &p4, x, y, endX, endY, true, true, false, false);
							}

							n1 = vec3(0.0f, 0.0f, 1.0f);
							v1 = m_pRenderer->AddVertexToMesh(p1, n1, r, g, b, a, m_pMesh);
							t1 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 0.0f, m_pMesh);
							v2 = m_pRenderer->AddVertexToMesh(p2, n1, r, g, b, a, m_pMesh);
							t2 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 0.0f, m_pMesh);
							v3 = m_pRenderer->AddVertexToMesh(p3, n1, r, g, b, a, m_pMesh);
							t3 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 1.0f, m_pMesh);
							v4 = m_pRenderer->AddVertexToMesh(p4, n1, r, g, b, a, m_pMesh);
							t4 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 1.0f, m_pMesh);

							m_pRenderer->AddTriangleToMesh(v1, v2, v3, m_pMesh);
							m_pRenderer->AddTriangleToMesh(v1, v3, v4, m_pMesh);
						}
					}

					p1 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p2 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p3 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p4 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p5 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p6 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p7 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p8 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);

					// Back
					if (doZNegative && ((z == 0) || (z > 0 && GetActive(x, y, z - 1) == false)))
					{
						bool addSide = true;

						if ((z == 0))
						{
							Chunk* pChunk = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ - 1);
							if (pChunk == NULL || pChunk->IsSetup())
							{
								addSide = pChunk != NULL && (pChunk->GetActive(x, y, CHUNK_SIZE - 1) == false);
							}
						}

						if (addSide)
						{
							int endX = (x / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;
							int endY = (y / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;

							if (m_pChunkManager->GetFaceMerging())
							{
								UpdateMergedSide(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE, &p6, &p5, &p8, &p7, x, y, endX, endY, false, true, false, false);
							}

							n1 = vec3(0.0f, 0.0f, -1.0f);
							v1 = m_pRenderer->AddVertexToMesh(p5, n1, r, g, b, a, m_pMesh);
							t1 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 0.0f, m_pMesh);
							v2 = m_pRenderer->AddVertexToMesh(p6, n1, r, g, b, a, m_pMesh);
							t2 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 0.0f, m_pMesh);
							v3 = m_pRenderer->AddVertexToMesh(p7, n1, r, g, b, a, m_pMesh);
							t3 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 1.0f, m_pMesh);
							v4 = m_pRenderer->AddVertexToMesh(p8, n1, r, g, b, a, m_pMesh);
							t4 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 1.0f, m_pMesh);

							m_pRenderer->AddTriangleToMesh(v1, v2, v3, m_pMesh);
							m_pRenderer->AddTriangleToMesh(v1, v3, v4, m_pMesh);
						}
					}

					p1 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p2 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p3 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p4 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p5 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p6 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p7 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p8 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);

					// Right
					if (doXPositive && ((x == CHUNK_SIZE - 1) || (x < CHUNK_SIZE - 1 && GetActive(x + 1, y, z) == false)))
					{
						bool addSide = true;

						if ((x == CHUNK_SIZE - 1))
						{
							Chunk* pChunk = m_pChunkManager->GetChunk(m_gridX + 1, m_gridY, m_gridZ);
							if (pChunk == NULL || pChunk->IsSetup())
							{
								addSide = pChunk != NULL && (pChunk->GetActive(0, y, z) == false);
							}
						}

						if (addSide)
						{
							int endX = (z / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;
							int endY = (y / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;

							if (m_pChunkManager->GetFaceMerging())
							{
								UpdateMergedSide(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE, &p5, &p2, &p3, &p8, z, y, endX, endY, true, false, true, false);
							}

							n1 = vec3(1.0f, 0.0f, 0.0f);
							v1 = m_pRenderer->AddVertexToMesh(p2, n1, r, g, b, a, m_pMesh);
							t1 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 0.0f, m_pMesh);
							v2 = m_pRenderer->AddVertexToMesh(p5, n1, r, g, b, a, m_pMesh);
							t2 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 0.0f, m_pMesh);
							v3 = m_pRenderer->AddVertexToMesh(p8, n1, r, g, b, a, m_pMesh);
							t3 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 1.0f, m_pMesh);
							v4 = m_pRenderer->AddVertexToMesh(p3, n1, r, g, b, a, m_pMesh);
							t4 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 1.0f, m_pMesh);

							m_pRenderer->AddTriangleToMesh(v1, v2, v3, m_pMesh);
							m_pRenderer->AddTriangleToMesh(v1, v3, v4, m_pMesh);
						}
					}

					p1 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p2 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p3 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p4 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p5 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p6 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p7 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p8 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);

					// Left
					if (doXNegative && ((x == 0) || (x > 0 && GetActive(x - 1, y, z) == false)))
					{
						bool addSide = true;

						if ((x == 0))
						{
							Chunk* pChunk = m_pChunkManager->GetChunk(m_gridX - 1, m_gridY, m_gridZ);
							if (pChunk == NULL || pChunk->IsSetup())
							{
								addSide = pChunk != NULL && (pChunk->GetActive(CHUNK_SIZE - 1, y, z) == false);
							}
						}

						if (addSide)
						{
							int endX = (z / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;
							int endY = (y / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;

							if (m_pChunkManager->GetFaceMerging())
							{
								UpdateMergedSide(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE, &p6, &p1, &p4, &p7, z, y, endX, endY, false, false, true, false);
							}

							n1 = vec3(-1.0f, 0.0f, 0.0f);
							v1 = m_pRenderer->AddVertexToMesh(p6, n1, r, g, b, a, m_pMesh);
							t1 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 0.0f, m_pMesh);
							v2 = m_pRenderer->AddVertexToMesh(p1, n1, r, g, b, a, m_pMesh);
							t2 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 0.0f, m_pMesh);
							v3 = m_pRenderer->AddVertexToMesh(p4, n1, r, g, b, a, m_pMesh);
							t3 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 1.0f, m_pMesh);
							v4 = m_pRenderer->AddVertexToMesh(p7, n1, r, g, b, a, m_pMesh);
							t4 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 1.0f, m_pMesh);

							m_pRenderer->AddTriangleToMesh(v1, v2, v3, m_pMesh);
							m_pRenderer->AddTriangleToMesh(v1, v3, v4, m_pMesh);
						}
					}

					p1 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p2 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p3 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p4 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p5 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p6 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p7 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p8 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);

					// Top
					if (doYPositive && ((y == CHUNK_SIZE - 1) || (y < CHUNK_SIZE - 1 && GetActive(x, y + 1, z) == false)))
					{
						bool addSide = true;

						if ((y == CHUNK_SIZE - 1))
						{
							Chunk* pChunk = m_pChunkManager->GetChunk(m_gridX, m_gridY + 1, m_gridZ);
							if (pChunk == NULL || pChunk->IsSetup())
							{
								addSide = pChunk != NULL && (pChunk->GetActive(x, 0, z) == false);
							}
						}

						if (addSide)
						{
							int endX = (x / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;
							int endY = (z / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;

							if (m_pChunkManager->GetFaceMerging())
							{
								UpdateMergedSide(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE, &p7, &p8, &p3, &p4, x, z, endX, endY, true, false, false, true);
							}

							n1 = vec3(0.0f, 1.0f, 0.0f);
							v1 = m_pRenderer->AddVertexToMesh(p4, n1, r, g, b, a, m_pMesh);
							t1 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 0.0f, m_pMesh);
							v2 = m_pRenderer->AddVertexToMesh(p3, n1, r, g, b, a, m_pMesh);
							t2 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 0.0f, m_pMesh);
							v3 = m_pRenderer->AddVertexToMesh(p8, n1, r, g, b, a, m_pMesh);
							t3 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 1.0f, m_pMesh);
							v4 = m_pRenderer->AddVertexToMesh(p7, n1, r, g, b, a, m_pMesh);
							t4 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 1.0f, m_pMesh);

							m_pRenderer->AddTriangleToMesh(v1, v2, v3, m_pMesh);
							m_pRenderer->AddTriangleToMesh(v1, v3, v4, m_pMesh);
						}
					}

					p1 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p2 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p3 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p4 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z + BLOCK_RENDER_SIZE);
					p5 = vec3(x + BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p6 = vec3(x - BLOCK_RENDER_SIZE, y - BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p7 = vec3(x - BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);
					p8 = vec3(x + BLOCK_RENDER_SIZE, y + BLOCK_RENDER_SIZE, z - BLOCK_RENDER_SIZE);

					// Bottom
					if (doYNegative && ((y == 0) || (y > 0 && GetActive(x, y - 1, z) == false)))
					{
						bool addSide = true;

						if ((y == 0))
						{
							Chunk* pChunk = m_pChunkManager->GetChunk(m_gridX, m_gridY - 1, m_gridZ);
							if (pChunk == NULL || pChunk->IsSetup())
							{
								addSide = pChunk != NULL && (pChunk->GetActive(x, CHUNK_SIZE - 1, z) == false);
							}
						}

						if (addSide)
						{
							int endX = (x / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;
							int endY = (z / CHUNK_SIZE) * CHUNK_SIZE + CHUNK_SIZE;

							if (m_pChunkManager->GetFaceMerging())
							{
								UpdateMergedSide(l_merged, x, y, z, CHUNK_SIZE, CHUNK_SIZE, &p6, &p5, &p2, &p1, x, z, endX, endY, false, false, false, true);
							}

							n1 = vec3(0.0f, -1.0f, 0.0f);
							v1 = m_pRenderer->AddVertexToMesh(p6, n1, r, g, b, a, m_pMesh);
							t1 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 0.0f, m_pMesh);
							v2 = m_pRenderer->AddVertexToMesh(p5, n1, r, g, b, a, m_pMesh);
							t2 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 0.0f, m_pMesh);
							v3 = m_pRenderer->AddVertexToMesh(p2, n1, r, g, b, a, m_pMesh);
							t3 = m_pRenderer->AddTextureCoordinatesToMesh(1.0f, 1.0f, m_pMesh);
							v4 = m_pRenderer->AddVertexToMesh(p1, n1, r, g, b, a, m_pMesh);
							t4 = m_pRenderer->AddTextureCoordinatesToMesh(0.0f, 1.0f, m_pMesh);

							m_pRenderer->AddTriangleToMesh(v1, v2, v3, m_pMesh);
							m_pRenderer->AddTriangleToMesh(v1, v3, v4, m_pMesh);
						}
					}
				}
			}
		}
	}

	// Delete the merged array
	delete l_merged;
}
Exemplo n.º 6
0
// Rebuild
void Chunk::RebuildMesh()
{
	m_isRebuildingMesh = true;
	if (m_pMesh != NULL)
	{
		m_pRenderer->ClearMesh(m_pMesh);
		m_pMesh = NULL;
	}

	CreateMesh();

	// Update our wall flags, so that our neighbors can check if they are surrounded
	UpdateWallFlags();
	UpdateSurroundedFlag();

	Chunk* pChunkXMinus = m_pChunkManager->GetChunk(m_gridX - 1, m_gridY, m_gridZ);
	Chunk* pChunkXPlus = m_pChunkManager->GetChunk(m_gridX + 1, m_gridY, m_gridZ);
	Chunk* pChunkYMinus = m_pChunkManager->GetChunk(m_gridX, m_gridY - 1, m_gridZ);
	Chunk* pChunkYPlus = m_pChunkManager->GetChunk(m_gridX, m_gridY + 1, m_gridZ);
	Chunk* pChunkZMinus = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ - 1);
	Chunk* pChunkZPlus = m_pChunkManager->GetChunk(m_gridX, m_gridY, m_gridZ + 1);

	if (pChunkXMinus != NULL && pChunkXMinus->IsSetup() == true)
		pChunkXMinus->UpdateSurroundedFlag();
	if (pChunkXPlus != NULL && pChunkXPlus->IsSetup() == true)
		pChunkXPlus->UpdateSurroundedFlag();
	if (pChunkYMinus != NULL && pChunkYMinus->IsSetup() == true)
		pChunkYMinus->UpdateSurroundedFlag();
	if (pChunkYPlus != NULL && pChunkYPlus->IsSetup() == true)
		pChunkYPlus->UpdateSurroundedFlag();
	if (pChunkZMinus != NULL && pChunkZMinus->IsSetup() == true)
		pChunkZMinus->UpdateSurroundedFlag();
	if (pChunkZPlus != NULL && pChunkZPlus->IsSetup() == true)
		pChunkZPlus->UpdateSurroundedFlag();

	// Rebuild neighbours
	if (m_rebuildNeighours)
	{
		if (pChunkXMinus != NULL && pChunkXMinus->IsSetup() == true)
			pChunkXMinus->SetNeedsRebuild(true, false);
		if (pChunkXPlus != NULL && pChunkXPlus->IsSetup() == true)
			pChunkXPlus->SetNeedsRebuild(true, false);
		if (pChunkYMinus != NULL && pChunkYMinus->IsSetup() == true)
			pChunkYMinus->SetNeedsRebuild(true, false);
		if (pChunkYPlus != NULL && pChunkYPlus->IsSetup() == true)
			pChunkYPlus->SetNeedsRebuild(true, false);
		if (pChunkZMinus != NULL && pChunkZMinus->IsSetup() == true)
			pChunkZMinus->SetNeedsRebuild(true, false);
		if (pChunkZPlus != NULL && pChunkZPlus->IsSetup() == true)
			pChunkZPlus->SetNeedsRebuild(true, false);

		m_rebuildNeighours = false;
	}

	m_numRebuilds++;
	m_rebuild = false;
}
Exemplo n.º 7
0
bool Item::CheckCollisions(vec3 positionCheck, vec3 previousPosition, vec3 *pNormal, vec3 *pMovement)
{
	float radius = GetRadius();

	vec3 movementCache = *pMovement;

	// World collisions
	bool worldCollision = false;

	vec3 floorPosition;
	if (m_pChunkManager->FindClosestFloor(positionCheck, &floorPosition) == false)
	{
		*pMovement = vec3(0.0f, 0.0f, 0.0f);
		return true;
	}
	else
	{
		int blockX, blockY, blockZ;
		vec3 blockPos;
		int numChecks = 1 + (int)(radius / (Chunk::BLOCK_RENDER_SIZE* 2.0f));
		for (int x = -numChecks; x <= numChecks; x++)
		{
			for (int y = -numChecks; y <= numChecks; y++)
			{
				for (int z = -numChecks; z <= numChecks; z++)
				{
					*pNormal = vec3(0.0f, 0.0f, 0.0f);

					Chunk* pChunk = GetCachedGridChunkOrFromPosition(positionCheck + vec3((Chunk::BLOCK_RENDER_SIZE*2.0f)*x, (Chunk::BLOCK_RENDER_SIZE*2.0f)*y, (Chunk::BLOCK_RENDER_SIZE*2.0f)*z));
					bool active = m_pChunkManager->GetBlockActiveFrom3DPosition(positionCheck.x + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*x), positionCheck.y + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*y), positionCheck.z + ((Chunk::BLOCK_RENDER_SIZE*2.0f)*z), &blockPos, &blockX, &blockY, &blockZ, &pChunk);

					if (active == false)
					{
						if (pChunk == NULL || pChunk->IsSetup() == false)
						{
							*pMovement = vec3(0.0f, 0.0f, 0.0f);
							worldCollision = false;
						}
					}
					else if (active == true)
					{
						Plane3D planes[6];
						planes[0] = Plane3D(vec3(-1.0f, 0.0f, 0.0f), vec3(Chunk::BLOCK_RENDER_SIZE, 0.0f, 0.0f));
						planes[1] = Plane3D(vec3(1.0f, 0.0f, 0.0f), vec3(-Chunk::BLOCK_RENDER_SIZE, 0.0f, 0.0f));
						planes[2] = Plane3D(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, Chunk::BLOCK_RENDER_SIZE, 0.0f));
						planes[3] = Plane3D(vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, -Chunk::BLOCK_RENDER_SIZE, 0.0f));
						planes[4] = Plane3D(vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, 0.0f, Chunk::BLOCK_RENDER_SIZE));
						planes[5] = Plane3D(vec3(0.0f, 0.0f, 1.0f), vec3(0.0f, 0.0f, -Chunk::BLOCK_RENDER_SIZE));

						float distance;
						int inside = 0;
						bool insideCache[6];

						for (int i = 0; i < 6; i++)
						{
							vec3 pointToCheck = blockPos - previousPosition;
							distance = planes[i].GetPointDistance(pointToCheck);

							if (distance < -radius)
							{
								// Outside...
								insideCache[i] = false;
							}
							else if (distance < radius)
							{
								// Intersecting..
								insideCache[i] = true;
							}
							else
							{
								// Inside...
								insideCache[i] = true;
							}
						}

						for (int i = 0; i < 6; i++)
						{
							vec3 pointToCheck = blockPos - positionCheck;
							distance = planes[i].GetPointDistance(pointToCheck);

							if (distance < -radius)
							{
								// Outside...
							}
							else if (distance < radius)
							{
								// Intersecting..
								inside++;
								if (insideCache[i] == false)
								{
									*pNormal += planes[i].mNormal;
								}
							}
							else
							{
								// Inside...
								inside++;
								if (insideCache[i] == false)
								{
									*pNormal += planes[i].mNormal;
								}
							}
						}

						if (inside == 6)
						{
							if (length(*pNormal) <= 1.0f)
							{
								if (length(*pNormal) > 0.0f)
								{
									*pNormal = normalize(*pNormal);
								}

								float dotResult = dot(*pNormal, *pMovement);
								*pNormal *= dotResult;

								*pMovement -= *pNormal;

								worldCollision = true;
							}
						}
					}
				}
			}
		}
	}

	if (worldCollision)
		return true;

	*pMovement = movementCache;

	return false;
}