示例#1
0
        public void ProcessSetBlockQueue()
        {
            // Modify blocks
            for (int i = 0; i < m_setBlockQueue.Count; i++)
            {
                SetBlockContext context = m_setBlockQueue[i];

                Blocks[context.BX, context.BY, context.BZ] = context.Block;

                // Chunk needs to be finialized again

                /*
                 *  TODO: This can be optimized. There's no need to recompute min/max chunk index
                 *  everytime we update a block. An update is only required when we delete/add a block.
                 *  The best would be having two 2D [chunkWidth,chunkHeight] arrays storing min and
                 *  max height indexes respectively. This would be helpful for other things as well.
                 */
                RefreshState(ChunkState.FinalizeData);

                // Let us know that there was a change in data since the last time the chunk
                // was loaded so we can enqueue serialization only when it is really necessary.
                m_refreshTasks = m_refreshTasks.Set(ChunkState.Serialize);

                // Ask for rebuild of geometry
                RefreshState(ChunkState.BuildVertices);

                // Notify subscribers
                if (context.SubscribersMask > 0)
                {
                    for (int j = 0; j < Subscribers.Length; j++)
                    {
                        Chunk subscriber = (Chunk)Subscribers[j];
                        if (subscriber != null && ((context.SubscribersMask >> j) & 1) != 0)
                        {
                            subscriber.RefreshState(ChunkState.BuildVertices);
                        }
                    }
                }
            }

            m_setBlockQueue.Clear();
        }
示例#2
0
文件: Chunk.cs 项目: bejita968/Voxe
        private void ProcessSetBlockQueue()
        {
            if (m_setBlockQueue.Count <= 0)
            {
                return;
            }

            StateManager.RequestState(ChunkState.FinalizeData | ChunkState.BuildVerticesNow);

            int rebuildMask = 0;

            // Modify blocks
            for (int j = 0; j < m_setBlockQueue.Count; j++)
            {
                SetBlockContext context = m_setBlockQueue[j];

                int x, y, z;
                Helpers.GetIndex3DFrom1D(context.Index, out x, out y, out z);
                this[x, y, z] = context.Block;

                if (
                    // Only check neighbors if it is still needed
                    rebuildMask == 0x3f ||
                    // Only check neighbors when it is a change of a block on a chunk's edge
                    (((x + 1) & EngineSettings.ChunkConfig.Mask) > 1 &&
                     ((y + 1) & EngineSettings.ChunkConfig.Mask) > 1 &&
                     ((z + 1) & EngineSettings.ChunkConfig.Mask) > 1)
                    )
                {
                    continue;
                }

                int cx = Pos.X;
                int cy = Pos.Y;
                int cz = Pos.Z;

                // If it is an edge position, notify neighbor as well
                // Iterate over neighbors and decide which ones should be notified to rebuild
                for (int i = 0; i < StateManager.Listeners.Length; i++)
                {
                    ChunkEvent listener = StateManager.Listeners[i];
                    if (listener == null)
                    {
                        continue;
                    }

                    // No further checks needed once we know all neighbors need to be notified
                    if (rebuildMask == 0x3f)
                    {
                        break;
                    }

                    ChunkStateManagerClient listenerChunk = (ChunkStateManagerClient)listener;

                    int lx = listenerChunk.chunk.Pos.X;
                    int ly = listenerChunk.chunk.Pos.Y;
                    int lz = listenerChunk.chunk.Pos.Z;

                    if ((ly == cy || lz == cz) &&
                        (
                            // Section to the left
                            ((x == 0) && (lx + EngineSettings.ChunkConfig.Mask == cx)) ||
                            // Section to the right
                            ((x == EngineSettings.ChunkConfig.Mask) && (lx - EngineSettings.ChunkConfig.Mask == cx))
                        ))
                    {
                        rebuildMask = rebuildMask | (1 << i);
                    }

                    if ((lx == cx || lz == cz) &&
                        (
                            // Section to the bottom
                            ((y == 0) && (ly + EngineSettings.ChunkConfig.Mask == cy)) ||
                            // Section to the top
                            ((y == EngineSettings.ChunkConfig.Mask) && (ly - EngineSettings.ChunkConfig.Mask == cy))
                        ))
                    {
                        rebuildMask = rebuildMask | (1 << i);
                    }

                    if ((ly == cy || lx == cx) &&
                        (
                            // Section to the back
                            ((z == 0) && (lz + EngineSettings.ChunkConfig.Mask == cz)) ||
                            // Section to the front
                            ((z == EngineSettings.ChunkConfig.Mask) && (lz - EngineSettings.ChunkConfig.Mask == cz))
                        ))
                    {
                        rebuildMask = rebuildMask | (1 << i);
                    }
                }
            }

            m_setBlockQueue.Clear();

            // Notify neighbors that they need to rebuilt their geometry
            if (rebuildMask > 0)
            {
                for (int j = 0; j < StateManager.Listeners.Length; j++)
                {
                    ChunkStateManagerClient listener = (ChunkStateManagerClient)StateManager.Listeners[j];
                    if (listener != null && ((rebuildMask >> j) & 1) != 0)
                    {
                        listener.RequestState(ChunkState.FinalizeData | ChunkState.BuildVerticesNow);
                    }
                }
            }
        }