예제 #1
0
        private VertexPositionNormalTexture[] GetVertices(Vector3 position, TextureTile texture)
        {
            var vertices = new VertexPositionNormalTexture[TILE_FACE_VERTICES];

            for (int i = 0; i < TILE_FACE_VERTICES; i++)
            {
                vertices[i].Position          = position + Vectors[i];
                vertices[i].Normal            = Normals[i];
                vertices[i].TextureCoordinate = texture.GetPosition(new Vector2(vertices[i].Position.X, vertices[i].Position.Z));
            }
            float xLength  = Math.Abs((vertices[1].Position - vertices[0].Position).Length());
            float yLength  = Math.Abs((vertices[3].Position - vertices[0].Position).Length());
            float dxLength = Math.Abs((vertices[2].Position - vertices[3].Position).Length());
            float dyLength = Math.Abs((vertices[2].Position - vertices[1].Position).Length());

            var start = new Vector2(vertices[0].Position.X, vertices[0].Position.Z);

            /*vertices[0].TextureCoordinate = texture.GetPosition(start + new Vector2(0, 0));
             * vertices[1].TextureCoordinate = texture.GetPosition(start + new Vector2(xLength, 0));
             * vertices[2].TextureCoordinate = texture.GetPosition(start + new Vector2(dxLength, dyLength));
             * //vertices[2].TextureCoordinate = texture.GetPosition(start + new Vector2(xLength, yLength));
             * vertices[3].TextureCoordinate = texture.GetPosition(start + new Vector2(0, yLength));*/
            vertices[0].TextureCoordinate = texture.GetPosition(start + new Vector2(0, 0));
            vertices[1].TextureCoordinate = texture.GetPosition(start + new Vector2(1, 0));
            vertices[2].TextureCoordinate = texture.GetPosition(start + new Vector2(1, 1));
            vertices[3].TextureCoordinate = texture.GetPosition(start + new Vector2(0, 1));
            return(vertices);
        }
예제 #2
0
        protected override void DrawSubCell(SKCanvas g, TextureTile tile, Direction direction, Color c)
        {
            var baseArea = GetTileArea(tile);
            var tileArea = GetSubTileAreaForDirection(direction, baseArea);

            g.DrawRectangle(c, new IntRect(tileArea.X, tileArea.Y, tileArea.Width - 1, tileArea.Height - 1));
        }
예제 #3
0
        protected override void DrawSubCell(SKCanvas g, TextureTile tile, Direction direction, Color c)
        {
            var baseArea = GetTileArea(tile);
            var tileArea = GetSubTileAreaForDirection(direction, baseArea);

            CreateShape(tileArea).Draw(g, c);
        }
예제 #4
0
        public virtual TextureTile TexturePosition(Direction direction)
        {
            TextureTile tile = new TextureTile();

            tile.x = 0;
            tile.y = 0;

            return(tile);
        }
예제 #5
0
        public void ValidateTextureTile()
        {
            var tt   = new TextureTile();
            var root = TextureSetFileWriter.GenerateTile(tt);

            root.Name.Should().Be(Namespace + "tile");
            root.Should().HaveAttribute("x", "0");
            root.Should().HaveAttribute("y", "0");
        }
예제 #6
0
 public Tile(TextureTile faceTextures, MapTile[] tiles, int depthScale)
 {
     FaceTexture = faceTextures;
     for (int i = 0; i < TILE_FACE_VERTICES; i++)
     {
         Vectors[i].Y = GetDepth(tiles[i], depthScale);
         Normals[i]   = new Vector3((float)(tiles[i].Data.A - tiles[i].Data.C) / depthScale, (float)(tiles[i].Data.B - tiles[i].Data.D) / depthScale, 2);
         Normals[i].Normalize();
     }
 }
예제 #7
0
        public BlockStructure(BlockType type, BlockState state, SoundType soundType = SoundType.DESTROY_STONE)
        {
            this.type  = type;
            this.state = state;
            this.shape = BlockShape.CUBE;

            topUVs     = sideUVs = botUvs = BlockUVs.AIR_UV;
            topTexture = sideTexture = botTexture = TextureTile.AIR;

            this.soundType = soundType;
        }
예제 #8
0
        public virtual Vector2[] FaceUVs(Direction direction)
        {
            Vector2[]   UVs     = new Vector2[4];
            TextureTile tilePos = TexturePosition(direction);

            UVs [0] = new Vector2(TILE_SIZE * tilePos.x + TILE_SIZE, TILE_SIZE * tilePos.y);
            UVs [1] = new Vector2(TILE_SIZE * tilePos.x + TILE_SIZE, TILE_SIZE * tilePos.y + TILE_SIZE);
            UVs [2] = new Vector2(TILE_SIZE * tilePos.x, TILE_SIZE * tilePos.y + TILE_SIZE);
            UVs [3] = new Vector2(TILE_SIZE * tilePos.x, TILE_SIZE * tilePos.y);
            return(UVs);
        }
예제 #9
0
        protected override void DrawIndexedDirection(SKCanvas g, TextureTile tile, NeighbourIndex idx)
        {
            var points = CreateShape(GetTileArea(tile)).ToHighlight().GetHighlightFor(idx);
            var brush  = Grid.TextureTileFormattingMetaData.TileHighlightColor ?? Preferences.DefaultTileHighlightColor;

            for (var pidx = 1; pidx < points.Count; pidx += 1)
            {
                var p1 = points[pidx - 1];
                var p2 = points[pidx];
                g.DrawRasterLine(brush, p1.X, p1.Y, p2.X, p2.Y);
            }
        }
예제 #10
0
        public BlockStructure(BlockType type, TextureTile tile, BlockShape shape, BlockState state, SoundType soundType = SoundType.DESTROY_STONE)
        {
            this.type  = type;
            this.shape = shape;
            this.state = state;

            topTexture = sideTexture = botTexture = tile;
            topUVs     = BlockUVs.GetTileUVs(tile);
            sideUVs    = BlockUVs.GetTileUVs(tile);
            botUvs     = BlockUVs.GetTileUVs(tile);

            this.soundType = soundType;
        }
예제 #11
0
        public override void Draw(SKCanvas g, TextureTile tile)
        {
            DrawCellFrame(g, tile);

            var rect = GetTileArea(tile);
            var pen  = Grid.TextureTileFormattingMetaData.TileOutlineColor ?? Preferences.DefaultTileColor;

            var shape = CreateShape(rect);

            shape.Draw(g, pen);

            DrawHeightIndicator(g, tile);
            DrawSelectorHint(g, tile);
            DrawAnchor(g, tile);
        }
예제 #12
0
        public override void Draw(SKCanvas g, TextureTile tile)
        {
            DrawCellFrame(g, tile);

            var pen = Grid.TextureTileFormattingMetaData.TileOutlineColor ?? Preferences.DefaultTileColor;

            // to be pixel perfect, the rectangle size must be reduced by one so that the
            // line is drawing within the tile area.
            var tileArea = GetTileArea(tile);

            g.DrawRectangle(pen, tileArea);

            DrawSelectorHint(g, tile);
            DrawAnchor(g, tile);
        }
예제 #13
0
        public BlockStructure(BlockType type, TextureTile top, TextureTile side, TextureTile bottom, BlockShape shape, BlockState state, SoundType soundType = SoundType.DESTROY_STONE)
        {
            this.type  = type;
            this.shape = shape;
            this.state = state;

            this.topTexture  = top;
            this.sideTexture = side;
            this.botTexture  = bottom;
            topUVs           = BlockUVs.GetTileUVs(top);
            sideUVs          = BlockUVs.GetTileUVs(side);
            botUvs           = BlockUVs.GetTileUVs(bottom);

            this.soundType = soundType;
        }
예제 #14
0
        static bool TileAlreadyExists(List <TextureTile> existingTiles, TextureTile tile)
        {
            bool ContainsAll(ICollection <string> pool, IEnumerable <string> needles)
            {
                return(needles.All(pool.Contains));
            }

            foreach (var t in existingTiles)
            {
                if (ContainsAll(t.Tags, tile.Tags))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #15
0
 public static void Initialize()
 {
     if (initialized)
     {
         Debug.Log("TileRegistry has been initialized already.");
         return;
     }
     else
     {
         initialized = true;
     }
     TileNames    = new string[2];
     Tiles        = new Tile[2];
     Tiles[0]     = new TextureTile(0, 0, 0);
     TileNames[0] = "Test 1 [0, 0]";
     Tiles[1]     = new TextureTile(1, 3, 3);
     TileNames[1] = "Test 2 [3, 3]";
 }
예제 #16
0
        public void ValidateTextureTileMultipleTags()
        {
            var tt = new TextureTile();

            tt.Tags.Add("tag1");
            tt.Tags.Add("tag2");
            var root = TextureSetFileWriter.GenerateTile(tt);

            root.Name.Should().Be(Namespace + "tile");
            root.Attribute("tag").Should().BeNull();
            root.Should().HaveAttribute("x", "0");
            root.Should().HaveAttribute("y", "0");

            var l = root.Elements(Namespace + "tag").ToList();

            l.Count.Should().Be(2);
            l[0].Should().HaveValue("tag1");
            l[1].Should().HaveValue("tag2");
        }
예제 #17
0
        void DrawTile(SKCanvas g, TextureTile tile)
        {
            var cw = grid.EffectiveCellSize;
            var x  = tile.X * (cw.Width + grid.CellSpacing);
            var y  = tile.Y * (cw.Height + grid.CellSpacing);

            var trs = g.TotalMatrix;

            try
            {
                g.Translate(x, y);
                var painter = grid.CreateTilePainter(prefs);
                painter.Draw(g, tile);
            }
            finally
            {
                g.SetMatrix(trs);
            }
        }
예제 #18
0
        public async Task SaveFile(string fileName)
        {
            var textureSet = SelectedItem switch
            {
                TextureSetFile s => s,
                TileTextureCollection c => c.Parent,
                TextureGrid g => g.Parent?.Parent,
                TextureTile t => t.Parent?.Parent?.Parent,
                _ => null
            };

            if (textureSet == null)
            {
                return;
            }

            GeneratorPreferencesWriter.EnsureParentDirectoryExists(fileName);
            var doc = TextureSetFileWriter.GenerateXml(textureSet);

            await using var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true);
            await doc.SaveAsync(stream, default, default);
예제 #19
0
        void OnArrangeTiles()
        {
            var collections = selectedItem switch
            {
                TextureSetFile tf => tf.Collections.ToArray(),
                TileTextureCollection tc => new[] { tc },
                TextureGrid gd => new[] { gd.Parent },
                TextureTile t => new[] { t.Parent?.Parent },
                _ => Array.Empty <TileTextureCollection>()
            };

            foreach (var c in collections)
            {
                if (c != null)
                {
                    TextureGridAutoLayout.ArrangeGrids(UserPreferences.Preferences, c);
                }
            }
        }

        void OnGenerateTiles()
        {
            var grids = selectedItem switch
            {
                TextureSetFile tf => tf.Collections.SelectMany(e => e.Grids),
                TileTextureCollection tc => tc.Grids,
                TextureGrid gd => Enumerable.Repeat(gd, 1),
                TextureTile t => Enumerable.Repeat(t.Parent, 1),
                _ => Array.Empty <TextureGrid>()
            };

            foreach (var g in grids)
            {
                if (g != null)
                {
                    TextureTileGenerator.Regenerate(g);
                }
            }
        }
예제 #20
0
    public async override Task <TextureTile> GetTexture(TileId tileId, CancellationToken cancellationToken = default)
    {
        // This tile service works in TilePositions (X, Y, ZOOM), not TileIds, so we need to convert.
        var tilePosition = tileId.ToTilePosition();
        var zoom         = tilePosition.LevelOfDetail.Value;

        // Also, the service has four DNS aliases which can help distribute request load. Because this is a quad-tree
        // tile system where each tile has three siblings, i.e. a tile has four children, then we can use the tile's ID
        // in relation to it's parent (is it child 0, 1, 2, or 3?) to determine which subdomain alias to use.
        var subdomain   = tileId.GetSubdomain();
        var subdomainId = subdomain == 0 ? "" : subdomain.ToString();

        // Construct the URL.
        var uri = $@"http://mesonet{subdomainId}.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/{zoom}/{tilePosition.X}/{tilePosition.Y}.jpg";

        // Retrieve the bytes for this tile (it's a JPEG).
        var response = await _httpClient.GetAsync(uri).ConfigureAwait(false);

        var result = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

        // Create a TextureTile.
        return(TextureTile.FromImageData(result));
    }
예제 #21
0
        static private VertexPositionNormalTexture[] GetVertices(Vector3 position, List <TextureTile> textures)
        {
            var vertices   = new VertexPositionNormalTexture[CUBE_VERTICES_COUNT];
            int face       = -1;
            int faceVertex = CUBE_FACE_VERTICES - 1;
//			int faceRotation = 0;
            TextureTile texture = null;

            for (int i = 0; i < CUBE_VERTICES_COUNT; i++)
            {
                if (++faceVertex == CUBE_FACE_VERTICES)
                {
                    texture    = textures[++face];
                    faceVertex = 0;
//					faceRotation = FaceTextureRotation[face];
                }
                var cornerVector = Vectors[i];
                vertices[i].Position          = position + cornerVector;
                vertices[i].Normal            = Normal[i];
                vertices[i].TextureCoordinate = texture.GetPosition(TextureCoordinates[faceVertex]);
            }
            return(vertices);
        }
예제 #22
0
        void OnTreeSelectionChanged()
        {
            var collection = structureTree.SelectedItem switch
            {
                TextureSetFile f => f.Collections.FirstOrDefault(),
                TileTextureCollection c => c,
                TextureGrid g => g.Parent,
                TextureTile t => t.Parent?.Parent,
                _ => null
            };

            var textureSet = structureTree.SelectedItem switch
            {
                TextureSetFile f => f,
                TileTextureCollection c => c.Parent,
                TextureGrid g => g.Parent?.Parent,
                TextureTile t => t.Parent?.Parent?.Parent,
                _ => null
            };

            Console.WriteLine("Selection changed " + structureTree.SelectedItem + " -> " + collection + " | " + textureSet);
            SelectedTextureCollection = collection;
            SelectedTextureSet        = textureSet;
        }
예제 #23
0
        void DrawHeightIndicator(SKCanvas g, TextureTile tile)
        {
            var rect       = GetTileArea(tile);
            var extraSpace = rect.Y;

            // Only draw the extra height if the resulting box would be
            // sufficiently large. Otherwise the upper and lower shape
            // just meld together into a ugly blob.
            if (extraSpace < 5)
            {
                return;
            }

            var baseShape = CreateShape(rect);

            var brush = Grid.TextureTileFormattingMetaData.TileOutlineColor ?? Preferences.DefaultTileColor;
            var shape = CreateShape(new IntRect(rect.X, rect.Y - extraSpace, rect.Width, rect.Height));

            shape.Draw(g, brush);

            g.DrawRasterLine(brush, baseShape.Left, shape.Left);
            g.DrawRasterLine(brush, baseShape.Right, shape.Right);
            g.DrawRasterLine(brush, baseShape.Bottom, shape.Bottom);
        }
예제 #24
0
        public IntRect GetTileHighlightArea(TextureTile tile)
        {
            var rect = GetTileArea(tile);

            return(new IntRect(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));
        }
예제 #25
0
        /// <summary>
        /// Generates tiles
        /// </summary>
        /// <param name="solidArea">A reference array that will be filled with the solid tiles</param>
        public void GenerateTiles(bool[,] solidArea)
        {
            for (int y = 0; y < gridSizeY; ++y)
            {
                for (int x = 0; x < gridSizeX; ++x)
                {
                    if (IsInsideBorder(x, y))
                    {
                        //If first row inside border, cast top shadow
                        if (y == 1)
                        {
                            //If first block inside row, corner shadow
                            if (x == 1)
                                textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.TopLeftShadow], tileTexture);
                            else
                                textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.TopShadow], tileTexture);

                            continue;
                        }

                        //If first column inside border, cast left shadow
                        if (x == 1)
                        {
                            textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.LeftShadow], tileTexture);
                            continue;
                        }

                        //Hard block every 2 spaces
                        if (x % 2 == 0 && y % 2 == 0)
                        {
                            textureTileGrid[x, y] = new TextureTile(0, 0, hardBlockTexture);
                            solidArea[x, y] = true;
                        }
                        else //Make shadow for block
                        {
                            if (x % 2 == y % 2)
                                textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.DiagonalBlockShadow], tileTexture);
                            else if (x % 2 == 0 && y % 2 != 0)
                                textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.UnderBlockShadow], tileTexture);
                            else
                                textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.RightBlockShadow], tileTexture);
                        }
                    }
                    else //The border
                    {
                        if (x == 0 && y != 0 && y != gridSizeY - 1)
                            textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.LeftBorder], tileTexture);
                        else
                            textureTileGrid[x, y] = new TextureTile(TileTypes[(int)TileType.Border], tileTexture);

                        solidArea[x, y] = true;
                    }
                }
            }
        }
예제 #26
0
 public CubeFace(TextureTile tile)
 {
     TextureTile = tile;
 }
예제 #27
0
        public virtual TextureTile TexturePosition(Direction direction)
        {
            TextureTile tile = new TextureTile ();
            tile.x = 0;
            tile.y = 0;

            return tile;
        }
예제 #28
0
 public IntRect GetTileArea(TextureTile tile)
 {
     if (tile.Parent == null)
     {
         return(default);
        public static BlockUVs GetTileUVs(TextureTile tile)
        {
            switch (tile)
            {
            case TextureTile.DIRT:
                return(DIRT_UV);

            case TextureTile.SAND:
                return(SAND_UV);

            case TextureTile.GRASS_BLOCK_TOP:
                return(GRASS_BLOCK_TOP_UV);

            case TextureTile.GRASS_BLOCK_SIDE:
                return(GRASS_BLOCK_SIDE_UV);

            case TextureTile.STONE:
                return(STONE_UV);

            case TextureTile.COBBLESTONE:
                return(COBBLESTONE_UV);

            case TextureTile.OBSIDIAN:
                return(OBSIDIAN_UV);

            case TextureTile.OAK_LOG_SIDE:
                return(OAK_LOG_SIDE_UV);

            case TextureTile.SPRUCE_LOG_SIDE:
                return(SPRUCE_LOG_SIDE_UV);

            case TextureTile.BIRCH_LOG_SIDE:
                return(BIRCH_LOG_SIDE_UV);

            case TextureTile.JUNGLE_LOG_SIDE:
                return(JUNGLE_LOG_SIDE_UV);

            case TextureTile.OAK_LOG_TOP:
                return(OAK_LOG_TOP_UV);

            case TextureTile.SPRUCE_LOG_TOP:
                return(SPRUCE_LOG_TOP_UV);

            case TextureTile.BIRCH_LOG_TOP:
                return(BIRCH_LOG_TOP_UV);

            case TextureTile.JUNGLE_LOG_TOP:
                return(JUNGLE_LOG_TOP_UV);

            case TextureTile.OAK_LEAVES:
                return(OAK_LEAVES_UV);

            case TextureTile.SPRUCE_LEAVES:
                return(SPRUCE_LEAVES_UV);

            case TextureTile.BIRCH_LEAVES:
                return(BIRCH_LEAVES_UV);

            case TextureTile.JUNGLE_LEAVES:
                return(JUNGLE_LEAVES_UV);

            case TextureTile.OAK_PLANKS:
                return(OAK_PLANKS_UV);

            case TextureTile.SPRUCE_PLANKS:
                return(SPRUCE_PLANKS_UV);

            case TextureTile.BIRCH_PLANKS:
                return(BIRCH_PLANKS_UV);

            case TextureTile.JUNGLE_PLANKS:
                return(JUNGLE_PLANKS_UV);

            case TextureTile.ICE:
                return(ICE_UV);

            case TextureTile.SNOW:
                return(SNOW_UV);

            case TextureTile.WATER:
                return(WATER_UV);

            case TextureTile.GRASS_0:
                return(GRASS_UV_0);

            case TextureTile.GRASS_1:
                return(GRASS_UV_1);

            case TextureTile.GRASS_2:
                return(GRASS_UV_2);

            default:
                return(DIRT_UV);
            }
        }
예제 #30
0
 private static Vector2 GetTextureCoordinates(TextureTile texture, VertexPositionNormalTexture distance)
 {
     return(texture.GetPosition(new Vector2(distance.Position.X, distance.Position.Z)));
 }
예제 #31
0
        protected override void DrawIndexedDirection(SKCanvas g, TextureTile tile, NeighbourIndex idx)
        {
            var points = new List <IntPoint>();

            var rect = GetTileHighlightArea(tile);

            var left    = rect.X;
            var top     = rect.Y;
            var right   = rect.X + rect.Width - 1;
            var bottom  = rect.Y + rect.Height - 1;
            var centerX = MidPoint(rect.X, rect.X + rect.Width);
            var centerY = MidPoint(rect.Y, rect.Y + rect.Height);

            switch (idx)
            {
            case NeighbourIndex.North:
                points.Add(new IntPoint(left, top));
                points.Add(new IntPoint(right, top));
                break;

            case NeighbourIndex.NorthEast:
                points.Add(new IntPoint(centerX, top));
                points.Add(new IntPoint(right, top));
                points.Add(new IntPoint(right, centerY));
                break;

            case NeighbourIndex.East:
                points.Add(new IntPoint(right, top));
                points.Add(new IntPoint(right, bottom));
                break;

            case NeighbourIndex.SouthEast:
                points.Add(new IntPoint(right, centerY));
                points.Add(new IntPoint(right, bottom));
                points.Add(new IntPoint(centerX, bottom));
                break;

            case NeighbourIndex.South:
                points.Add(new IntPoint(left, bottom));
                points.Add(new IntPoint(right, bottom));
                break;

            case NeighbourIndex.SouthWest:
                points.Add(new IntPoint(centerX, bottom));
                points.Add(new IntPoint(left, bottom));
                points.Add(new IntPoint(left, centerY));
                break;

            case NeighbourIndex.West:
                points.Add(new IntPoint(left, top));
                points.Add(new IntPoint(left, bottom));
                break;

            case NeighbourIndex.NorthWest:
                points.Add(new IntPoint(left, centerY));
                points.Add(new IntPoint(left, top));
                points.Add(new IntPoint(centerX, top));
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(idx), idx, null);
            }

            var pen = Grid.TextureTileFormattingMetaData.TileHighlightColor ?? Preferences.DefaultTileHighlightColor;

            g.DrawGeometry(pen, points);
        }
예제 #32
0
        void OnAddCollection()
        {
            var textureSet = SelectedItem switch
            {
                TextureSetFile s => s,
                TileTextureCollection c => c.Parent,
                TextureGrid g => g.Parent?.Parent,
                TextureTile t => t.Parent?.Parent?.Parent,
           _ => null
            };

            textureSet?.Collections.Add(new TileTextureCollection()
            {
                Id = "New Collection"
            }.WithTextureGrid(new TextureGrid()

            {
                Name = "New Texture Grid"
            }));
        }

        void OnAddGrid()
        {
            var textureCollection = SelectedItem switch
            {
                TileTextureCollection c => c,
                TextureGrid g => g.Parent,
                TextureTile t => t.Parent?.Parent,
                _ => null
            };

            textureCollection?.Grids.Add(new TextureGrid()
            {
                Name = "New Texture Grid"
            });
        }

        void OnAddTile()
        {
            var textureGrid = SelectedItem switch
            {
                TextureGrid g => g,
                TextureTile t => t.Parent,
                _ => null
            };

            textureGrid?.Tiles.Add(new TextureTile());
        }

        bool HasAnySelection(object?selectedItem) => selectedItem != null;

        bool CanAddGrid(object?selectedItem) => selectedItem switch
        {
            TileTextureCollection => true,
            TextureGrid => true,
            TextureTile => true,
            _ => false
        };

        bool CanAddTile(object?selectedItem) => selectedItem switch
        {
            TextureGrid => true,
            TextureTile => true,
            _ => false
        };

        public Task OpenFile(string fileName)
        {
            try
            {
                var x = TextureSetFileLoader.Read(fileName);
                TextureFiles.Add(x);
                return(Task.CompletedTask);
            }
            catch (Exception e)
            {
                return(Task.FromException(e));
            }
        }