Пример #1
0
        /// <summary>
        /// Generate mesh from mesh data
        /// </summary>
        /// <param name="data">Contains data to build mesh</param>
        private void GenerateMesh(MeshData data)
        {
            chunkState = ChunkState.Ready;
            if (data.vertices.Count == 0)
            {
                return;
            }

            Mesh mesh = meshFilter.sharedMesh;

            if (mesh == null)
            {
                mesh = new Mesh();
            }
            else
            {
                mesh.Clear();
            }

            mesh.SetVertices(data.vertices);
            mesh.SetTriangles(data.triangles, 0);
            mesh.uv = new Vector2[data.vertices.Count];
            mesh.SetNormals(data.normals);


            meshFilter.mesh         = mesh;
            meshCollider.sharedMesh = mesh;

            gameObject.SetActive(true);

            for (int i = 0; i < spawners.Count; i++)
            {
                spawnedObjects[i] = spawners[i].SpawnObjects(this);
            }
        }
Пример #2
0
        public void RequestState(ChunkState state)
        {
            switch (state)
            {
            case ChunkState.PrepareSaveData:
            {
                m_isSaveNeeded = true;
            }
            break;

            case ChunkState.Remove:
            {
                if (m_removalRequested)
                {
                    return;
                }
                m_removalRequested = true;

                if (Features.SerializeChunkWhenUnloading)
                {
                    OnNotified(this, ChunkState.PrepareSaveData);
                }
                OnNotified(this, ChunkState.Remove);
            }
            break;
            }

            m_pendingStates = m_pendingStates.Set(state);
        }
Пример #3
0
 public void MarkAsGenerated()
 {
     m_completedStates = m_completedStates.Set(
         ChunkState.Generate |
         ChunkState.FinalizeData
         );
 }
Пример #4
0
        /// <summary>
        /// Offset the location (usually to rebuild)
        /// </summary>
        /// <param name="offset"></param>
        public void OffsetLocation(Point offset, SpeedyDictionary chunkCollection)
        {
            // Remove old chunks and update location
            for (int i = 0; i < chunks.Length; ++i)
            {
                chunkCollection.Remove(new Vector3(location.X, i * chunkSize, location.Y));
            }

            this.location.X += offset.X;
            this.location.Y += offset.Y;

            // Update the chunk locations as well
            for (int i = 0; i < chunks.Length; ++i)
            {
                chunks[i].SetLocation(new Vector3(location.X, i * chunkSize, location.Y));
            }

            // Reset biome location and generate 2D biome map data
            biome.SetLocation(location);
            Parallel.For(0, chunkSize + 2, x =>
            {
                for (int z = 0; z < chunkSize + 2; ++z)
                {
                    biome.GetBaseHeight(x, z, true);
                    biome.GetLocalHumidity(x, z, 0.05f, true);
                }
            });

            // Set dirty flag
            state = ChunkState.Dirty;
        }
Пример #5
0
        private bool GenerateBlueprints()
        {
            Assert.IsTrue(m_completedTasks.Check(ChunkState.Generate),
                          string.Format("[{0},{1},{2}] - GenerateBlueprints set sooner than Generate completed. Pending:{3}, Completed:{4}", Pos.X, Pos.Y, Pos.Z, m_pendingTasks, m_completedTasks)
                          );
            if (!m_completedTasks.Check(ChunkState.Generate))
            {
                return(true);
            }

            m_pendingTasks = m_pendingTasks.Reset(CurrStateGenerateBlueprints);

            if (m_completedTasks.Check(CurrStateGenerateBlueprints))
            {
                OnGenerateBlueprintsDone(this);
                return(false);
            }

            m_completedTasks = m_completedTasks.Reset(CurrStateGenerateBlueprints);

            m_taskRunning = true;
            WorkPoolManager.Add(new ThreadItem(
                                    m_threadID,
                                    arg =>
            {
                Chunk chunk = (Chunk)arg;
                OnGenerateBlueprints(chunk);
            },
                                    this)
                                );

            return(true);
        }
Пример #6
0
        internal ExactPhraseScorer(Weight weight, PhraseQuery.PostingsAndFreq[] postings, Similarity.SimScorer docScorer)
            : base(weight)
        {
            this.docScorer = docScorer;

            chunkStates = new ChunkState[postings.Length];

            endMinus1 = postings.Length - 1;

            // min(cost)
            cost = postings[0].postings.GetCost();

            for (int i = 0; i < postings.Length; i++)
            {
                // Coarse optimization: advance(target) is fairly
                // costly, so, if the relative freq of the 2nd
                // rarest term is not that much (> 1/5th) rarer than
                // the first term, then we just use .nextDoc() when
                // ANDing.  this buys ~15% gain for phrases where
                // freq of rarest 2 terms is close:
                bool useAdvance = postings[i].docFreq > 5 * postings[0].docFreq;
                chunkStates[i] = new ChunkState(postings[i].postings, -postings[i].position, useAdvance);
                if (i > 0 && postings[i].postings.NextDoc() == DocIdSetIterator.NO_MORE_DOCS)
                {
                    noDocs = true;
                    return;
                }
            }
        }
Пример #7
0
        public void Build(VoxelCache cache, Biome biome)
        {
            // Check if neighbors are loaded for next time
            if (state == ChunkState.VoxelsLoaded && NeighborsLoaded())
            {
                state = ChunkState.NeighborsLoaded;
            }

            // Next, build the mesh
            if (state == ChunkState.NeighborsLoaded)
            {
                if (!isEmpty && !isCompletelySolid)
                {
                    // Second pass: Add visible voxels
                    FindVisible(cache, biome);

                    // Third pass: Build mesh out of visible voxels
                    BuildMesh(cache, biome);
                }

                state = ChunkState.Meshed;

                // Remove data from cache and reset
                cache.voxels.Remove(offset);
                cache.ResetData();

                // Set matrix transformation
                transformMatrix = Matrix.CreateTranslation(offset.X, offset.Y, offset.Z);
            }
        }
    /// <summary>
    /// 更新当前块列表
    /// </summary>
    /// <param name="actulChunkList">实际块列表</param>
    /// <param name="currentVector">当前中心块位置</param>
    private void UpdateCurrentChunkList(List <ChunkExample> actulChunkList, ChunkVector2 currentVector)
    {
        for (int i = 0; i < currentCacheChunkList.Count; i++)
        {
            ChunkExample chunk = currentCacheChunkList[i];
            if (!actulChunkList.Contains(chunk))   //实际列表里若不存在当前列表的指定元素 则卸载删除
            {
                chunk.DisplayUnload();             //卸载不存在于实际块列表的块

                currentCacheChunkList.RemoveAt(i); //移除当前块列表中不存在与实际列表的块

                i--;                               //在遍历列表时删除列表元素 记得索引-1 否则无法正确遍历
            }
            else
            {
                actulChunkList.Remove(chunk);//实际块列表移除和当前块列表中相同的元素 注:移除完毕后,实际块列表中的元素
                //先获取chunk的实际状态
                ChunkState actualState = GetChunkStateByRelativePosition(chunk, currentVector);
                chunk.Excute(actualState);
            }
        }

        for (int i = 0; i < actulChunkList.Count; i++)
        {
            ChunkExample chunk = actulChunkList[i];
            //先获取chunk的实际状态
            ChunkState actualState = GetChunkStateByRelativePosition(chunk, currentVector);
            chunk.Excute(actualState);
            currentCacheChunkList.Add(chunk);//这里添加完以后,当前块列表将与实际块列表保持一致
        }
    }
Пример #9
0
        /// <summary>
        /// Initiates content parsing.
        /// </summary>
        /// <param name="received">The request/response data received so far.</param>
        /// <param name="dataPos">Position of the first byte of content data after the headers.</param>
        /// <returns><c>true</c> if the data has been completely parsed.</returns>
        /// <remarks>
        /// <para>
        /// This method will return true indicating that all of the content has been parsed
        /// if the content was included in the blocks received while parsing the headers.
        /// </para>
        /// <note>
        /// The block array passed should not be used again
        /// after making this call.  Ownership should be considered to
        /// have been passed to this instance.
        /// </note>
        /// </remarks>
        /// <exception cref="HttpBadProtocolException">Badly formatted HTTP message.</exception>
        /// <exception cref="HttpContentSizeException">The content size exceeds the maximum allowed.</exception>
        public bool BeginParse(BlockArray received, int dataPos)
        {
            isChunked = String.Compare(headers.Get("Transfer-Encoding", "identity"), "chunked", true) == 0;
            if (isChunked)
            {
                cbContent  = 0;
                chunkState = ChunkState.Start;
                return(ChunkParser(received, dataPos));
            }

            content   = received.Extract(dataPos);
            isRequest = headers.IsRequest;

            // Get the content length.  If this is not present and this is an
            // HTTP request then assume that there is no content.  For responses,
            // we're going to assume that the server will close its side of
            // the socket to signal the end of the content.

            cbContent = headers.Get("Content-Length", -1);
            if (cbContent < 0)
            {
                if (isRequest)
                {
                    cbContent = 0;
                    return(true);
                }

                cbContent = -1;
            }

            // Return true if we already have all of the content.

            return(cbContent != -1 && content.Size >= cbContent);
        }
Пример #10
0
        private bool GenerateData(bool possiblyVisible)
        {
            if (m_completedTasks.Check(CurrStateGenerateData))
            {
                m_pendingTasks = m_pendingTasks.Reset(CurrStateGenerateData);

                OnGenerateDataDone(this);
                return(false);
            }

            // In order to save performance only generate data on-demand
            if (!possiblyVisible)
            {
                return(true);
            }

            m_pendingTasks   = m_pendingTasks.Reset(CurrStateGenerateData);
            m_completedTasks = m_completedTasks.Reset(CurrStateGenerateData);

            m_taskRunning = true;
            WorkPoolManager.Add(new ThreadItem(
                                    m_threadID,
                                    arg =>
            {
                Chunk chunk = (Chunk)arg;
                OnGenerateData(chunk);
            },
                                    this)
                                );

            return(true);
        }
Пример #11
0
    public Chunk(World world, Vector2Int coordination)
    {
        _world        = world;
        _coordination = coordination;

        _nearbyChunks = new Chunk[8];

        _chunkRenderer = new ChunkRenderer(this);

        _state = ChunkState.Unloaded;
        _tiles = new Tile[Length, Height, Length];

        _entities    = new LinkedList <Entity>();
        _collidables = new LinkedList <ICollidable <Entity> >();

        for (int i = 0; i < Length; i++)
        {
            for (int j = 0; j < Height; j++)
            {
                for (int k = 0; k < Length; k++)
                {
                    _tiles[i, j, k] = new Tile(this, (ushort)(i | (j << 4) | (k << 12)));
                }
            }
        }
    }
Пример #12
0
        private void ProcessNotifyState()
        {
            if (m_notifyState == ChunkState.Idle)
            {
                return;
            }

            // Notify neighbors about our state.
            // States after GenerateBlueprints are handled differently because they are related only
            // to the chunk itself rather than chunk's neighbors
            switch (m_notifyState)
            {
#if ENABLE_BLUEPRINTS
            case ChunkState.GenerateBlueprints:
#endif
            case ChunkState.BuildVertices:
                NotifyAll(m_notifyState);
                break;

            default:
                OnNotified(m_notifyState);
                break;
            }

            m_notifyState = ChunkState.Idle;
        }
Пример #13
0
        public override void OnNotified(ChunkState state)
        {
            int eventIndex = -1;

            switch (state)
            {
#if ENABLE_BLUEPRINTS
            case ChunkState.GenerateBlueprints:
                eventIndex = 0;
                break;
#endif
            case ChunkState.BuildVertices:
                eventIndex = 1;
                break;
            }

            if (eventIndex >= 0)
            {
                // Check completition
                int cnt = ++m_eventCnt[eventIndex];
                if (cnt < Subscribers.Length)
                {
                    return;
                }

                // Reset counter and process/queue event
                m_eventCnt[eventIndex] = 0;
            }

            // Queue operation
            m_pendingTasks = m_pendingTasks.Set(state);
        }
Пример #14
0
        internal ExactPhraseScorer(Weight weight, PhraseQuery.PostingsAndFreq[] postings, Similarity.SimScorer docScorer)
            : base(weight)
        {
            this.DocScorer = docScorer;

            ChunkStates = new ChunkState[postings.Length];

            EndMinus1 = postings.Length - 1;

            // min(cost)
            Cost_Renamed = postings[0].Postings.Cost();

            for (int i = 0; i < postings.Length; i++)
            {
                // Coarse optimization: advance(target) is fairly
                // costly, so, if the relative freq of the 2nd
                // rarest term is not that much (> 1/5th) rarer than
                // the first term, then we just use .nextDoc() when
                // ANDing.  this buys ~15% gain for phrases where
                // freq of rarest 2 terms is close:
                bool useAdvance = postings[i].DocFreq > 5 * postings[0].DocFreq;
                ChunkStates[i] = new ChunkState(postings[i].Postings, -postings[i].Position, useAdvance);
                if (i > 0 && postings[i].Postings.NextDoc() == DocIdSetIterator.NO_MORE_DOCS)
                {
                    NoDocs = true;
                    return;
                }
            }
        }
Пример #15
0
        public void Serialization_WriteAndReadChunk()
        {
            const ushort location = 7, value = 58;
            const byte   b = 0xFE;

            var blockDataPoolingRegistry = new BlockDataPoolRegistry();

            blockDataPoolingRegistry.Register(value, () => new MockBlockData());

            var chunkState1 = new ChunkState();
            var chunkState2 = new ChunkState();

            var blockData = chunkState1.SetBlock(location, value, blockDataPoolingRegistry) as MockBlockData;

            blockData.theByte = b;

            var buffer = new ResizableByteBuffer();

            buffer.RestartForWriting();
            chunkState1.Serialize(buffer);

            buffer.RestartForReading();
            chunkState2.Deserialize(buffer, blockDataPoolingRegistry);

            var resultId       = chunkState2.GetBlockID(location);
            var resultData     = (MockBlockData)chunkState2.GetBlockData(location);
            var resultDataByte = resultData.theByte;

            Assert.AreEqual(value, resultId);
            Assert.AreEqual(b, resultDataByte);
        }
Пример #16
0
 public void Unload()
 {
     if (state != ChunkState.Unloaded)
     {
         state = ChunkState.Unloaded;
         voxelObject.getLoadedChunks().Remove(this);
     }
 }
Пример #17
0
 public void Load()
 {
     if (state != ChunkState.Loaded)
     {
         state = ChunkState.Loaded;
         voxelObject.getLoadedChunks().Add(this);
     }
 }
Пример #18
0
        //public Biome biome;

        public Chunk(int x, int y)
        {
            this.x     = x;
            this.y     = y;
            terrain    = new Tile[chunkSize, chunkSize];
            tiles      = new Tile[chunkSize, chunkSize];
            heightMap  = new double[chunkSize, chunkSize];
            chunkState = ChunkState.NotGenerated;
        }
Пример #19
0
        public void MarkDataOutOfSync(bool enqueueChunk = true)
        {
            _state = ChunkState.DataOutOfSync;

            if (enqueueChunk)
            {
                _world.ChunkManager.EnqueueChunkForBuild(this);
            }
        }
Пример #20
0
        public Task <ChunkState> GetStateAsync()
        {
            var chunkState = new ChunkState
            {
                ChangeIndex = State.ChangeIndex,
                Image       = State.Image
            };

            return(Task.FromResult(chunkState));
        }
Пример #21
0
        public void MarkAsLoaded()
        {
            m_completedTasks = m_completedTasks.Set(
                ChunkState.Generate |
#if ENABLE_BLUEPRINTS
                ChunkState.GenerateBlueprints |
#endif
                ChunkState.FinalizeData
                );
        }
Пример #22
0
 protected override JsonValue ReadItem(Stream stream, byte itemFormatVersion, ChunkState state)
 {
     if (itemFormatVersion == 0)
     {
         return(readJsonValueFormat0(stream, state));
     }
     else
     {
         throw new Exception($"Unsupported item format version: {itemFormatVersion}");
     }
 }
Пример #23
0
    // Clears all SpriteRenderer objects from this
    // chunk and returns them to a pool.
    public void ClearSprites(WorldRender rend)
    {
        for (int i = 0; i < rects.Count; ++i)
        {
            rend.ReturnTileRect(rects[i]);
        }

        rects.Clear();

        state = ChunkState.Empty;
    }
Пример #24
0
        /// <summary>
        /// Set up a empty array of chunks according to the chunk sizes
        /// </summary>
        public ChunkStack(Point location, int chunkSize, int numberOfChunks)
        {
            state  = ChunkState.New;
            chunks = new Chunk[numberOfChunks];
            biome  = new Biome(location, chunkSize);

            this.numberOfChunks = numberOfChunks;
            this.location       = location;
            this.chunkSize      = chunkSize;
            this.stackHeight    = chunkSize * numberOfChunks;
        }
Пример #25
0
 public bool SurroundingChunksMinimumState(ChunkState minimumState)
 {
     foreach (var chunk in EightSurroundingChunks)
     {
         if (chunk.State < minimumState)
         {
             return(false);
         }
     }
     return(true);
 }
Пример #26
0
        public void SetComplete()
        {
            if (stream != null)
            {
                stream.Close();
                stream = null;
            }

            request        = null;
            bytesPerSecond = 0;
            state          = ChunkState.Complete;
        }
Пример #27
0
        public void SetCancelled()
        {
            if (stream != null)
            {
                stream.Close();
                stream = null;
            }

            request        = null;
            bytesPerSecond = 0;
            state          = ChunkState.Cancel;
        }
Пример #28
0
        public void Reset()
        {
            // Make sure the number of items left to process is zero!
            while (0 != Interlocked.CompareExchange(ref m_genericWorkItemsLeftToProcess, 0, 0))
            {
                Assert.IsTrue(false, "Attempting to release a chunk with unprocessed generic work items");
            }
            m_genericWorkItemsLeftToProcess = 0;

            UnregisterFromNeighbors();

            // Reset chunk events
            for (int i = 0; i < m_eventCnt.Length; i++)
            {
                m_eventCnt[i] = 0;
            }

            m_requestedRemoval  = false;
            m_taskRunning       = false;
            m_firstFinalization = true;

            m_lod = 0;

            m_notifyState    = m_notifyState.Reset();
            m_pendingTasks   = m_pendingTasks.Reset();
            m_completedTasks = m_completedTasks.Reset();
            m_refreshTasks   = m_refreshTasks.Reset();

            m_setBlockQueue.Clear();

            // Reset blocks
            Blocks.Reset();

            PossiblyVisible = false;

            MinRenderX         = EngineSettings.ChunkConfig.Mask;
            MaxRenderX         = 0;
            MinRenderY         = EngineSettings.ChunkConfig.Mask;
            MaxRenderY         = 0;
            MinRenderZ         = EngineSettings.ChunkConfig.Mask;
            MaxRenderZ         = 0;
            m_lowestEmptyBlock = EngineSettings.ChunkConfig.Mask;

            // Reset sections
            NonEmptyBlocks = 0;
            IsBuilt        = false;

            m_drawCallBatcher.Clear();

            ResetGeometryBoundingMesh();

            ResetEvent();
        }
Пример #29
0
    // Preloads some data
    public void Preload(MonoBehaviour mono)
    {
        if (state >= ChunkState.PRELOADED)
        {
            return;
        }

        GenerateTerrain();
        PrepareWaterList();
        //mono.StartCoroutine("PrepareWaterList", this);//PrepareWaterList();
        state = ChunkState.PRELOADED;
    }
Пример #30
0
    void GenerateTerrain()
    {
        for (int x = (int)bounds.xMin; x < bounds.xMax + 1; x++)
        {
            for (int z = (int)bounds.zMin; z < bounds.zMax + 1; z++)
            {
                Vector2Int localPoint = GetLocalCoord(new Vector2Int(x, z));
                terrainHeightMap[localPoint.x, localPoint.y] = TerrainGen.GenerateTerrainAt(x, z);
            }
        }

        state = ChunkState.PRELOADED;
    }
Пример #31
0
 protected override long ReadItem(Stream stream, byte itemFormatVersion, ChunkState state)
 {
     if (itemFormatVersion == 1)
     {
         var result = state.PrevId + stream.ReadInt64Optim();
         state.PrevId = result;
         return(result);
     }
     else
     {
         throw new NotSupportedException($"Match format {itemFormatVersion} is not supported.");
     }
 }
Пример #32
0
 public override void WriteBase64(byte[] buffer, int index, int count)
 {
     if (chunkState == null)
     {
         chunkState = new ChunkState();
     }
     int remaining = chunkState.AppendBytes(buffer, index, count);
     if (chunkState.Count == ChunkingUtils.ChunkSize)
     {
         CreateChunkMessage();
     }
     int end=index + count - 1;
     while (remaining > 0)
     {
         int start = end - remaining + 1;
         remaining=chunkState.AppendBytes(buffer,start,remaining);
         if (chunkState.Count == ChunkingUtils.ChunkSize)
         {
             CreateChunkMessage();
         }
     }
 }
Пример #33
0
 public static ChunkState Set(this ChunkState state, ChunkState flag)
 {
     return state|flag;
 }
Пример #34
0
 public static bool CheckAny(this ChunkState state, ChunkState flag)
 {
     return (state & flag) != 0;
 }
Пример #35
0
 public static bool Check(this ChunkState state, ChunkState flag)
 {
     return (state & flag) == flag;
 }
Пример #36
0
 public static ChunkState Reset(this ChunkState state, ChunkState flag)
 {
     return state&(~flag);
 }
Пример #37
0
        void CreateChunkMessage()
        {
            ChunkBodyWriter bodyWriter = new ChunkBodyWriter(this.WriteChunkCallback, this.chunkState);
            Message chunk = Message.CreateMessage(this.version, ChunkingUtils.ChunkAction, bodyWriter);
            chunk.Headers.Add(this.messageIdHeader);
            chunk.Headers.Add(MessageHeader.CreateHeader(ChunkingUtils.ChunkNumberHeader, ChunkingUtils.ChunkNs, this.chunkNum, true));
            this.outputChannel.Send(chunk, chunkingTimeout.RemainingTime());
            Console.WriteLine(" > Sent chunk {0} of message {1}", chunkNum, this.messageId);
            this.chunkNum++;
            this.chunkState = new ChunkState();

        }
Пример #38
0
        public Chunk(Vector3Int chunkCachePosition, Block[] blocks, MappingFunction mappingFunction, GetNeighborChunk getNeighborChunk)
        {
            ChunkState = ChunkState.AwaitingGenerate; // set initial state to awaiting generation.
            ChunkCachePosition = chunkCachePosition; // set the relative position.
            m_blocks = blocks;
            m_mappingFunction = mappingFunction;
            m_getNeighborChunk = getNeighborChunk;

            // calculate the real world position.
            Position = new Vector3Int(ChunkCachePosition.X * SizeInBlocks,
                                           ChunkCachePosition.Y * SizeInBlocks,
                                           ChunkCachePosition.Z * SizeInBlocks);

            // calculate bounding-box.
            BoundingBox = new BoundingBox(new Vector3(Position.X, Position.Y, Position.Z),
                                          new Vector3(Position.X + SizeInBlocks, Position.Y + SizeInBlocks,
                                                      Position.Z + SizeInBlocks));
            #if DEBUG
            MainEngine.GetEngineInstance().DebugOnlyDebugManager.RegisterInGameDebuggable(this);
            #endif
        }
Пример #39
0
 public void PrepForRemoval()
 {
     ChunkState = ChunkState.AwaitingRemoval;
     if (VertexBuffer != null)
     {
         VertexBuffer.Dispose();
         VertexBuffer = null;
     }
     if (IndexBuffer != null)
     {
         IndexBuffer.Dispose();
         IndexBuffer = null;
     }
     //TODO : if dirty flag is true send this chunk to the persistance manager
 }
Пример #40
0
 public override void SetMeshDirty(int x, int y, int z)
 {
     if (ChunkState == ChunkState.Ready)
     {
         ChunkState = ChunkState.AwaitingBuild;
     }
     var edgesBlockIsIn = GetChunkEdgesBlockIsIn(x, y, z);
     foreach (var edge in edgesBlockIsIn)
     {
         var neighborChunk = m_getNeighborChunk(this, edge);
         if (neighborChunk != null && neighborChunk.ChunkState == ChunkState.Ready)
         {
             neighborChunk.ChunkState = ChunkState.AwaitingBuild;
         }
     }
 }
Пример #41
0
 public void ChangeState(ChunkManager manager, ChunkState newState)
 {
     //log.Write(newState.ToString(), this.ToString(), "");
     if (StateChanged != null) StateChanged(manager, this, newState);
     _state = newState;
 }
Пример #42
0
        public void NeighborChangedStateCallback(ChunkManager manager, Chunk chunk, ChunkState state)
        {
            switch (state)
            {
                case ChunkState.Loaded:
                    {
                        LightDependenciesFlag |= Coords.Neighbors(ref chunk.Coords);
                        break;
                    }
                case ChunkState.PendingLight:
                    break;
                case ChunkState.Lighting:
                    break;
                case ChunkState.PendingBuild:
                    {
                        BuildDependenciesFlag |= Coords.Neighbors(ref chunk.Coords);
                        break;
                    }
                case ChunkState.Built:
                    break;
                case ChunkState.PendingRebuild:
                    break;
                case ChunkState.Unloading:
                    {
                        byte val = Coords.Neighbors(ref chunk.Coords);
                        if((NeighborsInMemoryFlag & val) == val) NeighborsInMemoryFlag -= val;
                        if((LightDependenciesFlag & val) == val) LightDependenciesFlag -= val;
                        if((BuildDependenciesFlag & val) == val) BuildDependenciesFlag -= val;

                        StateChanged -= chunk.NeighborChangedStateCallback;
                        chunk.StateChanged -= NeighborChangedStateCallback;

                        break;
                    }
            }
        }