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; }
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(); } }
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; }
// 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; }
// 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; }
// 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; }
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; }