public void TestGridRectangle() { GridRectangle rectA = new GridRectangle(10, 50, 20, 40); bool success = rectA.Contains(new GridVector2(10, 20)); Debug.Assert(success); success = rectA.Contains(new GridVector2(50, 40)); Debug.Assert(success); success = rectA.Contains(rectA.Center); Debug.Assert(success); GridRectangle rectBOverlaps = new GridRectangle(5, 15, 10, 21); success = rectA.Intersects(rectBOverlaps); Debug.Assert(success); success = rectA.Contains(rectBOverlaps); Debug.Assert(false == success); GridRectangle rectCNoOverlap = new GridRectangle(5, 15, 10, 19); success = rectA.Intersects(rectCNoOverlap); Debug.Assert(false == success); success = rectA.Contains(rectBOverlaps); Debug.Assert(false == success); GridRectangle rectDContained = new GridRectangle(15, 45, 25, 35); success = rectA.Intersects(rectDContained); Debug.Assert(success); success = rectA.Contains(rectDContained); Debug.Assert(success); /*Scale the rectangle and test again*/ rectA.Scale(2); Debug.Assert(-10.0 == rectA.Left && 70 == rectA.Right && 10 == rectA.Bottom && 50 == rectA.Top); /*Scale the rectangle and test again*/ rectA.Scale(0.5); Debug.Assert(10.0 == rectA.Left && 50 == rectA.Right && 20 == rectA.Bottom && 40 == rectA.Top); }
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; }