コード例 #1
0
        private void DrawFlat(GraphicsDevice graphicsDevice, SectorBounds bounds, ISector rootSector)
        {
            RenderTarget2D renderTarget = renderTargets[rootSector];

            // Set the render target
            graphicsDevice.SetRenderTarget(renderTarget);
            graphicsDevice.DepthStencilState = new DepthStencilState()
            {
                DepthBufferEnable = true
            };
            graphicsDevice.Clear(Pallete.OCEAN_BLUE);

            double         relativeCameraZoom = camera.cameraZoom - Math.Log(ZCoords.GetSectorManager().GetTopmostOSMSectors().Count, 4) + (Game1.RECORDING ? 1 : 0);
            int            zoomLevel          = Math.Min(Math.Max((int)(relativeCameraZoom - 3), 0), ZCoords.GetSectorManager().GetHighestOSMZoom());
            List <ISector> containedSectors   = rootSector.GetSectorsInRange(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY, zoomLevel);
            List <ISector> sorted             = containedSectors.Where(x => x.GetRoot().Equals(rootSector)).ToList();

            sorted.Sort((x, y) => x.Zoom.CompareTo(y.Zoom));
            foreach (var sector in sorted)
            {
                IGraphicsBuffer buffer = loadedMaps[sector];
                if (!(buffer is ImageTileBuffer))
                {
                    continue;
                }
                Matrixd       projection = Matrixd.CreateOrthographicOffCenter(bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.maxY * (1 << sector.Zoom) - sector.Y, bounds.minY * (1 << sector.Zoom) - sector.Y, -1, 0.01f); // TODO: why negative?
                RenderContext context    = new RenderContext(graphicsDevice, projection, bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.minY * (1 << sector.Zoom) - sector.Y, bounds.maxY * (1 << sector.Zoom) - sector.Y, camera.cameraZoom, RenderContext.LayerPass.MAIN_PASS);
                buffer.Draw(context);
            }
        }
コード例 #2
0
        public PlanetComponent(Game game, EditorCamera camera)
        {
            this.camera = camera;
            foreach (var rootSector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
#if WINDOWS
                RenderTarget2D renderTarget = new RenderTarget2D(
                    game.GraphicsDevice,
                    2560,
                    1440,
                    true,
                    GraphicsDevice.PresentationParameters.BackBufferFormat,
                    DepthFormat.Depth24);
#else
                RenderTarget2D renderTarget = new RenderTarget2D(
                    game.GraphicsDevice,
                    2560,
                    1440,
                    false,
                    game.GraphicsDevice.PresentationParameters.BackBufferFormat,
                    DepthFormat.Depth24);
#endif
                renderTargets[rootSector] = renderTarget;
            }
        }
コード例 #3
0
        public HouseBuffer(GraphicsDevice graphicsDevice, List <Matrix> matrices, ISector sector)
        {
            this.sector   = sector;
            this.matrices = matrices;

            double radius = 6356000; // of earth, in meters
            double scale  = 2 / Math.Sqrt(4 * Math.PI * radius * radius / ZCoords.GetSectorManager().GetTopmostOSMSectors().Count / (1 << (2 * ZCoords.GetSectorManager().GetHighestOSMZoom())));

            VertexDeclaration instanceVertexDeclaration = GenerateInstanceVertexDeclaration();

            instanceBuffer = new VertexBuffer(graphicsDevice, instanceVertexDeclaration, matrices.Count, BufferUsage.WriteOnly);
            instanceBuffer.SetData(matrices.Select(x => Matrix.CreateScale((float)scale) * x).ToArray());
            bindings = new List <VertexBufferBinding[]>();

            foreach (ModelMesh mesh in GlobalContent.House.Meshes)
            {
                foreach (var meshPart in mesh.MeshParts)
                {
                    var meshPartBindings = new VertexBufferBinding[2];
                    meshPartBindings[0] = new VertexBufferBinding(meshPart.VertexBuffer, 0);
                    meshPartBindings[1] = new VertexBufferBinding(instanceBuffer, 0, 1);
                    bindings.Add(meshPartBindings);
                }
            }
        }
コード例 #4
0
        // make a lo-rez map showing where there's coast so we can flood-fill it later with land/water
        public static void SaveCoastLineMap(GraphicsDevice graphicsDevice)
        {
            var manager   = ZCoords.GetSectorManager();
            int imageSize = 1 << manager.GetHighestOSMZoom();

            foreach (var sector in manager.GetTopmostOSMSectors())
            {
                RenderTarget2D newTarget = new RenderTarget2D(graphicsDevice, imageSize, imageSize, false, graphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24);
                graphicsDevice.SetRenderTarget(newTarget);
                List <ISector> sectorsToCheck = new List <ISector>();
                sectorsToCheck.AddRange(sector.GetChildrenAtLevel(ZCoords.GetSectorManager().GetHighestOSMZoom()));
                foreach (var s in sectorsToCheck)
                {
                    if (File.Exists(OSMPaths.GetSectorPath(s)))
                    {
                        GraphicsBasic.DrawScreenRect(graphicsDevice, s.X, s.Y, 1, 1, ContainsCoast(s) ? Microsoft.Xna.Framework.Color.Gray : Microsoft.Xna.Framework.Color.White);
                    }
                    else
                    {
                        GraphicsBasic.DrawScreenRect(graphicsDevice, s.X, s.Y, 1, 1, Microsoft.Xna.Framework.Color.Red);
                    }
                }
                string mapFile = OSMPaths.GetCoastlineImagePath(sector);
                using (var writer = File.OpenWrite(mapFile))
                {
                    newTarget.SaveAsPng(writer, imageSize, imageSize);
                }
            }
        }
コード例 #5
0
        // move some of our files to the Android assets folder
        private static void HelpZenithAndroid()
        {
            LongLat           longLat       = new LongLat(-87.3294527 * Math.PI / 180, 30.4668536 * Math.PI / 180); // Pensacola
            CubeSector        ourRoot       = new CubeSector(CubeSector.CubeSectorFace.LEFT, 0, 0, 0);
            Vector2d          relativeCoord = ourRoot.ProjectToLocalCoordinates(longLat.ToSphereVector());
            HashSet <ISector> sectorsToLoad = new HashSet <ISector>();

            foreach (var r in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                sectorsToLoad.Add(r);
                for (int z = 1; z <= 3; z++)
                {
                    foreach (var child in r.GetChildrenAtLevel(z))
                    {
                        sectorsToLoad.Add(child);
                    }
                }
            }
            for (int z = 4; z <= 8; z++)
            {
                ISector sector = ourRoot.GetSectorAt(relativeCoord.X, relativeCoord.Y, z);
                for (int i = 0; i < 25; i++)
                {
                    sectorsToLoad.Add(new CubeSector(((CubeSector)sector).sectorFace, sector.X + i / 5 - 2, sector.Y + i % 5 - 2, sector.Zoom));
                }
            }
            foreach (var sector in sectorsToLoad)
            {
                MoveSectorImage(sector);
                MoveSectorOSM(sector);
            }
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: geoffreylhart/Zenith
 static void Main(string[] args)
 {
     if (args.Length > 0)
     {
         Game1.RENDER_SECTOR = ZCoords.GetSectorManager().FromString(args[0]);
     }
     using (var game = new Zenith.Game1())
         game.Run();
 }
コード例 #7
0
ファイル: OSMMetaFinal.cs プロジェクト: geoffreylhart/Zenith
 private static void LoadAll()
 {
     GLOBAL_FINAL = new OSMMetaFinal();
     // init
     GLOBAL_FINAL.gridPoints = new Dictionary <ISector, GridPointInfo[, ]>();
     foreach (var root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
     {
         GridPointInfo[,] gp = new GridPointInfo[257, 257];
         for (int x = 0; x < 257; x++)
         {
             for (int y = 0; y < 257; y++)
             {
                 gp[x, y] = new GridPointInfo();
             }
         }
         GLOBAL_FINAL.gridPoints[root] = gp;
     }
     for (int r = 0; r < 6; r++)
     {
         var    frRoot   = new CubeSector((CubeSector.CubeSectorFace)r, 0, 0, 0);
         string filePath = Path.Combine(OSMPaths.GetRenderRoot(), $"Coastline{frRoot.sectorFace.GetFaceAcronym()}.txt");
         using (var writer = File.Open(filePath, FileMode.Open))
         {
             using (var br = new BinaryReader(writer))
             {
                 int badRelationsCount = br.ReadInt32();
                 for (int i = 0; i < badRelationsCount; i++)
                 {
                     GLOBAL_FINAL.badRelations.Add(br.ReadInt64());
                 }
                 for (int i = 0; i < 257; i++)
                 {
                     for (int j = 0; j < 257; j++)
                     {
                         GridPointInfo gridPoint         = GLOBAL_FINAL.gridPoints[frRoot][i, j];
                         int           naturalTypesCount = br.ReadInt32();
                         for (int k = 0; k < naturalTypesCount; k++)
                         {
                             gridPoint.naturalTypes.Add(br.ReadInt32());
                         }
                         int relationsCount = br.ReadInt32();
                         for (int k = 0; k < relationsCount; k++)
                         {
                             gridPoint.relations.Add(br.ReadInt64());
                         }
                         int waysCount = br.ReadInt32();
                         for (int k = 0; k < waysCount; k++)
                         {
                             gridPoint.ways.Add(br.ReadInt64());
                         }
                     }
                 }
             }
         }
     }
 }
コード例 #8
0
        public ISector FromString(string s)
        {
            String[] split = s.Split(',');
            CubeSector.CubeSectorFace sectorFace = ZCoords.FromFaceAcronym(split[0]);
            int x    = int.Parse(split[1].Split('=')[1]);
            int y    = int.Parse(split[2].Split('=')[1]);
            int zoom = int.Parse(split[3].Split('=', '.')[1]);

            return(new CubeSector(sectorFace, x, y, zoom));
        }
コード例 #9
0
        public override void Draw(RenderContext renderContext, GameTime gameTime)
        {
            if (renderContext.layerPass == RenderContext.LayerPass.MAIN_PASS && !Game1.DEFERRED_RENDERING)
            {
                var effect = this.GetDefaultEffect(renderContext.graphicsDevice);

                camera.ApplyMatrices(effect);
                float distance = (float)(9 * Math.Pow(0.5, camera.cameraZoom)); // TODO: this is hacky
                effect.View = CameraMatrixManager.GetWorldRelativeView(distance);

                effect.TextureEnabled = true;
                foreach (var rootSector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
                {
                    SectorBounds       bounds = GetSectorBounds(renderContext.graphicsDevice, rootSector);
                    VertexIndiceBuffer sphere = SphereBuilder.MakeSphereSegExplicit(renderContext.graphicsDevice, rootSector, 2, bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, camera);
                    effect.Texture = renderTargets[rootSector];
                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();
                        renderContext.graphicsDevice.Indices = sphere.indices;
                        renderContext.graphicsDevice.SetVertexBuffer(sphere.vertices);
                        renderContext.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, sphere.indices.IndexCount / 3);
                    }
                    sphere.vertices.Dispose();
                    sphere.indices.Dispose();
                }
            }
            if (renderContext.layerPass == RenderContext.LayerPass.MAIN_PASS && Game1.DEFERRED_RENDERING)
            {
                var    effect   = GlobalContent.DeferredBasicNormalTextureShader;
                float  distance = (float)(9 * Math.Pow(0.5, camera.cameraZoom)); // TODO: this is hacky
                Matrix view     = CameraMatrixManager.GetWorldRelativeView(distance);
                effect.Parameters["WVP"].SetValue(camera.world * view * camera.projection);
                foreach (var rootSector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
                {
                    SectorBounds       bounds = GetSectorBounds(renderContext.graphicsDevice, rootSector);
                    VertexIndiceBuffer sphere = SphereBuilder.MakeSphereSegExplicit(renderContext.graphicsDevice, rootSector, 2, bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, camera);
                    effect.Parameters["Texture"].SetValue(renderTargets[rootSector]);
                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();
                        renderContext.graphicsDevice.Indices = sphere.indices;
                        renderContext.graphicsDevice.SetVertexBuffer(sphere.vertices);
                        renderContext.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, sphere.indices.IndexCount / 3);
                    }
                    sphere.vertices.Dispose();
                    sphere.indices.Dispose();
                }
            }
            foreach (var rootSector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                Draw3D(renderContext.graphicsDevice, allBounds[rootSector], rootSector, renderContext.layerPass);
            }
        }
コード例 #10
0
 private ISector GetContainingSector(LongLat x, int level)
 {
     foreach (var root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
     {
         if (root.ContainsLongLat(x))
         {
             Vector2d localAgain = root.ProjectToLocalCoordinates(x.ToSphereVector());
             return(root.GetSectorAt(localAgain.X, localAgain.Y, level));
         }
     }
     throw new NotImplementedException();
 }
コード例 #11
0
 private void RebuildImage(GraphicsDevice graphicsDevice, ISector sector)
 {
     // combination images
     using (Texture2D rendered = new RenderTarget2D(graphicsDevice, 512, 512, false, graphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24))
     {
         int highestZoom = ZCoords.GetSectorManager().GetHighestCacheZoom();
         foreach (var parent in sector.GetAllParents().OrderBy(x => - x.Zoom).Where(x => x.Zoom <= highestZoom))
         {
             List <ISector> roadSectors = parent.GetChildrenAtLevel(parent.Zoom == highestZoom - 1 ? ZCoords.GetSectorManager().GetHighestOSMZoom() : parent.Zoom + 1);
             Texture2D[]    textures    = new Texture2D[roadSectors.Count];
             for (int i = 0; i < roadSectors.Count; i++)
             {
                 IGraphicsBuffer buffer = null;
                 if (File.Exists(OSMPaths.GetSectorImagePath(roadSectors[i])))
                 {
                     using (var reader = File.OpenRead(OSMPaths.GetSectorImagePath(roadSectors[i])))
                     {
                         buffer = new ImageTileBuffer(graphicsDevice, Texture2D.FromStream(graphicsDevice, reader), roadSectors[i]);
                     }
                 }
                 else
                 {
                     throw new NotImplementedException();
                 }
                 textures[i] = buffer.GetImage(graphicsDevice);
             }
             if (textures.Any(x => x != null))
             {
                 graphicsDevice.SetRenderTarget((RenderTarget2D)rendered);
                 for (int i = 0; i < roadSectors.Count; i++)
                 {
                     int size, x, y;
                     size = 512 >> (roadSectors[i].Zoom - parent.Zoom);
                     x    = parent.GetRelativeXOf(roadSectors[i]) * size;
                     y    = parent.GetRelativeYOf(roadSectors[i]) * size;
                     if (textures[i] != null)
                     {
                         GraphicsBasic.DrawSpriteRect(graphicsDevice, x, y, size, size, textures[i], BlendState.AlphaBlend, Microsoft.Xna.Framework.Color.White);
                     }
                 }
             }
             for (int i = 0; i < textures.Length; i++)
             {
                 if (textures[i] != null && textures[i] != GlobalContent.Error)
                 {
                     textures[i].Dispose();
                 }
             }
             SuperSave(rendered, OSMPaths.GetSectorImagePath(parent));
         }
     }
 }
コード例 #12
0
 Dictionary <ISector, SectorBounds> allBounds = new Dictionary <ISector, SectorBounds>(); // TODO: refactor this away from static-ness
 public override void InitDraw(RenderContext renderContext)
 {
     allBounds = new Dictionary <ISector, SectorBounds>();
     // precompute this because it depends heavily on the active GraphicsDevice RenderTarget
     foreach (var rootSector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
     {
         allBounds[rootSector] = GetSectorBounds(renderContext.graphicsDevice, rootSector);
     }
     foreach (var rootSector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
     {
         InitDraw(renderContext.graphicsDevice, allBounds[rootSector], rootSector);
     }
     foreach (var rootSector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
     {
         DrawFlat(renderContext.graphicsDevice, allBounds[rootSector], rootSector);
     }
 }
コード例 #13
0
        private ISector GetSector(double mouseX, double mouseY, double cameraZoom)
        {
            int     zoom    = GetRoundedZoom(cameraZoom);
            LongLat longLat = new LongLat(mouseX, mouseY);

            foreach (var sector in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                if (sector.ContainsLongLat(longLat))
                {
                    var localCoord = sector.ProjectToLocalCoordinates(longLat.ToSphereVector());
                    var sectorAt   = sector.GetSectorAt(localCoord.X, localCoord.Y, zoom);
                    if (sectorAt != null)
                    {
                        return(sectorAt);
                    }
                }
            }
            return(null);
        }
コード例 #14
0
        // took 21.117584 hours to save 4.19 GB
        // saved to 6 different files in case it crashes
        public void LoadAllDetailsFromSource()
        {
            int i = 0;

            foreach (CubeSector root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                for (int x = 0; x < 256; x++)
                {
                    for (int y = 0; y < 256; y++)
                    {
                        var sector = new CubeSector(root.sectorFace, x, y, 8);
                        LoadDetailsFromSource(sector);
                    }
                }
                SaveAll("planet-meta" + i + ".data");
                Clear();
                i++;
            }
        }
コード例 #15
0
        static int READ_BREAKUP_STEP    = 0; // easy way to allow continuation, should usually equal (#filesThatArenttoplevel)/3
        public static void SegmentOSMPlanet()
        {
            READ_BREAKUP_STEP = int.Parse(File.ReadAllText(OSMPaths.GetPlanetStepPath()).Split(',')[0]); // file should contain the number of physical breakups that were finished
            List <ISector> quadrants = ZCoords.GetSectorManager().GetTopmostOSMSectors();

            if (READ_BREAKUP_STEP <= CURRENT_BREAKUP_STEP)
            {
                foreach (var quadrant in quadrants)
                {
                    String quadrantPath = OSMPaths.GetSectorPath(quadrant);
                    if (File.Exists(quadrantPath))
                    {
                        File.Delete(quadrantPath);                            // we're assuming it's corrupted
                    }
                    if (!Directory.Exists(Path.GetDirectoryName(quadrantPath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(quadrantPath));
                    }
                    var fInfo = new FileInfo(OSMPaths.GetPlanetPath());
                    using (var fileInfoStream = fInfo.OpenRead())
                    {
                        using (var source = new PBFOsmStreamSource(fileInfoStream))
                        {
                            var filtered = source.FilterNodes(x => x.Longitude.HasValue && x.Latitude.HasValue && quadrant.ContainsLongLat(new LongLat(x.Longitude.Value * Math.PI / 180, x.Latitude.Value * Math.PI / 180)), true);
                            using (var stream = new FileInfo(quadrantPath).Open(FileMode.Create, FileAccess.ReadWrite))
                            {
                                var target = new PBFOsmStreamTarget(stream, true);
                                target.RegisterSource(filtered);
                                target.Pull();
                                target.Close();
                            }
                        }
                    }
                }
            }
            BreakupStepDone();
            foreach (var quadrant in quadrants)
            {
                String quadrantPath = OSMPaths.GetSectorPath(quadrant);
                BreakupFile(quadrantPath, quadrant, ZCoords.GetSectorManager().GetHighestOSMZoom());
            }
        }
コード例 #16
0
        private void Draw3D(GraphicsDevice graphicsDevice, SectorBounds bounds, ISector rootSector, RenderContext.LayerPass layerPass)
        {
            double         relativeCameraZoom = camera.cameraZoom - Math.Log(ZCoords.GetSectorManager().GetTopmostOSMSectors().Count, 4) + (Game1.RECORDING ? 1 : 0);
            int            zoomLevel          = Math.Min(Math.Max((int)(relativeCameraZoom - 3), 0), ZCoords.GetSectorManager().GetHighestOSMZoom());
            List <ISector> containedSectors   = rootSector.GetSectorsInRange(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY, zoomLevel);
            List <ISector> sorted             = containedSectors.Where(x => x.GetRoot().Equals(rootSector)).ToList();

            sorted.Sort((x, y) => x.Zoom.CompareTo(y.Zoom));
            foreach (var sector in sorted)
            {
                IGraphicsBuffer buffer = loadedMaps[sector];
                if (buffer is ImageTileBuffer)
                {
                    continue;
                }
                SectorBounds b           = new SectorBounds(bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.minY * (1 << sector.Zoom) - sector.Y, bounds.maxY * (1 << sector.Zoom) - sector.Y);
                SectorBounds limitedB    = new SectorBounds(Math.Max(0, Math.Min(1, b.minX)), Math.Max(0, Math.Min(1, b.maxX)), Math.Max(0, Math.Min(1, b.minY)), Math.Max(0, Math.Min(1, b.maxY)));
                BasicEffect  basicEffect = new BasicEffect(graphicsDevice);
                camera.ApplyMatrices(basicEffect);
                // going to make it easy and assume the shape is perfectly parallel (it's not)
                // the sector plane is constructed by flattening the visible portion of the sphere, basically
                Vector3d v1    = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.minX, limitedB.minY));
                Vector3d v2    = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.maxX, limitedB.minY));
                Vector3d v3    = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.minX, limitedB.maxY));
                Vector3d xAxis = (v2 - v1) / (limitedB.maxX - limitedB.minX);
                Vector3d yAxis = (v3 - v1) / (limitedB.maxY - limitedB.minY);
                Vector3d start = v1 - xAxis * limitedB.minX - yAxis * limitedB.minY;
                Vector3d zAxis = start * (xAxis.Length() + yAxis.Length()) / start.Length() / 2;                                          // make this roughly the same length
                // matrixes copied over
                Matrixd       world           = Matrixd.CreateRotationZ(-camera.cameraRotX) * Matrixd.CreateRotationX(camera.cameraRotY); // eh.... think hard on this later
                double        distance        = 9 * Math.Pow(0.5, camera.cameraZoom);
                Matrixd       view            = CameraMatrixManager.GetWorldViewd(distance);
                Matrixd       projection      = CameraMatrixManager.GetWorldProjectiond(distance, graphicsDevice.Viewport.AspectRatio);
                Matrixd       transformMatrix = new Matrixd(xAxis.X, xAxis.Y, xAxis.Z, 0, yAxis.X, yAxis.Y, yAxis.Z, 0, zAxis.X, zAxis.Y, zAxis.Z, 0, start.X, start.Y, start.Z, 1); // turns our local coordinates into 3d spherical coordinates, based on the sector
                Matrixd       WVP             = Normalize(transformMatrix * world * view * projection);                                                                              // combine them all to allow for higher precision
                RenderContext context         = new RenderContext(graphicsDevice, WVP, b.minX, b.maxX, b.minY, b.maxY, camera.cameraZoom, layerPass);
                buffer.Draw(context);
            }
        }
コード例 #17
0
        private IGraphicsBuffer GetBuffer(GraphicsDevice graphicsDevice, ISector sector, bool cached)
        {
            if (sector.Zoom > ZCoords.GetSectorManager().GetHighestOSMZoom())
            {
                throw new NotImplementedException();
            }
            if (ZCoords.GetSectorManager().GetHighestCacheZoom() > ZCoords.GetSectorManager().GetHighestOSMZoom())
            {
                throw new NotImplementedException();
            }

            try
            {
                if ((cached || sector.Zoom != ZCoords.GetSectorManager().GetHighestOSMZoom()))
                {
                    string path = OSMPaths.GetSectorImagePath(sector);
#if WINDOWS || LINUX
                    if (File.Exists(path))
                    {
                        using (var reader = File.OpenRead(path))
                        {
                            return(new ImageTileBuffer(graphicsDevice, Texture2D.FromStream(graphicsDevice, reader), sector));
                        }
                    }
#else
                    using (var reader = Activity1.ASSETS.Open(path))
                    {
                        return(new ImageTileBuffer(graphicsDevice, Texture2D.FromStream(graphicsDevice, reader), sector));
                    }
#endif
                }
            }
            catch (Exception ex)
            {
                // sometimes the image is corrupt (or zero bytes)
            }
            // otherwise, build it
            if (sector.Zoom == ZCoords.GetSectorManager().GetHighestOSMZoom())
            {
                if (cached)
                {
                    // TODO: somehow all of this still breaks often and is pretty slow, but at least we only have to run it once
                    if (sector.Zoom <= ZCoords.GetSectorManager().GetHighestCacheZoom())
                    {
                        SuperSave(GlobalContent.Error, OSMPaths.GetSectorImagePath(sector));
                        //RebuildImage(graphicsDevice, sector);
                    }
                    return(new ImageTileBuffer(graphicsDevice, GlobalContent.Error, sector));
                }
                else
                {
                    try
                    {
                        ProceduralTileBuffer buffer = new ProceduralTileBuffer(sector);
                        Stopwatch            sw     = new Stopwatch();
                        sw.Start();
                        buffer.LoadLinesFromFile();
                        buffer.GenerateVertices();
                        buffer.GenerateBuffers(graphicsDevice);
                        Console.WriteLine($"Total load time for {sector} is {sw.Elapsed.TotalSeconds} s");
                        if (sector.Zoom <= ZCoords.GetSectorManager().GetHighestCacheZoom())
                        {
#if WINDOWS || LINUX
                            using (var image = buffer.GetImage(graphicsDevice))
                            {
                                SuperSave(image, OSMPaths.GetSectorImagePath(sector));
                            }
                            RebuildImage(graphicsDevice, sector);
#endif
                        }
                        return(buffer);
                    }
                    catch (Exception ex)
                    {
                        if (sector.Zoom <= ZCoords.GetSectorManager().GetHighestCacheZoom())
                        {
                            SuperSave(GlobalContent.Error, OSMPaths.GetSectorImagePath(sector));
                            RebuildImage(graphicsDevice, sector);
                        }
                        return(new ImageTileBuffer(graphicsDevice, GlobalContent.Error, sector));
                    }
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #18
0
ファイル: OSMMetaFinal.cs プロジェクト: geoffreylhart/Zenith
        internal void LoadAll(string fileName)
        {
            OSMMetaManager manager = new OSMMetaManager();

            if (fileName.Contains("*"))
            {
                for (int i = 0; i < 6; i++)
                {
                    manager.LoadAll(fileName.Replace("*", i + ""));
                }
            }
            else
            {
                manager.LoadAll(fileName);
            }
            // init
            gridPoints = new Dictionary <ISector, GridPointInfo[, ]>();
            gridTops   = new Dictionary <ISector, GridPointInfo[, ]>();
            gridLefts  = new Dictionary <ISector, GridPointInfo[, ]>();
            foreach (var root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                GridPointInfo[,] gp = new GridPointInfo[257, 257];
                GridPointInfo[,] gt = new GridPointInfo[256, 257];
                GridPointInfo[,] gl = new GridPointInfo[257, 256];
                for (int x = 0; x < 257; x++)
                {
                    for (int y = 0; y < 257; y++)
                    {
                        gp[x, y] = new GridPointInfo();
                        if (x < 256)
                        {
                            gt[x, y] = new GridPointInfo();
                        }
                        if (y < 256)
                        {
                            gl[x, y] = new GridPointInfo();
                        }
                    }
                }
                gridPoints[root] = gp;
                gridTops[root]   = gt;
                gridLefts[root]  = gl;
            }
            // find bad relations
            foreach (var relation in manager.relationInfo)
            {
                if (!IsValidRelation(manager, relation.Key))
                {
                    badRelations.Add(relation.Key);
                }
            }
            // process all edge info
            foreach (var edge in manager.edgeInfo)
            {
                if (!manager.wayInfo.ContainsKey(edge.wayID))
                {
                    continue;                                           // probably doesn't exist because we've removed it to try and save some memory
                }
                foreach (var root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
                {
                    var local1 = root.ProjectToLocalCoordinates(edge.longLat1.ToSphereVector());
                    var local2 = root.ProjectToLocalCoordinates(edge.longLat2.ToSphereVector());
                    if ((local1 - local2).Length() > 0.2)
                    {
                        continue;
                    }
                    // first, order by X
                    if (local1.X > local2.X)
                    {
                        var temp = local2;
                        local2 = local1;
                        local1 = temp;
                    }
                    for (int x = (int)Math.Ceiling(local1.X * 256); x <= local2.X * 256; x++)
                    {
                        if (x == local1.X * 256)
                        {
                            continue;
                        }
                        double t = (x / 256.0 - local1.X) / (local2.X - local1.X);
                        int    y = (int)Math.Floor((local1.Y + t * (local2.Y - local1.Y)) * 256);
                        if (x >= 0 && x < 257 && y >= 0 && y < 256)
                        {
                            XORWithEdge(manager, gridLefts[root][x, y], edge);
                        }
                    }
                    // now, order by Y
                    if (local1.Y > local2.Y)
                    {
                        var temp = local2;
                        local2 = local1;
                        local1 = temp;
                    }
                    for (int y = (int)Math.Ceiling(local1.Y * 256); y <= local2.Y * 256; y++) // BUG: can't believe this was required, but we do sometimes have nodes on exactly the edge, apparently
                    {
                        // ignore the edge that bruhes up exactly against the top (assuming it exists at all, since our original load logic can exclude such an edge)
                        // with a point exactly on an edge, the -other- edge that matches exactly on bottom should trigger the flag instead (double-flag would be bad)
                        if (y == local1.Y * 256)
                        {
                            continue;
                        }
                        double t = (y / 256.0 - local1.Y) / (local2.Y - local1.Y);
                        int    x = (int)Math.Floor((local1.X + t * (local2.X - local1.X)) * 256); // BUG: (int) is NOT THE SAME AS Math.Floor!
                        if (x >= 0 && x < 256 && y >= 0 && y < 257)
                        {
                            XORWithEdge(manager, gridTops[root][x, y], edge);
                        }
                    }
                }
            }
            // now actually figure out the points
            // TODO: we're just doing front for now
            var frRoot = new CubeSector((CubeSector.CubeSectorFace) int.Parse(Regex.Match(fileName, "[0-9]").Value), 0, 0, 0);

            if (frRoot.sectorFace == CubeSector.CubeSectorFace.RIGHT || frRoot.sectorFace == CubeSector.CubeSectorFace.BACK)
            {
                // invert these faces
                gridPoints[frRoot][0, 0].naturalTypes.Add(0);
            }
            for (int y = 0; y < 257; y++)
            {
                for (int x = 0; x < 257; x++)
                {
                    GridPointInfo prev;
                    GridPointInfo next;
                    GridPointInfo edge;
                    if (x == 0)
                    {
                        if (y == 0)
                        {
                            continue;
                        }
                        prev = gridPoints[frRoot][0, y - 1];
                        next = gridPoints[frRoot][0, y];
                        edge = gridLefts[frRoot][0, y - 1];
                    }
                    else
                    {
                        prev = gridPoints[frRoot][x - 1, y];
                        next = gridPoints[frRoot][x, y];
                        edge = gridTops[frRoot][x - 1, y];
                    }
                    foreach (var n in prev.naturalTypes)
                    {
                        next.naturalTypes.Add(n);
                    }
                    foreach (var n in prev.relations)
                    {
                        next.relations.Add(n);
                    }
                    foreach (var n in prev.ways)
                    {
                        next.ways.Add(n);
                    }
                    foreach (var n in edge.naturalTypes)
                    {
                        if (next.naturalTypes.Contains(n))
                        {
                            next.naturalTypes.Remove(n);
                        }
                        else
                        {
                            next.naturalTypes.Add(n);
                        }
                    }
                    foreach (var n in edge.relations)
                    {
                        if (next.relations.Contains(n))
                        {
                            next.relations.Remove(n);
                        }
                        else
                        {
                            next.relations.Add(n);
                        }
                    }
                    foreach (var n in edge.ways)
                    {
                        if (next.ways.Contains(n))
                        {
                            next.ways.Remove(n);
                        }
                        else
                        {
                            next.ways.Add(n);
                        }
                    }
                }
            }
            SaveAsImage(manager, frRoot);
            SaveAsFile(manager, frRoot);
        }
コード例 #19
0
        private void InitDraw(GraphicsDevice graphicsDevice, SectorBounds bounds, ISector rootSector)
        {
            double relativeCameraZoom = camera.cameraZoom - Math.Log(ZCoords.GetSectorManager().GetTopmostOSMSectors().Count, 4) + (Game1.RECORDING ? 1 : 0);
            // autoload stuff
            // TODO: move to update step?
            int            zoomLevel        = Math.Min(Math.Max((int)(relativeCameraZoom - 3), 0), ZCoords.GetSectorManager().GetHighestOSMZoom());
            List <ISector> containedSectors = rootSector.GetSectorsInRange(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY, zoomLevel);

            foreach (var pair in loadedMaps.Where(x => AllowUnload(x.Key, rootSector, containedSectors)).ToList())
            {
                loadedMaps[pair.Key].Dispose();
                loadedMaps.Remove(pair.Key);
            }
            // end autoload stuff
            if (toLoad != null || Constants.TO_LOAD != null)
            {
                if (Constants.TO_LOAD != null)
                {
                    toLoad = ZCoords.GetSectorManager().FromString(Constants.TO_LOAD);
                }
                Stopwatch sw = new Stopwatch();
                sw.Start();
                foreach (var sector in toLoad.GetChildrenAtLevel(ZCoords.GetSectorManager().GetHighestOSMZoom()))
                {
                    osmSectorLoader.GetGraphicsBuffer(graphicsDevice, sector).Dispose();
                }
                Console.WriteLine($"Total load time for {toLoad} is {sw.Elapsed.TotalHours} h");
                toLoad = null;
                if (Constants.TO_LOAD != null)
                {
                    Constants.TERMINATE = true;
                    Constants.TO_LOAD   = null;
                }
            }
            bool loadCache = !(relativeCameraZoom - 4 > ZCoords.GetSectorManager().GetHighestOSMZoom());

            foreach (var l in containedSectors)
            {
                if (loadCache)
                {
                    if (!loadedMaps.ContainsKey(l))
                    {
                        loadedMaps[l] = osmSectorLoader.GetCacheBuffer(graphicsDevice, l);
                    }
                }
                else
                {
                    if (!loadedMaps.ContainsKey(l) || loadedMaps[l] is ImageTileBuffer)
                    {
                        if (loadedMaps.ContainsKey(l))
                        {
                            loadedMaps[l].Dispose();
                        }
                        loadedMaps[l] = osmSectorLoader.GetGraphicsBuffer(graphicsDevice, l);
                    }
                }
            }
            List <ISector> sorted = containedSectors.Where(x => x.GetRoot().Equals(rootSector)).ToList();

            sorted.Sort((x, y) => x.Zoom.CompareTo(y.Zoom));
            foreach (var sector in sorted)
            {
                IGraphicsBuffer buffer     = loadedMaps[sector];
                Matrixd         projection = Matrixd.CreateOrthographicOffCenter(bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.maxY * (1 << sector.Zoom) - sector.Y, bounds.minY * (1 << sector.Zoom) - sector.Y, -1, 0.01f); // TODO: why negative?
                RenderContext   context    = new RenderContext(graphicsDevice, projection, bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.minY * (1 << sector.Zoom) - sector.Y, bounds.maxY * (1 << sector.Zoom) - sector.Y, camera.cameraZoom, RenderContext.LayerPass.MAIN_PASS);
                buffer.InitDraw(context);
            }
        }