private void UpdateGhostChunks()
        {
            if (ghostChunks.Count > 0)
            {
                for (int i = 0; i < ghostChunks.Count; i++)
                {
                    Serialization.SaveChunk(ghostChunks[i], true);
                }

                ghostChunks.Clear();
            }
        }
Beispiel #2
0
        private void ProcessChunkRemoval()
        {
            for (int i = chunksToRemove.Length - 1; i >= 0; i--)
            {
                if (chunks.TryGetValue(chunksToRemove[i], out Chunk chunk))
                {
                    if (!chunk.CanRemove)
                    {
                        continue;
                    }

                    if (chunk.changed)
                    {
                        Serialization.SaveChunk(chunk, true);
                    }
                    chunk.Dispose();

                    if (chunkColliders.Count > 0)
                    {
                        if (chunkColliders.TryGetValue(chunksToRemove[i], out MeshCollider collider))
                        {
                            PoolChunkCollider(collider);
                            chunkColliders.Remove(chunksToRemove[i]);
                        }
                    }

                    if (chunkRenderers.Count > 0)
                    {
                        if (chunkRenderers.TryGetValue(chunksToRemove[i], out MeshRenderer renderer))
                        {
                            PoolChunkRenderer(renderer);
                            chunkRenderers.Remove(chunksToRemove[i]);
                        }
                    }

                    chunks.Remove(chunksToRemove[i]);
                }
            }
        }
        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);
                        }
                    }
                }
            }
        }