コード例 #1
0
        public void ProcessChunk(Chunk chunk)
        {
            Profiler.BeginSample("ProcessChunk");

            ChunkStateManagerClient stateManager = chunk.stateManager;

            int tx = m_clipmap.TransformX(chunk.pos.x / Env.ChunkSize);
            int ty = m_clipmap.TransformY(chunk.pos.y / Env.ChunkSize);
            int tz = m_clipmap.TransformZ(chunk.pos.z / Env.ChunkSize);

            // Chunk is too far away. Remove it
            if (!m_clipmap.IsInsideBounds_Transformed(tx, ty, tz))
            {
                stateManager.RequestState(ChunkState.Remove);
            }
            else
            {
                // Dummy collider example - create a collider for chunks directly surrounding the viewer
                int xd = Helpers.Abs((m_viewerPos.x - chunk.pos.x) / Env.ChunkSize);
                int yd = Helpers.Abs((m_viewerPos.y - chunk.pos.y) / Env.ChunkSize);
                int zd = Helpers.Abs((m_viewerPos.z - chunk.pos.z) / Env.ChunkSize);
                chunk.NeedsCollider = xd <= 1 && yd <= 1 && zd <= 1;

                if (!UseFrustumCulling)
                {
                    ClipmapItem item = m_clipmap.Get_Transformed(tx, ty, tz);

                    // Chunk is in visibilty range. Full update with geometry generation is possible
                    if (item.IsInVisibleRange)
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = true;
                        stateManager.Visible         = true;
                    }
                    // Chunk is in cached range. Full update except for geometry generation
                    else
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = true;
                        stateManager.Visible         = false;
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Sends a save request to all chunk currently loaded
        /// </summary>
        /// <param name="world">World holding chunks</param>
        /// <returns>List of chunks waiting to be saved.</returns>
        public static List <Chunk> SaveAll(World world)
        {
            if (world == null || !Features.UseSerialization)
            {
                return(null);
            }

            List <Chunk> chunksToSave = new List <Chunk> ();

            foreach (Chunk chunk in world.chunks.chunkCollection)
            {
                // Ignore chunks that can't be saved at the moment
                ChunkStateManagerClient stateManager = chunk.stateManager;
                if (!stateManager.IsSavePossible)
                {
                    continue;
                }

                chunksToSave.Add(chunk);
                stateManager.RequestState(ChunkState.PrepareSaveData);
            }

            return(chunksToSave);
        }
コード例 #3
0
        public void ProcessChunk(Chunk chunk)
        {
            Profiler.BeginSample("ProcessChunk");

            ChunkStateManagerClient stateManager = chunk.stateManager;

            int xd = (m_viewerPos.x - chunk.pos.x) / Env.ChunkSize;
            int yd = (m_viewerPos.y - chunk.pos.y) / Env.ChunkSize;
            int zd = (m_viewerPos.z - chunk.pos.z) / Env.ChunkSize;

            int hRadius = HorizontalChunkLoadRadius;
            int vRadius = VerticalChunkLoadRadius;
            int xDist   = xd * xd + zd * zd;
            int yDist   = yd * yd;

            // Remove the chunk if it is too far away
            if (xDist > hRadius * hRadius || yDist > vRadius * vRadius)
            {
                stateManager.RequestState(ChunkState.Remove);
            }
            else
            {
                // Dummy collider example - create a collider for chunks directly surrounding the viewer
                chunk.NeedsCollider = Helpers.Abs(xd) <= 1 && Helpers.Abs(yd) <= 1 && Helpers.Abs(zd) <= 1;

                if (!UseFrustumCulling)
                {
                    // Update visibility information
                    stateManager.Visible = xDist <= HorizontalChunkLoadRadius * HorizontalChunkLoadRadius &&
                                           yDist <= VerticalChunkLoadRadius * VerticalChunkLoadRadius;
                    stateManager.PossiblyVisible = true;
                }
            }

            Profiler.EndSample();
        }
コード例 #4
0
        public void Update()
        {
            ChunkStateManagerClient stateManager = chunk.stateManager;

            if (!stateManager.IsUpdateBlocksPossible)
            {
                return;
            }

            //UnityEngine.Debug.Log(m_setBlockQueue.Count);

            if (m_setBlockQueue.Count > 0)
            {
                if (rebuildMaskGeometry < 0)
                {
                    rebuildMaskGeometry = 0;
                }
                if (rebuildMaskCollider < 0)
                {
                    rebuildMaskCollider = 0;
                }

                var timeBudget = Globals.SetBlockBudget;

                // Modify blocks
                int j;
                for (j = 0; j < m_setBlockQueue.Count; j++)
                {
                    timeBudget.StartMeasurement();
                    m_setBlockQueue[j].Apply(this);
                    timeBudget.StopMeasurement();

                    // Sync edges if there's enough time

                    /*if (!timeBudget.HasTimeBudget)
                     * {
                     ++j;
                     *  break;
                     * }*/
                }

                rebuildMaskCollider |= rebuildMaskGeometry;

                if (j == m_setBlockQueue.Count)
                {
                    m_setBlockQueue.Clear();
                }
                else
                {
                    m_setBlockQueue.RemoveRange(0, j);
                    return;
                }
            }

            long now = Globals.Watch.ElapsedMilliseconds;

            // Request a geometry update at most 10 times a second
            if (rebuildMaskGeometry >= 0 && now - lastUpdateTimeGeometry >= 100)
            {
                lastUpdateTimeGeometry = now;

                // Request rebuild on this chunk
                stateManager.RequestState(ChunkState.BuildVerticesNow);

                // Notify neighbors that they need to rebuild their geometry
                if (rebuildMaskGeometry > 0)
                {
                    var listeners = stateManager.Listeners;
                    for (int j = 0; j < listeners.Length; j++)
                    {
                        ChunkStateManagerClient listener = (ChunkStateManagerClient)listeners[j];
                        if (listener != null && ((rebuildMaskGeometry >> j) & 1) != 0)
                        {
                            // Request rebuild on neighbor chunks
                            listener.RequestState(ChunkState.BuildVerticesNow);
                        }
                    }
                }

                rebuildMaskGeometry = -1;
            }

            // Request a collider update at most 4 times a second
            if (chunk.NeedsCollider && rebuildMaskCollider >= 0 && now - lastUpdateTimeCollider >= 250)
            {
                lastUpdateTimeCollider = now;

                // Request rebuild on this chunk
                stateManager.RequestState(ChunkState.BuildColliderNow);

                // Notify neighbors that they need to rebuilt their geometry
                if (rebuildMaskCollider > 0)
                {
                    var listeners = stateManager.Listeners;
                    for (int j = 0; j < listeners.Length; j++)
                    {
                        ChunkStateManagerClient listener = (ChunkStateManagerClient)listeners[j];
                        if (listener != null && ((rebuildMaskCollider >> j) & 1) != 0)
                        {
                            // Request rebuild on neighbor chunks
                            if (listener.chunk.NeedsCollider)
                            {
                                listener.RequestState(ChunkState.BuildColliderNow);
                            }
                        }
                    }
                }

                rebuildMaskCollider = -1;
            }
        }
コード例 #5
0
        public void ProcessChunk(Chunk chunk)
        {
            int xd = Helpers.Abs((m_viewerPos.x - chunk.pos.x) >> Env.ChunkPower);
            int yd = Helpers.Abs((m_viewerPos.y - chunk.pos.y) >> Env.ChunkPower);
            int zd = Helpers.Abs((m_viewerPos.z - chunk.pos.z) >> Env.ChunkPower);

            int tx = m_clipmap.TransformX(chunk.pos.x >> Env.ChunkPower);
            int ty = m_clipmap.TransformY(chunk.pos.y >> Env.ChunkPower);
            int tz = m_clipmap.TransformZ(chunk.pos.z >> Env.ChunkPower);

            ChunkStateManagerClient stateManager = (ChunkStateManagerClient)chunk.stateManager;

            // Chunk is too far away. Remove it
            if (!m_clipmap.IsInsideBounds_Transformed(tx, ty, tz))
            {
                stateManager.RequestState(ChunkState.Remove);
            }
            else
            {
                // Dummy collider example - create a collider for chunks directly surrounding the viewer
                chunk.NeedsCollider = xd <= 1 && yd <= 1 && zd <= 1;

                // Chunk is within view frustum
                if (FullLoadOnStartUp || IsChunkInViewFrustum(chunk))
                {
                    ClipmapItem item = m_clipmap.Get_Transformed(tx, ty, tz);

                    // Chunk is within visibilty range. Full update with geometry generation is possible
                    if (item.IsWithinVisibleRange)
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = true;
                        stateManager.Visible         = true;
                    }
                    // Chunk is within cached range. Full update except for geometry generation
                    else // if (item.IsWithinCachedRange)
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = true;
                        stateManager.Visible         = false;
                    }
                }
                else
                {
                    ClipmapItem item = m_clipmap.Get_Transformed(tx, ty, tz);

                    // Chunk is not in the view frustum but still within cached range
                    if (item.IsWithinCachedRange)
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = false;
                        stateManager.Visible         = false;
                    }
                    else
                    // Weird state
                    {
                        Assert.IsFalse(true);
                        stateManager.RequestState(ChunkState.Remove);
                    }
                }
            }
        }
コード例 #6
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);
                    }
                }
            }
        }
コード例 #7
0
ファイル: ChunkBlocks.cs プロジェクト: TrueLoop/Voxelmetric
        public void Update()
        {
            ChunkStateManagerClient stateManager = (ChunkStateManagerClient)chunk.stateManager;

            if (m_setBlockQueue.Count > 0)
            {
                if (rebuildMaskGeometry < 0)
                {
                    rebuildMaskGeometry = 0;
                }
                if (rebuildMaskCollider < 0)
                {
                    rebuildMaskCollider = 0;
                }

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

                    int x, y, z;
                    Helpers.GetChunkIndex3DFrom1D(context.Index, out x, out y, out z);

                    Vector3Int pos       = new Vector3Int(x, y, z);
                    Vector3Int globalPos = pos + chunk.pos;

                    BlockData oldBlockData = blocks.Get(context.Index);

                    Block oldBlock = m_blockTypes[oldBlockData.Type];
                    Block newBlock = m_blockTypes[context.Block.Type];
                    oldBlock.OnDestroy(chunk, pos, globalPos);
                    newBlock.OnCreate(chunk, pos, globalPos);

                    blocks.Set(context.Index, context.Block);

                    if (context.SetBlockModified)
                    {
                        BlockModified(new BlockPos(x, y, z), globalPos, context.Block);

                        chunk.blocks.contentsInvalidated = true;
                    }

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

                    int cx = chunk.pos.x;
                    int cy = chunk.pos.y;
                    int cz = chunk.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 (rebuildMaskGeometry == 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
                                ((pos.x == 0) && (lx + Env.ChunkSize == cx)) ||
                                // Section to the right
                                ((pos.x == Env.ChunkMask) && (lx - Env.ChunkSize == cx))
                            ))
                        {
                            rebuildMaskGeometry = rebuildMaskGeometry | (1 << i);
                        }

                        if ((lx == cx || lz == cz) &&
                            (
                                // Section to the bottom
                                ((pos.y == 0) && (ly + Env.ChunkSize == cy)) ||
                                // Section to the top
                                ((pos.y == Env.ChunkMask) && (ly - Env.ChunkSize == cy))
                            ))
                        {
                            rebuildMaskGeometry = rebuildMaskGeometry | (1 << i);
                        }

                        if ((ly == cy || lx == cx) &&
                            (
                                // Section to the back
                                ((pos.z == 0) && (lz + Env.ChunkSize == cz)) ||
                                // Section to the front
                                ((pos.z == Env.ChunkMask) && (lz - Env.ChunkSize == cz))
                            ))
                        {
                            rebuildMaskGeometry = rebuildMaskGeometry | (1 << i);
                        }
                    }

                    rebuildMaskCollider |= rebuildMaskGeometry;
                }

                m_setBlockQueue.Clear();
            }

            long now = Globals.Watch.ElapsedMilliseconds;

            // Request a geometry update at most 10 times a second
            if (rebuildMaskGeometry >= 0 && now - lastUpdateTimeGeometry >= 100)
            {
                lastUpdateTimeGeometry = now;

                // Request rebuild on this chunk
                stateManager.RequestState(ChunkState.BuildVerticesNow);;

                // Notify neighbors that they need to rebuilt their geometry
                if (rebuildMaskGeometry > 0)
                {
                    for (int j = 0; j < stateManager.Listeners.Length; j++)
                    {
                        ChunkStateManagerClient listener = (ChunkStateManagerClient)stateManager.Listeners[j];
                        if (listener != null && ((rebuildMaskGeometry >> j) & 1) != 0)
                        {
                            // Request rebuild on neighbor chunks
                            listener.RequestState(ChunkState.BuildVerticesNow);
                        }
                    }
                }

                rebuildMaskGeometry = -1;
            }

            // Request a collider update at most 4 times a second
            if (chunk.NeedsCollider && rebuildMaskCollider >= 0 && now - lastUpdateTimeCollider >= 250)
            {
                lastUpdateTimeCollider = now;

                // Request rebuild on this chunk
                stateManager.RequestState(ChunkState.BuildCollider);

                // Notify neighbors that they need to rebuilt their geometry
                if (rebuildMaskCollider > 0)
                {
                    for (int j = 0; j < stateManager.Listeners.Length; j++)
                    {
                        ChunkStateManagerClient listener = (ChunkStateManagerClient)stateManager.Listeners[j];
                        if (listener != null && ((rebuildMaskCollider >> j) & 1) != 0)
                        {
                            // Request rebuild on neighbor chunks
                            if (listener.chunk.NeedsCollider)
                            {
                                listener.RequestState(ChunkState.BuildCollider);
                            }
                        }
                    }
                }

                rebuildMaskCollider = -1;
            }
        }
コード例 #8
0
        public void Update()
        {
            ChunkStateManagerClient stateManager = (ChunkStateManagerClient)chunk.stateManager;

            if (m_setBlockQueue.Count > 0)
            {
                if (rebuildMaskGeometry < 0)
                {
                    rebuildMaskGeometry = 0;
                }
                if (rebuildMaskCollider < 0)
                {
                    rebuildMaskCollider = 0;
                }

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

                    if (!context.IsRange())
                    {
                        ProcessSetBlockQueue(context.Block, context.IndexFrom, context.SetBlockModified);
                    }
                    else
                    {
                        int sx, sy, sz, ex, ey, ez;
                        Helpers.GetChunkIndex3DFrom1D(context.IndexFrom, out sx, out sy, out sz);
                        Helpers.GetChunkIndex3DFrom1D(context.IndexTo, out ex, out ey, out ez);

                        for (int y = sy; y <= ey; y++)
                        {
                            for (int z = sz; z <= ez; z++)
                            {
                                for (int x = sx; x <= ex; x++)
                                {
                                    int index = Helpers.GetChunkIndex1DFrom3D(x, y, z);
                                    ProcessSetBlockQueue(context.Block, index, context.SetBlockModified);
                                }
                            }
                        }
                    }
                }

                rebuildMaskCollider |= rebuildMaskGeometry;

                m_setBlockQueue.Clear();
            }

            long now = Globals.Watch.ElapsedMilliseconds;

            // Request a geometry update at most 10 times a second
            if (rebuildMaskGeometry >= 0 && now - lastUpdateTimeGeometry >= 100)
            {
                lastUpdateTimeGeometry = now;

                // Request rebuild on this chunk
                stateManager.RequestState(ChunkState.BuildVerticesNow);;

                // Notify neighbors that they need to rebuilt their geometry
                if (rebuildMaskGeometry > 0)
                {
                    for (int j = 0; j < stateManager.Listeners.Length; j++)
                    {
                        ChunkStateManagerClient listener = (ChunkStateManagerClient)stateManager.Listeners[j];
                        if (listener != null && ((rebuildMaskGeometry >> j) & 1) != 0)
                        {
                            // Request rebuild on neighbor chunks
                            listener.RequestState(ChunkState.BuildVerticesNow);
                        }
                    }
                }

                rebuildMaskGeometry = -1;
            }

            // Request a collider update at most 4 times a second
            if (chunk.NeedsCollider && rebuildMaskCollider >= 0 && now - lastUpdateTimeCollider >= 250)
            {
                lastUpdateTimeCollider = now;

                // Request rebuild on this chunk
                stateManager.RequestState(ChunkState.BuildCollider);

                // Notify neighbors that they need to rebuilt their geometry
                if (rebuildMaskCollider > 0)
                {
                    for (int j = 0; j < stateManager.Listeners.Length; j++)
                    {
                        ChunkStateManagerClient listener = (ChunkStateManagerClient)stateManager.Listeners[j];
                        if (listener != null && ((rebuildMaskCollider >> j) & 1) != 0)
                        {
                            // Request rebuild on neighbor chunks
                            if (listener.chunk.NeedsCollider)
                            {
                                listener.RequestState(ChunkState.BuildCollider);
                            }
                        }
                    }
                }

                rebuildMaskCollider = -1;
            }
        }