public override TilePyramid VisibleTiles(GridRectangle VisibleBounds, double DownSample)
        {
            int roundedDownsample = NearestAvailableLevel(DownSample);

            GridQuad VisibleQuad = null;

            //Add any corners of the VisibleBounds that we can transform to the list of points
            List<MappingGridVector2> VisiblePoints = VisibleBoundsCorners(VolumeTransform, VisibleBounds);
            if (VisiblePoints.Count != 4)
            {
                //If we can't map all four corners then add all the points from the transform falling inside the visible rectangle or
                //connected to those points by an edge
                List<MappingGridVector2> listTransformPoints = this.VolumeTransform.IntersectingControlRectangle(VisibleBounds, true);
                VisiblePoints.AddRange(listTransformPoints);
            }
            else
            {
                VisiblePoints.Sort(new MappingGridVector2SortByMapPoints());
                VisibleQuad = new GridQuad(VisiblePoints[0].MappedPoint,
                                           VisiblePoints[1].MappedPoint,
                                           VisiblePoints[2].MappedPoint,
                                           VisiblePoints[3].MappedPoint);
            }

            //OK, transform all points falling inside the section border
            //Starting with low-res tiles, add tiles to the list until we reach desired resolution
            //List<Tile> TilesToDraw = new List<Tile>();
            TilePyramid TilesToDraw = new TilePyramid(VisibleBounds);

            if (VisiblePoints.Count < 3)
                return TilesToDraw;

            GridRectangle SectionBorder = MappingGridVector2.CalculateMappedBounds(VisiblePoints.ToArray());

            int iLevel = AvailableLevels.Length - 1;
            int level = AvailableLevels[iLevel];
            do
            {
                List<Tile> newTiles = RecursiveVisibleTiles(VisibleBounds,
                                                            SectionBorder,
                                                            VisibleQuad,
                                                            level
                                                            //PORT: AsynchTextureLoad
                                                            );

                //Insert at the beginning so we overwrite earlier tiles with poorer resolution
                TilesToDraw.AddTiles(level, newTiles.ToArray());

                iLevel--;
                if (iLevel >= 0)
                    level = AvailableLevels[iLevel];
            }
            while (level >= roundedDownsample && iLevel >= 0);

            //  Trace.WriteLine("Drawing " + TilesToDraw.Count.ToString() + " Tiles", "VolumeModel");

            return TilesToDraw;
        }
Beispiel #2
0
        protected virtual TilePyramid VisibleTiles(GridRectangle VisibleBounds,
                                                GridQuad SectionVisibleBounds,
                                                double DownSample)
        {
            TilePyramid VisibleTiles = new TilePyramid(VisibleBounds);

            //Setup a larger boundary outside of which we release textures
            GridRectangle releaseBounds = VisibleBounds; //Tiles outside this quad will have textures released
            GridRectangle loadBounds = VisibleBounds;  //Tiles inside this quad will have textures loaded
            GridRectangle abortBounds = VisibleBounds; //Tiles outside this quad will have HTTP requests aborted
            releaseBounds.Scale(1.25 * DownSample);
            loadBounds.Scale(1.1f);
            abortBounds.Scale(1.20f * DownSample);

            //Get ready by loading a smaller texture in case the user scrolls this direction
            //Once we have smaller textures then increase the quality
            //            int predictiveDownsample = DownSample * 4 > 64 ? 64 : (int)DownSample * 4;

            int roundedDownsample = NearestAvailableLevel(DownSample);

            ReferencePointBasedTransform[] Tranforms = this.TileTransforms;
            if (TileTransforms == null)
                return VisibleTiles;

            int ExpectedTileCount = Tranforms.Length;
            List<Tile> TilesToDraw = new List<Tile>(ExpectedTileCount);
            //            List<Tile> TilesToLoad = new List<Tile>(ExpectedTileCount);

            foreach (TriangulationTransform T in Tranforms)
            {
                //If this tile has been transformed out of existence then skip it
                if (T.MapPoints.Length < 3)
                    continue;

                if (VisibleBounds.Intersects(T.ControlBounds))
                {
                 //   bool LoadOnly = false;
                    TileTransformInfo info = T.Info as TileTransformInfo;
                    string name = TileFileName(info.TileFileName, roundedDownsample);
                    /*
                    if (SectionVisibleBounds != null)
                    {
                        GridRectangle MosaicPosition = new GridRectangle(T.mapPoints[0].ControlPoint, T.ImageWidth, T.ImageHeight);
                        if (SectionVisibleBounds.Contains(MosaicPosition) == false)
                        {
                            name = TileFileName(T.Number,predictiveDownsample);
                            LoadOnly = true;
                            continue;
                        }
                    }
                     */
                    string UniqueID = Tile.CreateUniqueKey(Section.Number, Name, CurrentPyramid.Name, roundedDownsample, info.TileFileName);
                    Tile tile = Global.TileCache.Fetch(UniqueID);
                    if(tile == null)
                    {
                        int MipMapLevels = 1; //No mip maps
                        if (roundedDownsample == this.AvailableLevels[AvailableLevels.Length - 1])
                            MipMapLevels = 0; //Generate mipmaps for lowest res texture

                        //First create a new tile
                        PositionNormalTextureVertex[] verticies = Tile.CalculateVerticies(T, info);

                        if(T.TriangleIndicies != null)
                        {

                            tile = Global.TileCache.ConstructTile(UniqueID,
                                                                 verticies,
                                                                 T.TriangleIndicies,
                                                                 this.TilePath + '/' + name,
                                                                 name,
                                //PORT: TileCacheName(T.Number, roundedDownsample),
                                                                 this.Name,
                                                                 roundedDownsample,
                                                                 MipMapLevels);//T.ImageHeight * T.ImageWidth / roundedDownsample);
                        }
                    }

                    if(tile != null)
                        VisibleTiles.AddTile(roundedDownsample, tile);

                    /*
                    if (LoadOnly)
                    {
                        TilesToLoad.Add(tile);
                        continue;
                    }
                     */

                    //I used to call draw here, but when exporting frames I want to have all tiles launch threads to load thier textures and then wait.
                    //It is much faster than doing one texture at a time
                    //PORT: Removed
                    //tile.GetTexture(graphicsDevice, true);
                    TilesToDraw.Add(tile);

                    //PORT: Modified to return all tiles of lower resolution

                    /*
                    //See if any tiles of alternate resolution are already loaded
                    //Use them if the correct resolution doesn't have a texture, otherwise abort any requests
                    bool TextureFound = tile.HasTexture;

                    foreach(int testLevel in UI.State.DownsampleLevels)
                    {
                        if(testLevel == roundedDownsample)
                            continue;

                        string altResName = TileFileName(T.Number, testLevel);
                        Tile altResTile = Global.TileCache.GetTile(altResName, this.Name);
                        if (altResTile != null)
                        {
                            //Stop the network request if we've already got a texture
                            //TODO: Once we have a list of textures to draw, send it to TextureConstructor
                            //and have it abort textures not in the list
                            if (TextureFound)
                                altResTile.AbortRequest();
                            else
                            {
                                if (altResTile.HasTexture)
                                {
                                    TilesToDraw.Add(altResTile);
                                    TextureFound = true;
                                }
                            }
                        }
                    }
                     */

                }

                /*PORT We no longer handle tiles to be loaded and the aborting tiles here
                else
                {
                    if (loadBounds.Intersects(T.CachedControlBounds))
                    {
                        string name = TileFileName(T.Number, predictiveDownsample);
                        Tile tile = Global.TileCache.GetTile(name, this.Name);
                        if(tile == null)
                        {
                            //First create a new tile
                            int MipMapLevels = 1; //No mip maps
                            if (roundedDownsample == this.AvailableLevels[AvailableLevels.Length - 1])
                                MipMapLevels = 0; //Generate mipmaps for lowest res texture

                            VertexPositionNormalTexture[] verticies = Tile.CalculateVerticies(T);
                            tile = Global.TileCache.ConstructTile(verticies,
                                                                 T.TriangleIndicies,
                                                                 name,
                                                                 TileCacheName(T.Number, predictiveDownsample),
                                                                 this.Name,
                                                                 roundedDownsample,
                                                                 MipMapLevels,
                                                                 T.ImageHeight * T.ImageWidth / predictiveDownsample);
                        }

                        TilesToLoad.Add(tile);
                    }
                    //Sometimes tiles can overlap both zones, so else if is used
                    else if (abortBounds.Intersects(T.CachedControlBounds) == false)
                    {
                        foreach (int testLevel in UI.State.DownsampleLevels)
                        {
                            string AbortTileName = TileFileName(T.Number, testLevel);
                            Tile tile = Global.TileCache.GetTile(AbortTileName, this.Name);
                            if (tile != null)
                            {
                                tile.AbortRequest();
                            }
                        }
                    }
                }
                 */
            }

            /*PORT Model does not load textures
            foreach (Tile tile in TilesToLoad)
            {
                //We are asking for a lower quality texture, but tile will keep any existing higher quality textures
                if (AsynchTextureLoad)
                    tile.GetTexture(graphicsDevice, true);
            }

            //TODO: Give a list of tiles to the TileConstructor that are OK to have outstanding load requests.
            //All other tiles will be aborted

            List<Tile> SafeTiles = new List<Tile>(TilesToLoad.Count + TilesToDraw.Count);
            SafeTiles.AddRange(TilesToLoad);
            SafeTiles.AddRange(TilesToDraw);

            Trace.WriteLine("Drawing " + TilesToDraw.Count.ToString() + " Tiles", "VolumeModel");

            return TilesToDraw.ToArray();
            */

            return VisibleTiles;
        }
Beispiel #3
0
        public override TilePyramid VisibleTiles(GridRectangle VisibleBounds, double DownSample)
        {
            TilePyramid VisibleTiles = new TilePyramid(VisibleBounds);
            int roundedDownsample = NearestAvailableLevel(DownSample);

            //Starting with low-res tiles, add tiles to the list until we reach desired resolution
            //            List<Tile> TilesToDraw = new List<Tile>();

            //Find the starting level of our rendering
            int iLevel = AvailableLevels.Length - 1;
            int level = AvailableLevels[iLevel];

            do
            {
                List<Tile> newTiles = RecursiveVisibleTiles(
                    VisibleBounds,
                    level
                    //PORT: AsynchTextureLoad
                    );

                //Insert at the beginning so we overwrite earlier tiles with poorer resolution
                VisibleTiles.AddTiles(level, newTiles);
                //TilesToDraw.AddRange(newTiles);

                iLevel--;
                if(iLevel >= 0)
                    level = AvailableLevels[iLevel];
            }
            while (level >= roundedDownsample && iLevel >= 0);

            //Trace.WriteLine("Drawing " + TilesToDraw.Count.ToString() + " Tiles", "VolumeModel");

            return VisibleTiles;
        }
Beispiel #4
0
        protected void UpdateTiles(Rect visRect, double downsample)
        {
            System.Diagnostics.Trace.WriteLine("UpdateTiles()");

            if (visRect.Width == 0 || visRect.Height == 0)
                return;

            //Find which tiles changed
            //Rect visRect = this.VisibleRect;
            Geometry.GridRectangle visibleGridRect = new Geometry.GridRectangle(visRect.Left, visRect.Right, visRect.Top, visRect.Bottom);
            TilePyramid oldTilePyramid = this.TilePyramid;

            Trace.WriteLine(TileMapping.ToString());

            TilePyramid newTilePyramid = TileMapping.VisibleTiles(visibleGridRect, downsample);

            if (oldTilePyramid != null)
            {
                if (false == oldTilePyramid.Bounds.Intersects(newTilePyramid.Bounds))
                    Tiles.Clear();
                else
                {
                    //Might be able to really speed up culling dead tiles with QuadTrees

                    //Sort out which of the old tiles are no longer visible
                    for (int iTile = 0; iTile < Tiles.Count; iTile++)
                    {
                        TileViewModel t = Tiles[iTile];
                        if (false == visibleGridRect.Intersects(t.Bounds))
                        {
                            Tiles.RemoveAt(iTile);
                            iTile--;
                        }
                        else
                        {
                            //SortedDictionary<string, Tile> tilesForLevel = newTilePyramid.GetTilesForLevel(t.Downsample);
                        }
                    }
                }
            }

            //Create tiles which are new
            for(int iLevel = newTilePyramid.AvailableLevels.Length -1; iLevel >= 0; iLevel--)
            //for (int iLevel = 0; iLevel >= 0; iLevel--)
            //for (int iLevel = 0; iLevel < newTilePyramid.AvailableLevels.Length; iLevel++)
            {
                int level = newTilePyramid.AvailableLevels[iLevel];
                SortedDictionary<string, Tile> tiles = newTilePyramid.GetTilesForLevel(level);
                bool IgnoreOldPyramid = oldTilePyramid == null;

                //Don't check the old pyramid if it doesn't have the downsample level we are looking at
                if (false == IgnoreOldPyramid)
                {
                    if (oldTilePyramid.AvailableLevels.Length == 0)
                    {
                        IgnoreOldPyramid = true;
                    }
                    else
                    {
                        IgnoreOldPyramid = level < oldTilePyramid.AvailableLevels.Min();

                        if (false == IgnoreOldPyramid)
                        {
                            IgnoreOldPyramid = level > oldTilePyramid.AvailableLevels.Max();
                        }
                    }
                }

                foreach (Tile t in tiles.Values)
                {
                    //We already loaded this one
              //          if (!IgnoreOldPyramid && oldTilePyramid.Bounds.Intersects(t.Bounds))
              //              continue;
              //          else
                    {
                        TileViewModel tileViewModel = null;

                        tileViewModel = TileCache.Fetch(t.UniqueKey);
                        if (tileViewModel == null)
                        {
                            tileViewModel = new TileViewModel(t, TileMapping.TilePath);

                            TileCache.Add(t.UniqueKey, tileViewModel);
                        }
            //                        else
             //                       {
                            //Don't add it to the collection again
                            if (Tiles.Contains(tileViewModel))
                                continue;

                        //}

                        this.Tiles.Add(tileViewModel);
                    }
                }
            }

            //This is horrible, but I do it to trigger the Dependancy property listeners because 3D collections don't subribe to the collection change notifications
            ObservableCollection<TileViewModel> newTiles = new ObservableCollection<TileViewModel>(this.Tiles);
            this.Tiles = newTiles;

            TilePyramid = newTilePyramid;
        }