Beispiel #1
0
        /// <summary>
        /// Updates tiles that are surrounding the tracked GameObject
        /// asynchronously
        /// </summary>
        public IEnumerator UpdateTiles()
        {
            List <Vector2> nearbyPositions = GetTilePositionsFromRadius();
            List <Vector2> newPositions    = Cache.GetNewTilePositions(nearbyPositions);

            //Remove old positions
            for (int i = 0; i < Cache.ActiveTiles.Count; i++)
            {
                bool found = false;

                foreach (Vector2 nearby in nearbyPositions)
                {
                    if (Cache.ActiveTiles[i].Position == nearby)                       //Position found, ignore
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    Cache.CacheTile(Cache.ActiveTiles[i]);
                    Cache.ActiveTiles.RemoveAt(i);
                    i--;
                }
            }

            //Add new positions
            foreach (Vector2 pos in newPositions)
            {
                TerrainTile cached = Cache.GetCachedTileAtPosition(pos);

                //Attempt to pull from cache, generate if not available
                if (cached != null)
                {
                    Cache.AddActiveTile(cached);
                }
                else
                {
                    yield return(AddTileAsync(pos));
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Updates tiles that are surrounding the tracked GameObject
        /// asynchronously. When calling this method using
        /// <see cref="MonoBehaviour.StartCoroutine(IEnumerator)"/>,
        /// tiles are generated once per frame
        /// </summary>
        public IEnumerator UpdateTiles()
        {
            List <GridPosition> nearbyPositions = GetTilePositionsFromRadius();
            List <GridPosition> newPositions    = Cache.GetNewTilePositions(nearbyPositions);
            List <Tile>         toRegenerate    = new List <Tile>();

            RemoveOldPositions(ref nearbyPositions, ref toRegenerate);

            //Add new positions
            _queuedTiles = newPositions.Count + toRegenerate.Count;

            foreach (GridPosition pos in newPositions)
            {
                if (_isGenerating && Application.isPlaying) //Wait and generate one tile per frame
                {
                    yield return(null);
                }

                Tile cached = Cache.GetCachedTileAtPosition(pos);

                //Attempt to pull from cache, generate if not available
                if (cached != null)
                {
                    if (cached.IsHeightmapLodValid())   //Cached tile is valid, use it
                    {
                        AddTile(cached);
                        _queuedTiles--;

                        continue;
                    }

                    TerraConfig.Log("Cached tile " + cached + " has heightmap res=" + cached.MeshManager.HeightmapResolution +
                                    ". requested res=" + cached.GetLodLevel().Resolution + ". Regenerating.");

                    toRegenerate.Add(cached);
                    Cache.AddActiveTile(cached);
                    continue;
                }

                _isGenerating = true;
                CreateTileAt(pos, tile => {
                    _queuedTiles--;

                    if (_queuedTiles == 0)
                    {
                        UpdateNeighbors(newPositions.ToArray(), false);
                    }

                    _isGenerating = false;
                });
            }

            //Regenerate tiles with outdated heightmaps
            for (int i = 0; i < toRegenerate.Count; i++)
            {
                Tile t = toRegenerate[i];
                TerraConfig.Log("Active tile " + t + " has heightmap res=" + t.MeshManager.HeightmapResolution +
                                ". requested res=" + t.GetLodLevel().Resolution + ". Regenerating.");

                //Generate one tile per frame
                if (Application.isPlaying)
                {
                    yield return(null);
                }

                if (Application.isPlaying)
                {
                    Config.StartCoroutine(t.UpdateHeightmapAsync(() => {
                        UpdateNeighbors(new[] { t.GridPosition }, false);
                        _queuedTiles--;
                    }, RemapMin, RemapMax));
                }
                else
                {
                    t.UpdateHeightmap(RemapMin, RemapMax);
                }
            }

            //If tiles were updated synchronously, notify queue completion
            if (newPositions.Count > 0 && _queuedTiles == 0)
            {
                UpdateNeighbors(newPositions.ToArray(), false);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Updates tiles that are surrounding the tracked GameObject
        /// asynchronously. When calling this method using
        /// <see cref="MonoBehaviour.StartCoroutine(System.Collections.IEnumerator)"/>,
        /// tiles are generated once per frame
        /// </summary>
        public IEnumerator UpdateTiles()
        {
            List <GridPosition> nearbyPositions  = GetTilePositionsFromRadius();
            List <GridPosition> newPositions     = Cache.GetNewTilePositions(nearbyPositions);
            List <Tile>         needRegenerating = new List <Tile>();

            //Remove old positions
            for (int i = 0; i < Cache.ActiveTiles.Count; i++)
            {
                bool found = false;

                foreach (GridPosition nearby in nearbyPositions)
                {
                    Tile t = Cache.ActiveTiles[i];

                    if (t.GridPosition == nearby)                       //Position found in ActiveTiles
                    {
                        if (t.IsHeightmapLodValid())                    //Correct heightmap, ignore
                        {
                            found = true;
                            break;
                        }

                        //Invalid heightmap, mark for regeneration
                        found = true;
                        needRegenerating.Add(t);
                    }
                }

                if (!found)
                {
                    Cache.CacheTile(Cache.ActiveTiles[i]);
                    Cache.ActiveTiles.RemoveAt(i);
                    i--;
                }
            }

            //Add new positions
            _queuedTiles = newPositions.Count + needRegenerating.Count;
            foreach (GridPosition pos in newPositions)
            {
                Tile cached = Cache.GetCachedTileAtPosition(pos);

                //Attempt to pull from cache, generate if not available
                if (cached != null)
                {
                    if (cached.IsHeightmapLodValid())                       //Cached tile is valid, use it
                    {
                        AddTile(cached);
                        _queuedTiles--;

                        continue;
                    }

                    //Cached tile has too low lod, mark for regeneration
                    Debug.Log("Cached tile " + cached + " has heightmap res=" + cached.MeshManager.MeshResolution +
                              ". requested res=" + cached.LodLevel.MeshResolution + ". Regenerating.");
                    //Cache.RemoveCachedTile(cached);
                    needRegenerating.Add(cached);
                    Cache.AddActiveTile(cached);
                    continue;
                }

                //Generate one tile per frame
                if (Application.isPlaying)
                {
                    yield return(null);
                }

                _isGeneratingTile = true;
                AddTileAt(pos, tile => {
                    _queuedTiles--;
                    _isGeneratingTile = false;

                    if (_queuedTiles == 0)
                    {
                        _queueCompletedAction(newPositions.ToArray());
                    }
                });
            }

            //Regenerate tiles with outdated positions
            for (int i = 0; i < needRegenerating.Count; i++)
            {
                Tile t = needRegenerating[i];
                Debug.Log("Active tile " + t + " has heightmap res=" + t.MeshManager.MeshResolution +
                          ". requested res=" + t.LodLevel.MeshResolution + ". Regenerating.");

                //Generate one tile per frame
                if (Application.isPlaying)
                {
                    yield return(null);
                }

                _isGeneratingTile = true;
                AddTileAt(t.GridPosition, tile => {
                    _queuedTiles--;
                    _isGeneratingTile = false;

                    //Remove low res tile
                    Cache.RemoveActiveTile(t);
                    Cache.RemoveCachedTile(t);

                    if (_queuedTiles == 0)
                    {
                        _queueCompletedAction(newPositions.ToArray());
                    }
                });
            }

            //If tiles were updated synchronously, notify queue completion
            if (newPositions.Count > 0 && _queuedTiles == 0)
            {
                _queueCompletedAction(newPositions.ToArray());
            }
        }