public RasterTile GetTile(RasterTileIdentifier identifier)
        {
            RasterTile tile;
            if (m_activeTiles.TryGetValue(identifier, out tile))
            {
                return tile;
            }

            // New tiles are not initially active.  They become active when loaded.
            tile = new RasterTile(this, identifier);
            return tile;
        }
        private void RequestTileLoad(RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            LinkedListNode <TileLoadRequest> requestNode;
            bool exists = details.LoadingTiles.TryGetValue(tile.Identifier, out requestNode);

            if (!exists)
            {
                // Create a new request.
                TileLoadRequest request = new TileLoadRequest();
                request.Level = level;
                request.Tile  = tile;
                requestNode   = new LinkedListNode <TileLoadRequest>(request);
            }

            lock (details.RequestList)
            {
                if (exists)
                {
                    // Remove the existing request from the queue so we can re-insert it
                    // in its new location.
                    if (requestNode.List == null)
                    {
                        // Request was in the queue at one point, but it's not anymore.
                        // That means it's been loaded,  so we don't need to do anything.
                        return;
                    }
                    details.RequestList.Remove(requestNode);
                }

                if (details.RequestInsertionPoint == null || details.RequestInsertionPoint.List == null)
                {
                    details.RequestList.AddLast(requestNode);
                }
                else
                {
                    details.RequestList.AddBefore(details.RequestInsertionPoint, requestNode);
                }
                details.RequestInsertionPoint = requestNode;

                // If the request list has too many entries, delete from the beginning
                const int MaxRequests = 500;
                while (details.RequestList.Count > MaxRequests)
                {
                    LinkedListNode <TileLoadRequest> nodeToRemove = details.RequestList.First;
                    details.RequestList.RemoveFirst();
                    details.LoadingTiles.Remove(nodeToRemove.Value.Tile.Identifier);
                }

                Monitor.Pulse(details.RequestList);
            }

            details.LoadingTiles[tile.Identifier] = requestNode;
        }
        public RasterTile GetTile(RasterTileIdentifier identifier)
        {
            RasterTile tile;

            if (m_activeTiles.TryGetValue(identifier, out tile))
            {
                return(tile);
            }

            // New tiles are not initially active.  They become active when loaded.
            tile = new RasterTile(this, identifier);
            return(tile);
        }
        private void RequestThreadEntryPoint(object state)
        {
            RasterDataDetails details = (RasterDataDetails)state;

            details.WorkerWindow.Context.MakeCurrent();

            while (true)
            {
                TileLoadRequest request = null;
                lock (details.RequestList)
                {
                    LinkedListNode <TileLoadRequest> lastNode = details.RequestList.Last;
                    if (lastNode != null)
                    {
                        request = lastNode.Value;
                        details.RequestList.RemoveLast();
                    }
                    else
                    {
                        Monitor.Wait(details.RequestList);

                        lastNode = details.RequestList.Last;
                        if (lastNode != null)
                        {
                            request = lastNode.Value;
                            details.RequestList.RemoveLast();
                        }
                    }
                }

                if (request != null)
                {
                    RasterTile tile = request.Tile;
                    request.Texture = tile.LoadTexture();

                    Fence fence = Device.CreateFence();
                    fence.ClientWait();

                    details.DoneQueue.Post(request);
                }
            }
        }
        private void ApplyIfNotLoaded(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            Texture2D texture;

            if (!details.LoadedTiles.TryGetValue(tile.Identifier, out texture) || texture == null)
            {
                ApplyNewTile(context, details, level, tile);
            }
        }
        private void ApplyNewTile(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            ClipmapLevel.Extent nextExtent  = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;
            RasterLevel         rasterLevel = details.Type == RasterType.Terrain ? level.Terrain : level.Imagery;

            ClipmapUpdate entireLevel = new ClipmapUpdate(
                level,
                nextExtent.West,
                nextExtent.South,
                nextExtent.East,
                nextExtent.North);

            ClipmapUpdate thisTile = new ClipmapUpdate(
                level,
                tile.West - 1,
                tile.South - 1,
                tile.East + 1,
                tile.North + 1);

            ClipmapUpdate intersection = IntersectUpdates(entireLevel, thisTile);

            if (intersection.Width > 0 && intersection.Height > 0)
            {
                Update(context, intersection, level, details, rasterLevel);

                // Recurse on child tiles if they're NOT loaded.  Unloaded children will use data from this tile.
                ClipmapLevel finer = level.FinerLevel;
                if (finer != null)
                {
                    ApplyIfNotLoaded(context, details, finer, tile.SouthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.SoutheastChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NorthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NortheastChild);
                }
            }
        }
Exemple #7
0
        public RasterTileRegion[] GetTilesInExtent(int west, int south, int east, int north)
        {
            int tileXStart = west / LongitudePostsPerTile;
            int tileXStop  = east / LongitudePostsPerTile;

            if (west < 0)
            {
                --tileXStart;
            }
            if (east < 0)
            {
                --tileXStop;
            }

            int tileYStart = south / LatitudePostsPerTile;
            int tileYStop  = north / LatitudePostsPerTile;

            if (south < 0)
            {
                --tileYStart;
            }
            if (north < 0)
            {
                --tileYStop;
            }

            int tileWidth  = tileXStop - tileXStart + 1;
            int tileHeight = tileYStop - tileYStart + 1;

            RasterTileRegion[] result = new RasterTileRegion[tileWidth * tileHeight];
            int resultIndex           = 0;

            for (int tileY = tileYStart; tileY <= tileYStop; ++tileY)
            {
                int tileYOrigin = tileY * LatitudePostsPerTile;

                int currentSouth = south - tileYOrigin;
                if (currentSouth < 0)
                {
                    currentSouth = 0;
                }

                int currentNorth = north - tileYOrigin;
                if (currentNorth >= LatitudePostsPerTile)
                {
                    currentNorth = LatitudePostsPerTile - 1;
                }

                for (int tileX = tileXStart; tileX <= tileXStop; ++tileX)
                {
                    int tileXOrigin = tileX * LongitudePostsPerTile;

                    int currentWest = west - tileXOrigin;
                    if (currentWest < 0)
                    {
                        currentWest = 0;
                    }

                    int currentEast = east - tileXOrigin;
                    if (currentEast >= LongitudePostsPerTile)
                    {
                        currentEast = LongitudePostsPerTile - 1;
                    }

                    RasterTileIdentifier tileID = new RasterTileIdentifier(_level, tileX, tileY);
                    RasterTile           tile   = Source.GetTile(tileID);
                    result[resultIndex] = new RasterTileRegion(tile, currentWest, currentSouth, currentEast, currentNorth);
                    ++resultIndex;
                }
            }

            return(result);
        }
 public void DeactivateTile(RasterTile tile)
 {
     m_activeTiles.Remove(tile.Identifier);
 }
 public void ActivateTile(RasterTile tile)
 {
     m_activeTiles[tile.Identifier] = tile;
 }
        private void RequestTileLoad(RasterDataDetails details,  ClipmapLevel level, RasterTile tile)
        {
            LinkedListNode<TileLoadRequest> requestNode;
            bool exists = details.LoadingTiles.TryGetValue(tile.Identifier, out requestNode);

            if (!exists)
            {
                // Create a new request.
                TileLoadRequest request = new TileLoadRequest();
                request.Level = level;
                request.Tile = tile;
                requestNode = new LinkedListNode<TileLoadRequest>(request);
            }

            lock (details.RequestList)
            {
                if (exists)
                {
                    // Remove the existing request from the queue so we can re-insert it
                    // in its new location.
                    if (requestNode.List == null)
                    {
                        // Request was in the queue at one point, but it's not anymore.
                        // That means it's been loaded,  so we don't need to do anything.
                        return;
                    }
                    details.RequestList.Remove(requestNode);
                }

                if (details.RequestInsertionPoint == null || details.RequestInsertionPoint.List == null)
                {
                    details.RequestList.AddLast(requestNode);
                }
                else
                {
                    details.RequestList.AddBefore(details.RequestInsertionPoint, requestNode);
                }
                details.RequestInsertionPoint = requestNode;

                // If the request list has too many entries, delete from the beginning
                const int MaxRequests = 500;
                while (details.RequestList.Count > MaxRequests)
                {
                    LinkedListNode<TileLoadRequest> nodeToRemove = details.RequestList.First;
                    details.RequestList.RemoveFirst();
                    details.LoadingTiles.Remove(nodeToRemove.Value.Tile.Identifier);
                }

                Monitor.Pulse(details.RequestList);
            }

            details.LoadingTiles[tile.Identifier] = requestNode;
        }
 private void ApplyIfNotLoaded(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
 {
     Texture2D texture;
     if (!details.LoadedTiles.TryGetValue(tile.Identifier, out texture) || texture == null)
     {
         ApplyNewTile(context, details, level, tile);
     }
 }
        private void ApplyNewTile(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            ClipmapLevel.Extent nextExtent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;
            RasterLevel rasterLevel = details.Type == RasterType.Terrain ? level.Terrain : level.Imagery;

            ClipmapUpdate entireLevel = new ClipmapUpdate(
                level,
                nextExtent.West,
                nextExtent.South,
                nextExtent.East,
                nextExtent.North);

            ClipmapUpdate thisTile = new ClipmapUpdate(
                level,
                tile.West - 1,
                tile.South - 1,
                tile.East + 1,
                tile.North + 1);

            ClipmapUpdate intersection = IntersectUpdates(entireLevel, thisTile);

            if (intersection.Width > 0 && intersection.Height > 0)
            {
                Update(context, intersection, level, details, rasterLevel);

                // Recurse on child tiles if they're NOT loaded.  Unloaded children will use data from this tile.
                ClipmapLevel finer = level.FinerLevel;
                if (finer != null)
                {
                    ApplyIfNotLoaded(context, details, finer, tile.SouthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.SoutheastChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NorthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NortheastChild);
                }
            }
        }
 public void DeactivateTile(RasterTile tile)
 {
     m_activeTiles.Remove(tile.Identifier);
 }
 public void ActivateTile(RasterTile tile)
 {
     m_activeTiles[tile.Identifier] = tile;
 }