public void SetBlocks(int fromX, int fromY, int fromZ, int toX, int toY, int toZ, Block block) { VoxLogger.Log("VoxelWorld : SetBlocks " + block); FixValues(ref fromX, ref toX); FixValues(ref fromY, ref toY); FixValues(ref fromZ, ref toZ); int3 chunkFrom = Helpers.ContainingChunkPosition(fromX, fromY, fromZ); int3 chunkTo = Helpers.ContainingChunkPosition(toX, toY, toZ); int minY = Helpers.Mod(fromY, Chunk.CHUNK_SIZE); for (int cy = chunkFrom.y; cy <= chunkTo.y; cy += Chunk.CHUNK_SIZE, minY = 0) { int maxY = math.min(toY - cy, Chunk.CHUNK_SIZE - 1); int minZ = Helpers.Mod(fromZ, Chunk.CHUNK_SIZE); for (int cz = chunkFrom.z; cz <= chunkTo.z; cz += Chunk.CHUNK_SIZE, minZ = 0) { int maxZ = math.min(toZ - cz, Chunk.CHUNK_SIZE - 1); int minX = Helpers.Mod(fromX, Chunk.CHUNK_SIZE); for (int cx = chunkFrom.x; cx <= chunkTo.x; cx += Chunk.CHUNK_SIZE, minX = 0) { bool ghostChunk = false; int3 chunkPosition = new int3(cx, cy, cz); VoxLogger.Log("VoxelWorld : SetBlocks " + block + " | Update chunk at " + chunkPosition + "."); Chunk chunk = GetChunk(chunkPosition); if (chunk == null) { VoxLogger.Log("VoxelWorld : SetBlocks " + block + " | Chunk is ghost chunk."); ghostChunk = true; chunk = CreateChunk(chunkPosition); chunk.render = false; chunks.Add(chunkPosition, chunk); chunk.NeedsTerrain = !Serialization.LoadChunk(chunk, true); if (chunk.NeedsTerrain) { AddToQueue(generateQueue, chunkPosition, 0); } ghostChunks.Add(chunk); } int maxX = math.min(toX - cx, Chunk.CHUNK_SIZE - 1); int3 from = new int3(minX, minY, minZ); int3 to = new int3(maxX, maxY, maxZ); // Only update if it's placing blocks on the edges of the chunk and // if they are the last/first ones in the loop. We don't need the chunks // to update each other. bool updateNorth = (from.z == Chunk.CHUNK_SIZE - 1 || to.z == Chunk.CHUNK_SIZE - 1) && cz == chunkTo.z; bool updateSouth = (from.z == 0 || to.z == 0) && cz == chunkFrom.z; bool updateEast = (from.x == Chunk.CHUNK_SIZE - 1 || to.x == Chunk.CHUNK_SIZE - 1) && cx == chunkTo.x; bool updateWest = (from.x == 0 || to.x == 0) && cx == chunkFrom.x; bool updateTop = (from.y == Chunk.CHUNK_SIZE - 1 || to.y == Chunk.CHUNK_SIZE - 1) && cy == chunkTo.y; bool updateBottom = (from.y == 0 || to.y == 0) && cy == chunkFrom.y; chunk.SetRangeRaw(from, to, block); if (!ghostChunk) { // Only update this chunk. chunk.UpdateChunk(); UpdateChunkNeighbors(chunkPosition, updateNorth, updateSouth, updateEast, updateWest, updateTop, updateBottom); } else if (!chunk.NeedsTerrain) { VoxLogger.Log("VoxelWorld : SetBlocks " + block + " | Saving ghost chunk " + chunk + "."); Serialization.SaveChunk(chunk, true); DestroyChunk(chunk); } } } } }