public Chunk GetChunkAtPosition(ChunkSpacePosition position) { if (position.y < 0 || position.y >= chunkMapSize[1]) { return(null); } Chunk returnChunk = null; int indexY = position.y; int indexX = position.x % chunkMapSize[0]; while (indexX < 0) { indexX += chunkMapSize[0]; } int indexZ = position.z % chunkMapSize[2]; while (indexZ < 0) { indexZ += chunkMapSize[2]; } returnChunk = chunkMap[indexX, indexY, indexZ]; return(returnChunk); }
private bool SlotIsEmpty(ChunkSpacePosition position) { int arrayX = (position.x - worldViewPositionX) + Configuration.CHUNK_VIEW_DISTANCE; int arrayZ = (position.z - worldViewPositionZ) + Configuration.CHUNK_VIEW_DISTANCE; return(loadedChunksCheckArray[arrayX, position.y, arrayZ] == false); }
public List <BlockLight> GetAllLightsWithinMaxRange(ChunkSpacePosition chunkPosition) { int distance = Configuration.MAX_LIGHT_RADIUS + Chunk.SIZE / 2; BlockSpacePosition checkPosition; checkPosition.x = chunkPosition.x * Chunk.SIZE + Chunk.SIZE / 2; checkPosition.y = chunkPosition.y * Chunk.SIZE + Chunk.SIZE / 2; checkPosition.z = chunkPosition.z * Chunk.SIZE + Chunk.SIZE / 2; List <BlockLight> lights = new List <BlockLight>(); foreach (Chunk chunk in ChunkRepository.IterateChunksWithinRadius(checkPosition, distance)) { // TODO -- This isn't super efficient on memory, but required for thread safety. Try to figure out a // better way of doing this. BlockLight[] chunkLights; lock (chunk) { chunkLights = chunk.LightsArray(); } int chunkLightsLength = chunkLights.Length; for (int chunkLightsIndex = 0; chunkLightsIndex < chunkLightsLength; chunkLightsIndex++) { BlockLight light = chunkLights[chunkLightsIndex]; BlockSpacePosition lightPosition = light.chunkPosition.GetBlockSpacePosition(chunk); if (BlockIsNotHidden(lightPosition)) { lights.Add(light); } } } return(lights); }
public void MarkSurroundingChunksForMeshUpdate(Chunk chunk) { if (chunk.BlockGenerationIsComplete()) { chunk.SetLoadState(ChunkLoadState.WaitingForMeshUpdate); chunk.MarkForMeshUpdate(); // Add the adjacent chunks as well, because that changes rendering ChunkSpacePosition position = chunk.WorldPosition(); position.z -= 1; MarkChunkAsNeedingMeshUpdate(position); position = chunk.WorldPosition(); position.z += 1; MarkChunkAsNeedingMeshUpdate(position); position = chunk.WorldPosition(); position.x -= 1; MarkChunkAsNeedingMeshUpdate(position); position = chunk.WorldPosition(); position.x += 1; MarkChunkAsNeedingMeshUpdate(position); position = chunk.WorldPosition(); position.y -= 1; MarkChunkAsNeedingMeshUpdate(position); position = chunk.WorldPosition(); position.y += 1; MarkChunkAsNeedingMeshUpdate(position); } }
private Chunk GetAdjacentChunk(int xOffset, int yOffset, int zOffset) { ChunkSpacePosition position = worldPosition; position.x += xOffset; position.y += yOffset; position.z += zOffset; return(ChunkRepository.GetChunkAtPosition(position)); }
private static void MarkChunkAsNeedingMeshUpdate(ChunkSpacePosition position) { Chunk checkChunk = ChunkRepository.GetChunkAtPosition(position); if (checkChunk != null) { checkChunk.MarkForMeshUpdate(); } }
private Chunk GenerateChunk(ChunkSpacePosition position) { int arrayX = (position.x - worldViewPositionX) + Configuration.CHUNK_VIEW_DISTANCE; int arrayZ = (position.z - worldViewPositionZ) + Configuration.CHUNK_VIEW_DISTANCE; Chunk newChunk = chunkPool.GetChunk(position); ChunkRepository.Add(newChunk); ChunkRepository.SetChunkAtPosition(position, newChunk); loadedChunksCheckArray[arrayX, position.y, arrayZ] = true; newChunk.LoadOrGenerate(); return(newChunk); }
public Chunk GetChunk(ChunkSpacePosition position) { lock (padlock) { Chunk returnChunk = null; if (ChunkIsAvailable()) { returnChunk = GetExistingChunk(); } else { returnChunk = CreateNewChunk(); } lock (returnChunk) { returnChunk.SetWorldPosition(position); } return(returnChunk); } }
// TODO -- Split up this function to make it shorter and more manageable public void CleanupOldChunks() { // TODO -- This is a weird place to update the worldviewposition worldViewPositionX = (int)(Camera.main.transform.position.x / Chunk.SIZE); worldViewPositionZ = (int)(Camera.main.transform.position.z / Chunk.SIZE); for (int xIttr = 0; xIttr < Configuration.CHUNK_VIEW_DISTANCE * 2 + 1; xIttr++) { for (int yIttr = 0; yIttr < chunkArrayHeight; yIttr++) { for (int zIttr = 0; zIttr < Configuration.CHUNK_VIEW_DISTANCE * 2 + 1; zIttr++) { loadedChunksCheckArray[xIttr, yIttr, zIttr] = false; } } } // Get rid of chunks that are too far from the camera for (int chunkIndex = 0; chunkIndex < ChunkRepository.NumberOfChunks(); chunkIndex++) { Chunk chunk = ChunkRepository.GetChunkAtIndex(chunkIndex); // If the chunk is out of range now, return it int xDiff = Mathf.Abs(chunk.WorldPosition().x - worldViewPositionX); int zDiff = Mathf.Abs(chunk.WorldPosition().z - worldViewPositionZ); if ((xDiff > Configuration.CHUNK_VIEW_DISTANCE) || (zDiff > Configuration.CHUNK_VIEW_DISTANCE)) { ChunkSpacePosition location = chunk.WorldPosition(); ChunkRepository.SetChunkAtPosition(location, null); ChunkRepository.Remove(chunk); chunk.MarkForUnload(); unloadChunksList.Add(chunk); } else { int markX = (chunk.WorldPosition().x - worldViewPositionX) + Configuration.CHUNK_VIEW_DISTANCE; int markZ = (chunk.WorldPosition().z - worldViewPositionZ) + Configuration.CHUNK_VIEW_DISTANCE; loadedChunksCheckArray[markX, chunk.WorldPosition().y, markZ] = true; } } }
public Chunk(ChunkSpacePosition worldPosition) { padlock = new object(); unload = false; visible = true; dirty = true; models = new List <Model>(); generatingModelsLock = new object(); worldGenerator = new WorldGenerator(); isShorelineCache = new bool[SIZE, SIZE]; generateBlocksWorkFunction = new BatchProcessor.WorkFunction(GenerateBlocksThread); chunkMeshCluster = null; SetLoadState(ChunkLoadState.LoadingFromDisk); needsMeshUpdate = false; lights = new List <BlockLight>(); modificationList = new Queue <BlockModification>(); adjacentTransparencyModificationList = new Queue <AdjacentTransparencyModification>(2000); // Get the instance variables ready blocks = new Block[SIZE, SIZE, SIZE]; int xIttr, yIttr, zIttr; for (xIttr = 0; xIttr < SIZE; xIttr++) { for (yIttr = 0; yIttr < SIZE; yIttr++) { for (zIttr = 0; zIttr < SIZE; zIttr++) { blocks[xIttr, yIttr, zIttr] = new Block(BlockType.Air); } } } this.worldPosition = worldPosition; isInChunkProcessingList = false; }
public void SetChunkAtPosition(ChunkSpacePosition position, Chunk chunk) { int indexY = position.y; int indexX = position.x % chunkMapSize[0]; while (indexX < 0) { indexX += chunkMapSize[0]; } int indexZ = position.z % chunkMapSize[2]; while (indexZ < 0) { indexZ += chunkMapSize[2]; } chunkMap[indexX, indexY, indexZ] = chunk; }
// TODO -- Make this func shorter public void GenerateMeshes(Chunk chunk) { if (chunk.NeedsMeshUpdate() && (chunk.GetLoadState() == ChunkLoadState.WaitingForMeshUpdate || chunk.GetLoadState() == ChunkLoadState.Done)) { ChunkSpacePosition position = chunk.WorldPosition(); position.z -= 1; Chunk northChunk = ChunkRepository.GetChunkAtPosition(position); position = chunk.WorldPosition(); position.z += 1; Chunk southChunk = ChunkRepository.GetChunkAtPosition(position); position = chunk.WorldPosition(); position.x -= 1; Chunk westChunk = ChunkRepository.GetChunkAtPosition(position); position = chunk.WorldPosition(); position.x += 1; Chunk eastChunk = ChunkRepository.GetChunkAtPosition(position); position = chunk.WorldPosition(); position.y += 1; Chunk aboveChunk = ChunkRepository.GetChunkAtPosition(position); position = chunk.WorldPosition(); position.y -= 1; Chunk belowChunk = ChunkRepository.GetChunkAtPosition(position); if ((northChunk == null || northChunk.BlocksAreGenerating() == false) && (southChunk == null || southChunk.BlocksAreGenerating() == false) && (westChunk == null || westChunk.BlocksAreGenerating() == false) && (eastChunk == null || eastChunk.BlocksAreGenerating() == false) && (aboveChunk == null || aboveChunk.BlocksAreGenerating() == false) && (belowChunk == null || belowChunk.BlocksAreGenerating() == false)) { chunk.GenerateMesh(northChunk, southChunk, westChunk, eastChunk, aboveChunk, belowChunk); } } }
public void SetWorldPosition(ChunkSpacePosition position) { worldPosition = position; }
/// <summary> /// Gather all the lights within the max lighting radius of a given chunk grid position. This is a /// CPU-intensive process, and should be cached when possible. /// </summary> public static List <BlockLight> GetAllLightsWithinMaxRange(ChunkSpacePosition chunkPosition) { return(Instance().GetAllLightsWithinMaxRange(chunkPosition)); }
/// <summary> /// Get the chunk at a specific position within the chunk grid. /// </summary> public static Chunk GetChunkAtPosition(ChunkSpacePosition position) { return(Instance().GetChunkAtPosition(position)); }
/// <summary> /// Set the chunk at specific position within the chunk grid. /// </summary> public static void SetChunkAtPosition(ChunkSpacePosition position, Chunk chunk) { Instance().SetChunkAtPosition(position, chunk); }