Beispiel #1
0
        private static void ImportLayers(ContentImporterContext context, List <TiledMapLayerContent> layers, string path)
        {
            for (var i = 0; i < layers.Count; i++)
            {
                if (layers[i] is TiledMapImageLayerContent imageLayer)
                {
                    imageLayer.Image.Source = Path.Combine(path, imageLayer.Image.Source);
                    ContentLogger.Log($"Adding dependency for '{imageLayer.Image.Source}'");

                    // Tell the pipeline that we depend on this image and need to rebuild the map if the image changes.
                    // (Maybe the image is a different size)
                    context.AddDependency(imageLayer.Image.Source);
                }
                if (layers[i] is TiledMapObjectLayerContent objectLayer)
                {
                    foreach (var obj in objectLayer.Objects)
                    {
                        if (!String.IsNullOrWhiteSpace(obj.TemplateSource))
                        {
                            obj.TemplateSource = Path.Combine(path, obj.TemplateSource);
                            ContentLogger.Log($"Adding dependency for '{obj.TemplateSource}'");
                            // Tell the pipeline that we depend on this template and need to rebuild the map if the template changes.
                            // (Templates are loaded into objects on process, so all objects which depend on the template file
                            //  need the change to the template)
                            context.AddDependency(obj.TemplateSource);
                        }
                    }
                }
                if (layers[i] is TiledMapGroupLayerContent groupLayer)
                {
                    // Yay recursion!
                    ImportLayers(context, groupLayer.Layers, path);
                }
            }
        }
        private TiledMapTilesetContent DeserializeTiledMapTilesetContent(string filePath, ContentImporterContext context)
        {
            using (var reader = new StreamReader(filePath))
            {
                var tilesetSerializer = new XmlSerializer(typeof(TiledMapTilesetContent));
                var tileset           = (TiledMapTilesetContent)tilesetSerializer.Deserialize(reader);

                tileset.Image.Source = $"{Path.GetDirectoryName(filePath)}/{tileset.Image.Source}";
                ContentLogger.Log($"Adding dependency '{tileset.Image.Source}'");
                context.AddDependency(tileset.Image.Source);

                foreach (var tile in tileset.Tiles)
                {
                    foreach (var obj in tile.Objects)
                    {
                        if (!string.IsNullOrWhiteSpace(obj.TemplateSource))
                        {
                            obj.TemplateSource = $"{Path.GetDirectoryName(filePath)}/{obj.TemplateSource}";
                            ContentLogger.Log($"Adding dependency '{obj.TemplateSource}'");

                            // We depend on the template.
                            context.AddDependency(obj.TemplateSource);
                        }
                    }
                }

                return(tileset);
            }
        }
Beispiel #3
0
        private static TiledMapContent DeserializeTiledMapContent(string mapFilePath, ContentImporterContext context)
        {
            using (var reader = new StreamReader(mapFilePath))
            {
                var mapSerializer = new XmlSerializer(typeof(TiledMapContent));
                var map           = (TiledMapContent)mapSerializer.Deserialize(reader);

                map.FilePath = mapFilePath;

                for (var i = 0; i < map.Tilesets.Count; i++)
                {
                    var tileset = map.Tilesets[i];

                    if (!string.IsNullOrWhiteSpace(tileset.Source))
                    {
                        tileset.Source = Path.Combine(Path.GetDirectoryName(mapFilePath), tileset.Source);
                        ContentLogger.Log($"Adding dependency for {tileset.Source}");
                        // We depend on the tileset. If the tileset changes, the map also needs to rebuild.
                        context.AddDependency(tileset.Source);
                    }
                    else
                    {
                        tileset.Image.Source = Path.Combine(Path.GetDirectoryName(mapFilePath), tileset.Image.Source);
                        ContentLogger.Log($"Adding dependency for {tileset.Image.Source}");
                        context.AddDependency(tileset.Image.Source);
                    }
                }

                ImportLayers(context, map.Layers, Path.GetDirectoryName(mapFilePath));

                map.Name = mapFilePath;
                return(map);
            }
        }
Beispiel #4
0
        private IList <Texture2DContent> ImportSLMC(string filename, ContentImporterContext context)
        {
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(filename);

            var channels = xmlDoc.DocumentElement;

            if (channels.Name != "channels")
            {
                throw new InvalidContentException(String.Format("Root element must be 'channels'."));
            }

            TextureImporter         txImporter = new TextureImporter();
            List <Texture2DContent> images     = new List <Texture2DContent>();

            foreach (XmlNode imageNode in channels.ChildNodes)
            {
                if (imageNode.Name != "image")
                {
                    throw new InvalidContentException(String.Format("Element '{0}' not supported in 'channels'.", imageNode.Name));
                }

                var imageSource     = GetAttribute(imageNode, "source");
                var fullImageSource = Path.Combine(Path.GetDirectoryName(filename), imageSource);
                context.AddDependency(fullImageSource);
                var textureContent = (Texture2DContent)txImporter.Import(fullImageSource, context);
                textureContent.Name = Path.GetFileNameWithoutExtension(fullImageSource);

                images.Add(textureContent);
            }

            return(images);
        }
Beispiel #5
0
        public override AtlasDec Import(string filename, ContentImporterContext context)
        {
            // TODO: process the input object, and return the modified data.
            string fileName  = Path.GetFileNameWithoutExtension(filename).Trim();
            string parentDir = Path.GetDirectoryName(filename);

            // Look for a folder with the same name as this file...
            string folder = Path.Combine(parentDir, fileName);
            bool   exists = Directory.Exists(folder);

            if (!exists)
            {
                throw new Exception("Failed to import the atlas, adjacent source folder '" + folder + "' was not found!");
            }

            string search = "*.png";
            var    found  = Directory.EnumerateFiles(folder, search, SearchOption.AllDirectories);
            var    files  = found.ToArray();

            for (int i = 0; i < files.Length; i++)
            {
                var f = files[i];
                context.AddDependency(f);
            }
            AtlasDec dec = new AtlasDec(folder, fileName, files);

            context.Logger.LogMessage("Imported atlas with " + files.Length + " files.");

            return(dec);
        }
        private MaterialContent GetMaterial(aiMesh aiMesh)
        {
            aiString difuse = new aiString();

            scene.mMaterials[(int)aiMesh.mMaterialIndex].GetTextureDiffuse0(difuse);

            if (!String.IsNullOrEmpty(difuse.Data))
            {
                String original = difuse.Data;
                difuse.Data = Path.GetFileName(difuse.Data);
                importerContext.AddDependency(Path.Combine(directory, difuse.Data));

                try
                {
                    BasicMaterialContent materialContent = new BasicMaterialContent();
                    materialContent.Name    = difuse.Data;
                    materialContent.Texture = new ExternalReference <TextureContent>(difuse.Data);
                    return(materialContent);
                }
                catch (InvalidContentException)
                {
                    // InvalidContentExceptions do not need further processing
                    throw;
                }
                catch (Exception e)
                {
                    // Wrap exception with content identity (includes line number)
                    throw new InvalidContentException(e.ToString());
                }
            }
            return(null);
        }
 /// <summary>
 /// Adds a dependency to the specified file. This causes a rebuild of the file, when modified,
 /// on subsequent incremental builds.
 /// </summary>
 /// <param name="filename">The name of an asset file.</param>
 public void AddDependency(string filename)
 {
     if (_importerContext != null)
     {
         _importerContext.AddDependency(filename);
     }
     if (_processorContext != null)
     {
         _processorContext.AddDependency(filename);
     }
 }
Beispiel #8
0
        public override List <byte[]> Import(string filename, ContentImporterContext context)
        {
            List <byte[]> imageData = new List <byte[]>();
            List <string> imageFilenames;

            context.AddDependency(Path.Combine(Environment.CurrentDirectory, filename));
            using (XmlReader reader = XmlReader.Create(filename))
            {
                imageFilenames = IntermediateSerializer.Deserialize <List <string> >(reader, null);
            }

            foreach (string imageFilename in imageFilenames)
            {
                byte[] imageBytes = File.ReadAllBytes(imageFilename);
                imageData.Add(imageBytes);
                context.AddDependency(Path.Combine(Environment.CurrentDirectory, imageFilename));
            }

            return(imageData);
        }
        private static TiledMapObjectTemplateContent DeserializeTileMapObjectTemplateContent(string filePath, ContentImporterContext context)
        {
            using (var reader = new StreamReader(filePath))
            {
                var templateSerializer = new XmlSerializer(typeof(TiledMapObjectTemplateContent));
                var template           = (TiledMapObjectTemplateContent)templateSerializer.Deserialize(reader);

                if (!string.IsNullOrWhiteSpace(template.Tileset?.Source))
                {
                    template.Tileset.Source = Path.Combine(Path.GetDirectoryName(filePath), template.Tileset.Source);
                    ContentLogger.Log($"Adding dependency '{template.Tileset.Source}'");
                    // We depend on this tileset.
                    context.AddDependency(template.Tileset.Source);
                }

                return(template);
            }
        }
Beispiel #10
0
        public override AtlasDeclaration Import(string filename, ContentImporterContext context)
        {
            // TODO: process the input object, and return the modified data.
            var folders = File.ReadLines(filename);
            //.Select(s => Path.GetFullPath(Path.Combine(Path.GetDirectoryName(filename), s)));
            var           rootDir = Path.GetDirectoryName(filename);
            List <string> pngList = new List <string>();

            foreach (var f in folders)
            {
                var pngs = Directory.EnumerateFiles(Path.GetFullPath(Path.Combine(rootDir, f))).Where(w => w.EndsWith(".png")).Select(s => s.Substring(rootDir.Length + 1));//, SearchOption.TopDirectoryOnly);
                foreach (var p in pngs)
                {
                    pngList.Add(p);
                    context.AddDependency(Path.Combine(rootDir, p));
                }
            }

            return(new AtlasDeclaration(rootDir, Path.GetFileNameWithoutExtension(filename), pngList.Select(s => s.Replace('\\', '/')).ToArray()));
        }
Beispiel #11
0
        private static TextureAtlasContent ImportTMX(string filename, ContentImporterContext context)
        {
            TextureAtlasContent output = new TextureAtlasContent();

            output.Identity = new ContentIdentity(filename);

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(filename);

            var map         = xmlDoc.DocumentElement;
            var orientation = GetAttribute(map, "orientation");

            if (orientation != "orthogonal")
            {
                throw new InvalidContentException("Invalid orientation. Only 'orthogonal' is supported for atlases.");
            }
            output.Renderorder = GetAttribute(map, "renderorder");
            output.MapColumns  = GetAttributeAsInt(map, "width").Value;
            output.MapRows     = GetAttributeAsInt(map, "height").Value;
            output.TileWidth   = GetAttributeAsInt(map, "tilewidth").Value;
            output.TileHeight  = GetAttributeAsInt(map, "tileheight").Value;
            output.Width       = output.MapColumns * output.TileWidth;
            output.Height      = output.MapRows * output.TileHeight;

            XmlNode tileset = map["tileset"];

            output.Firstgid = GetAttributeAsInt(tileset, "firstgid").Value;

            if (tileset.Attributes["source"] != null)
            {
                var tsxFilename   = tileset.Attributes["source"].Value;
                var baseDirectory = Path.GetDirectoryName(filename);
                tsxFilename = Path.Combine(baseDirectory, tsxFilename);
                var sourceSprites = ImportTSX(tsxFilename, context);
                output.SourceSprites.AddRange(sourceSprites);
                context.AddDependency(tsxFilename);
            }
            else
            {
                var rootDirectory = Path.GetDirectoryName(filename);
                var sourceSprites = ImportTileset(tileset, context, rootDirectory);
                output.SourceSprites.AddRange(sourceSprites);
            }

            XmlNode layerNode    = map["layer"];
            var     layerColumns = Convert.ToInt32(map.Attributes["width"].Value, CultureInfo.InvariantCulture);
            var     layerRows    = Convert.ToInt32(map.Attributes["height"].Value, CultureInfo.InvariantCulture);

            output.LayerColumns = layerColumns;
            output.LayerRows    = layerRows;

            XmlNode layerDataNode = layerNode["data"];
            var     encoding      = layerDataNode.Attributes["encoding"].Value;

            if (encoding != "csv")
            {
                throw new InvalidContentException("Invalid encoding. Only 'csv' is supported for data.");
            }
            var data           = layerDataNode.InnerText;
            var dataStringList = data.Split(',');
            var mapData        = new int[dataStringList.Length];

            for (int i = 0; i < dataStringList.Length; i++)
            {
                mapData[i] = Convert.ToInt32(dataStringList[i].Trim(), CultureInfo.InvariantCulture);
            }
            output.MapData = mapData;

            return(output);
        }
Beispiel #12
0
        public override TmxMap Import(string filename, ContentImporterContext context)
        {
            if (filename == null)
            {
                throw new ArgumentNullException(nameof(filename));
            }

            var mapSerializer     = new XmlSerializer(typeof(TmxMap));
            var tileSetSerializer = new XmlSerializer(typeof(TmxTileSet));

            var map = (TmxMap)mapSerializer.Deserialize(new StringReader(File.ReadAllText(filename)));

            map.OriginalFileName = filename;

            for (var i = 0; i < map.TileSets.Count; i++)
            {
                var baseReferenceFile = filename;
                if (!string.IsNullOrWhiteSpace(map.TileSets[i].Source))
                {
                    var tileSetPath = ImportPathHelper.GetReferencedFilePath(
                        filename,
                        map.TileSets[i].Source);

                    context.AddDependency(tileSetPath);

                    var originalFirstGid = map.TileSets[i].FirstGid;

                    map.TileSets[i]          = (TmxTileSet)tileSetSerializer.Deserialize(new StringReader(File.ReadAllText(tileSetPath)));
                    map.TileSets[i].FirstGid = originalFirstGid;

                    baseReferenceFile = tileSetPath;
                }

                if (map.TileSets[i].Image != null)
                {
                    map.TileSets[i].Image.Source = ImportPathHelper.GetReferencedFilePath(
                        baseReferenceFile,
                        map.TileSets[i].Image.Source);

                    context.AddDependency(map.TileSets[i].Image.Source);
                }

                foreach (var tile in map.TileSets[i].Tiles)
                {
                    if (tile.Image != null)
                    {
                        tile.Image.Source = ImportPathHelper.GetReferencedFilePath(
                            baseReferenceFile,
                            tile.Image.Source);
                    }
                }
            }

            foreach (var layer in map.Layers.OfType <TmxTileLayer>())
            {
                var data = layer.Data;

                if (data.Encoding == "csv")
                {
                    data.Tiles = data.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                 .Select(uint.Parse).Select(gid => new TmxDataTile {
                        Gid = gid
                    }).ToList();
                }
                else if (data.Encoding == "base64")
                {
                    var encodedData = data.Value.Trim();
                    var decodedData = Convert.FromBase64String(encodedData);

                    using (var stream = OpenStream(decodedData, data.Compression))
                        using (var reader = new BinaryReader(stream))
                        {
                            data.Tiles = new List <TmxDataTile>();

                            for (var y = 0; y < layer.Width; y++)
                            {
                                for (var x = 0; x < layer.Height; x++)
                                {
                                    var gid = reader.ReadUInt32();
                                    data.Tiles.Add(new TmxDataTile {
                                        Gid = gid
                                    });
                                }
                            }
                        }
                }
            }

            foreach (var layer in map.Layers.OfType <TmxImageLayer>())
            {
                if (layer.Image != null)
                {
                    layer.Image.Source = ImportPathHelper.GetReferencedFilePath(
                        filename,
                        layer.Image.Source);
                }
            }

            return(map);
        }
        /// <summary>
        /// Parses and executes an individual line of an OBJ file.
        /// </summary>
        /// <param name="lineTokens">Line to parse as tokens</param>
        private void ParseObjLine(string[] lineTokens)
        {
            // Switch by line type
            switch (lineTokens[0].ToLower())
            {
            // Object
            case "o":
                // The next token is the name of the model
                rootNode.Name = lineTokens[1];
                break;

            // Positions
            case "v":
                positions.Add(ParseVector3(lineTokens));
                break;

            // Texture coordinates
            case "vt":
            {
                // u is required, but v and w are optional
                // Require a Vector2 and ignore the w for the sake of this sample
                Vector2 vt = ParseVector2(lineTokens);

                // Flip the v coordinate
                vt.Y = 1 - vt.Y;

                texCoords.Add(vt);
                break;
            }

            // Normals
            case "vn":
                normals.Add(ParseVector3(lineTokens));
                break;

            // Groups (model meshes)
            case "g":
                // End the current mesh
                if (meshBuilder != null)
                {
                    FinishMesh();
                }

                // Begin a new mesh
                // The next token is an optional name
                if (lineTokens.Length > 1)
                {
                    StartMesh(lineTokens[1]);
                }
                else
                {
                    StartMesh(null);
                }
                break;

            // Smoothing group
            case "s":
                // Ignore; just use the normals as specified with verticies
                break;

            // Faces (triangles and quads are supported)
            case "f":

                // For triangles
                int[] polyIndices =
                {
                    0, 1, 2
                };

                // Warn about and ignore polygons which are not triangles or quads
                if (lineTokens.Length > 4)
                {
                    Array.Resize(ref polyIndices, 6);
                    polyIndices[2] = 3;
                    polyIndices[3] = 1;
                    polyIndices[4] = 2;
                    polyIndices[5] = 3;

                    /*
                     * Futher faces (if any) will be ignored
                     *  importerContext.Logger.LogWarning(null, rootNode.Identity,
                     * "N-sided polygons are not supported; Ignoring face");
                     *  break;*/
                }

                // If the builder is null, this face is outside of a group
                // Start a new, unnamed group
                if (meshBuilder == null)
                {
                    StartMesh(null);
                }

                // Loop through every polygon vertex (3 if triangle, 6 if quad)
                for (int vertexIndex = 0; vertexIndex < polyIndices.Length; vertexIndex++)
                {
                    // Each vertex is a set of three indices:
                    // position, texture coordinate, and normal
                    // The indices are 1-based, separated by slashes
                    // and only position is required.
                    string[] indices = lineTokens[polyIndices[vertexIndex] + 1].Split('/');

                    // Required: Position
                    int positionIndex = int.Parse(indices[0],
                                                  CultureInfo.InvariantCulture) - 1;

                    if (indices.Length > 1)
                    {
                        // Optional: Texture coordinate
                        int     texCoordIndex;
                        Vector2 texCoord;
                        if (int.TryParse(indices[1], out texCoordIndex))
                        {
                            texCoord = texCoords[texCoordIndex - 1];
                        }
                        else
                        {
                            texCoord = Vector2.Zero;
                        }

                        // Set channel data for texture coordinate for the following
                        // vertex. This must be done before calling AddTriangleVertex
                        meshBuilder.SetVertexChannelData(textureCoordinateDataIndex,
                                                         texCoord);
                    }

                    if (indices.Length > 2)
                    {
                        // Optional: Normal
                        int     normalIndex;
                        Vector3 normal;
                        if (int.TryParse(indices[2], out normalIndex))
                        {
                            normal = normals[normalIndex - 1];
                        }
                        else
                        {
                            normal = Vector3.Zero;
                        }

                        // Set channel data for normal for the following vertex.
                        // This must be done before calling AddTriangleVertex
                        meshBuilder.SetVertexChannelData(normalDataIndex,
                                                         normal);
                    }

                    // Add the vertex with the vertex data that was just set
                    meshBuilder.AddTriangleVertex(positionMap[positionIndex]);
                }
                break;

            // Import a material library file
            case "mtllib":
                // Remaining tokens are relative paths to MTL files
                for (int i = 1; i < lineTokens.Length; i++)
                {
                    string mtlFileName = lineTokens[i];

                    // A full path is needed,
                    if (!Path.IsPathRooted(mtlFileName))
                    {
                        // resolve relative paths
                        string directory =
                            Path.GetDirectoryName(rootNode.Identity.SourceFilename);
                        mtlFileName = Path.GetFullPath(
                            Path.Combine(directory, mtlFileName));
                    }

                    // By calling AddDependency, we will cause this model
                    // to be rebuilt if its associated MTL files change
                    importerContext.AddDependency(mtlFileName);

                    // Import and record the new materials
                    ImportMaterials(mtlFileName);
                }
                break;

            // Apply a material
            case "usemtl":
            {
                // If the builder is null, OBJ most likely lacks groups
                // Start a new, unnamed group
                if (meshBuilder == null)
                {
                    StartMesh(null);
                }

                // Next token is material name
                string materialName = lineTokens[1];

                // Apply the material to the upcoming faces
                MaterialContent material;
                if (materials.TryGetValue(materialName, out material))
                {
                    meshBuilder.SetMaterial(material);
                }
                else
                {
                    throw new InvalidContentException(String.Format(
                                                          "Material '{0}' not defined.", materialName),
                                                      rootNode.Identity);
                }

                break;
            }

            // Unsupported or invalid line types
            default:
                throw new InvalidContentException(
                          "Unsupported or invalid line type '" + lineTokens[0] + "'",
                          rootNode.Identity);
            }
        }
Beispiel #14
0
        void parseObjLine(string[] lineTokens)
        {
            switch (lineTokens[0].ToLower( ))
            {
            case "o":
                rootNode.Name = lineTokens[1];
                break;

            case "v":
                positions.Add(parseVector3(lineTokens));
                break;

            case "vt": {
                Vector2 vt = parseVector2(lineTokens);
                vt.Y = 1 - vt.Y;

                texCoords.Add(vt);
                break;
            }

            case "vn":
                normals.Add(parseVector3(lineTokens));
                break;

            case "g":
                if (meshBuilder != null)
                {
                    this.finishMesh( );
                }

                if (lineTokens.Length > 1)
                {
                    this.startMesh(lineTokens[1]);
                }
                else
                {
                    this.startMesh(null);
                }
                break;

            case "s":
                break;

            case "f":
                if (lineTokens.Length > 4)
                {
                    importerContext.Logger.LogWarning(null, rootNode.Identity, "N-sided polygons are not supported! Ignoring vertex.");
                    break;
                }

                if (meshBuilder == null)
                {
                    this.startMesh(null);
                }

                for (int vertexIndex = 1; vertexIndex <= 3; vertexIndex++)
                {
                    string[] indices       = lineTokens[vertexIndex].Split('/');
                    int      positionIndex = int.Parse(indices[0], CultureInfo.InvariantCulture) - 1;

                    if (indices.Length > 1)
                    {
                        int     texCoordIndex;
                        Vector2 texCoord;

                        if (int.TryParse(indices[1], out texCoordIndex))
                        {
                            texCoord = texCoords[texCoordIndex - 1];
                        }
                        else
                        {
                            texCoord = Vector2.Zero;
                        }

                        meshBuilder.SetVertexChannelData(textureCoordinateDataIndex, texCoord);
                    }

                    if (indices.Length > 2)
                    {
                        int     normalIndex;
                        Vector3 normal;

                        if (int.TryParse(indices[2], out normalIndex))
                        {
                            normal = normals[normalIndex - 1];
                        }
                        else
                        {
                            normal = Vector3.Zero;
                        }

                        meshBuilder.SetVertexChannelData(normalDataIndex, normal);
                    }

                    meshBuilder.AddTriangleVertex(positionMap[positionIndex]);
                }
                break;

            case "mtllib":
                for (int i = 1; i < lineTokens.Length; i++)
                {
                    string mtlFileName = lineTokens[i];

                    if (!Path.IsPathRooted(mtlFileName))
                    {
                        string directory = Path.GetDirectoryName(rootNode.Identity.SourceFilename);
                        mtlFileName = Path.GetFullPath(Path.Combine(directory, mtlFileName));
                    }

                    importerContext.AddDependency(mtlFileName);

                    this.importMaterials(mtlFileName);
                }
                break;

            case "usemtl": {
                if (meshBuilder == null)
                {
                    this.startMesh(null);
                }

                string          materialName = lineTokens[1];
                MaterialContent material;

                if (materials.TryGetValue(materialName, out material))
                {
                    meshBuilder.SetMaterial(material);
                }
                else
                {
                    throw new InvalidContentException(String.Format("Material '{0}' is not defined.", materialName), rootNode.Identity);
                }

                break;
            }

            default:
                throw new InvalidContentException("Unsupported or invalid line type '" + lineTokens[0] + "'", rootNode.Identity);
            }
        }