private StringWriter BuildWavefrontStringForTileObjectMesh(TmxMesh mesh)
        {
            Logger.WriteVerbose("Building mesh obj file for tile: '{0}.obj'", mesh.UniqueMeshName);
            GenericListDatabase <Vertex3> vertexDatabase = new GenericListDatabase <Vertex3>();
            HashIndexOf <PointF>          uvDatabase     = new HashIndexOf <PointF>();
            StringBuilder faces = new StringBuilder();


            // Get the single tile associated with this mesh
            TmxTile tmxTile = this.tmxMap.Tiles[mesh.TileIds[0]];

            var vertices = CalculateFaceVertices_TileObject(tmxTile.TileSize, tmxTile.Offset);
            var uvs      = CalculateFaceTextureCoordinates(tmxTile, false, false, false);

            // TileObjects have zero depth on their vertices. Their GameObject parent will set depth.
            FaceVertices faceVertices = new FaceVertices {
                Vertices = vertices, Depth_z = 0.0f
            };

            // Adds vertices and uvs to the database as we build the face strings
            string v0 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V0) + 1, uvDatabase.Add(uvs[0]) + 1);
            string v1 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V1) + 1, uvDatabase.Add(uvs[1]) + 1);
            string v2 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V2) + 1, uvDatabase.Add(uvs[2]) + 1);
            string v3 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V3) + 1, uvDatabase.Add(uvs[3]) + 1);

            faces.AppendFormat("f {0} {1} {2} {3}\n", v0, v1, v2, v3);

            // We have all the data we need to build the wavefront file format
            return(CreateWavefrontWriter(mesh, vertexDatabase, uvDatabase, faces));
        }
Exemple #2
0
        protected override void InternalFromXml(System.Xml.Linq.XElement xml, TmxMap tmxMap)
        {
            // Get the tile
            uint gid = TmxHelper.GetAttributeAsUInt(xml, "gid");

            this.FlippedHorizontal = TmxMath.IsTileFlippedHorizontally(gid);
            this.FlippedVertical   = TmxMath.IsTileFlippedVertically(gid);
            uint rawTileId = TmxMath.GetTileIdWithoutFlags(gid);

            this.Tile = tmxMap.Tiles[rawTileId];

            // The tile needs to have a mesh on it.
            // Note: The tile may already be referenced by another TmxObjectTile instance, and as such will have its mesh data already made
            if (this.Tile.Meshes.Count() == 0)
            {
                this.Tile.Meshes = TmxMesh.FromTmxTile(this.Tile, tmxMap);
            }

            // Check properties for layer placement
            if (this.Properties.PropertyMap.ContainsKey("unity:sortingLayerName"))
            {
                this.SortingLayerName = this.Properties.GetPropertyValueAsString("unity:sortingLayerName");
            }
            if (this.Properties.PropertyMap.ContainsKey("unity:sortingOrder"))
            {
                this.SortingOrder = this.Properties.GetPropertyValueAsInt("unity:sortingOrder");
            }
        }
Exemple #3
0
        public static List <TmxMesh> FromTmxTile(TmxTile tmxTile, TmxMap tmxMap)
        {
            List <TmxMesh> list = new List <TmxMesh>();
            int            num  = 0;

            foreach (TmxFrame frame in tmxTile.Animation.Frames)
            {
                uint    globalTileId = frame.GlobalTileId;
                TmxTile tmxTile2     = tmxMap.Tiles[globalTileId];
                TmxMesh tmxMesh      = new TmxMesh();
                tmxMesh.TileIds                 = new uint[1];
                tmxMesh.TileIds[0]              = globalTileId;
                tmxMesh.UniqueMeshName          = string.Format("{0}_mesh_tile_{1}", tmxMap.Name, TmxMath.GetTileIdWithoutFlags(globalTileId).ToString("D4"));
                tmxMesh.TmxImage                = tmxTile2.TmxImage;
                tmxMesh.ObjectName              = "tile_obj";
                tmxMesh.StartTimeMs             = num;
                tmxMesh.DurationMs              = frame.DurationMs;
                tmxMesh.FullAnimationDurationMs = tmxTile.Animation.TotalTimeMs;
                if (tmxMesh.DurationMs != 0)
                {
                    TmxMesh tmxMesh2 = tmxMesh;
                    tmxMesh2.ObjectName += $"[{num}-{num + tmxMesh.DurationMs}][{tmxMesh.FullAnimationDurationMs}]";
                }
                num += frame.DurationMs;
                list.Add(tmxMesh);
            }
            return(list);
        }
Exemple #4
0
        // Splits a layer into TmxMesh instances
        public static List <TmxMesh> ListFromTmxLayer(TmxLayer layer)
        {
            List <TmxMesh> meshes = new List <TmxMesh>();

            for (int i = 0; i < layer.TileIds.Count(); ++i)
            {
                // Copy the tile unto the mesh that uses the same image
                // (In other words, we are grouping tiles by images into a mesh)
                uint    tileId = layer.TileIds[i];
                TmxTile tile   = layer.TmxMap.GetTileFromTileId(tileId);
                if (tile == null)
                {
                    continue;
                }

                int timeMs = 0;
                foreach (var frame in tile.Animation.Frames)
                {
                    uint frameTileId = frame.GlobalTileId;

                    // Have to put any rotations/flipping from the source tile into this one
                    frameTileId |= (tileId & TmxMath.FLIPPED_HORIZONTALLY_FLAG);
                    frameTileId |= (tileId & TmxMath.FLIPPED_VERTICALLY_FLAG);
                    frameTileId |= (tileId & TmxMath.FLIPPED_DIAGONALLY_FLAG);

                    // Find a mesh to stick this tile into (if it exists)
                    TmxMesh mesh = meshes.Find(m => m.CanAddFrame(tile, timeMs, frame.DurationMs));
                    if (mesh == null)
                    {
                        // Create a new mesh and add it to our list
                        mesh                = new TmxMesh();
                        mesh.TileIds        = new uint[layer.TileIds.Count()];
                        mesh.UniqueMeshName = String.Format("mesh_{0}", layer.TmxMap.GetUniqueId().ToString("D4"));
                        mesh.TmxImage       = tile.TmxImage;

                        // Keep track of the timing for this mesh (non-animating meshes will have a start time and duration of 0)
                        mesh.StartTimeMs             = timeMs;
                        mesh.DurationMs              = frame.DurationMs;
                        mesh.FullAnimationDurationMs = tile.Animation.TotalTimeMs;

                        mesh.ObjectName = Path.GetFileNameWithoutExtension(tile.TmxImage.AbsolutePath);
                        if (mesh.DurationMs != 0)
                        {
                            // Decorate the name a bit with some animation details for the frame
                            mesh.ObjectName += string.Format("[{0}-{1}]", timeMs, timeMs + mesh.DurationMs);
                        }

                        meshes.Add(mesh);
                    }

                    // This mesh contains this tile
                    mesh.AddTile(i, frameTileId);

                    // Advance time
                    timeMs += frame.DurationMs;
                }
            }

            return(meshes);
        }
Exemple #5
0
        // Splits a layer into TmxMesh instances
        public static List<TmxMesh> ListFromTmxLayer(TmxLayer layer)
        {
            List<TmxMesh> meshes = new List<TmxMesh>();

            for (int i = 0; i < layer.TileIds.Count(); ++i)
            {
                // Copy the tile unto the mesh that uses the same image
                // (In other words, we are grouping tiles by images into a mesh)
                uint tileId = layer.TileIds[i];
                TmxTile tile = layer.TmxMap.GetTileFromTileId(tileId);
                if (tile == null)
                    continue;

                int timeMs = 0;
                foreach (var frame in tile.Animation.Frames)
                {
                    uint frameTileId = frame.GlobalTileId;

                    // Have to put any rotations/flipping from the source tile into this one
                    frameTileId |= (tileId & TmxMath.FLIPPED_HORIZONTALLY_FLAG);
                    frameTileId |= (tileId & TmxMath.FLIPPED_VERTICALLY_FLAG);
                    frameTileId |= (tileId & TmxMath.FLIPPED_DIAGONALLY_FLAG);

                    // Find a mesh to stick this tile into (if it exists)
                    TmxMesh mesh = meshes.Find(m => m.CanAddFrame(tile, timeMs, frame.DurationMs));
                    if (mesh == null)
                    {
                        // Create a new mesh and add it to our list
                        mesh = new TmxMesh();
                        mesh.TileIds = new uint[layer.TileIds.Count()];
                        mesh.UniqueMeshName = String.Format("mesh_{0}", layer.TmxMap.GetUniqueId().ToString("D4"));
                        mesh.TmxImage = tile.TmxImage;

                        // Keep track of the timing for this mesh (non-animating meshes will have a start time and duration of 0)
                        mesh.StartTimeMs = timeMs;
                        mesh.DurationMs = frame.DurationMs;
                        mesh.FullAnimationDurationMs = tile.Animation.TotalTimeMs;

                        mesh.ObjectName = Path.GetFileNameWithoutExtension(tile.TmxImage.AbsolutePath);
                        if (mesh.DurationMs != 0)
                        {
                            // Decorate the name a bit with some animation details for the frame
                            mesh.ObjectName += string.Format("[{0}-{1}]", timeMs, timeMs + mesh.DurationMs);
                        }

                        meshes.Add(mesh);
                    }

                    // This mesh contains this tile
                    mesh.AddTile(i, frameTileId);

                    // Advance time
                    timeMs += frame.DurationMs;
                }
            }

            return meshes;
        }
        private StringWriter BuildWavefrontStringForLayerMesh(TmxLayer layer, TmxMesh mesh, IEnumerable <int> horizontalRange, IEnumerable <int> verticalRange)
        {
            Logger.WriteVerbose("Building mesh obj file for '{0}'", mesh.UniqueMeshName);
            GenericListDatabase <Vertex3> vertexDatabase = new GenericListDatabase <Vertex3>();
            HashIndexOf <PointF>          uvDatabase     = new HashIndexOf <PointF>();
            StringBuilder faces = new StringBuilder();

            foreach (int y in verticalRange)
            {
                foreach (int x in horizontalRange)
                {
                    int  tileIndex = layer.GetTileIndex(x, y);
                    uint tileId    = mesh.GetTileIdAt(tileIndex);

                    // Skip blank tiles
                    if (tileId == 0)
                    {
                        continue;
                    }

                    TmxTile tile = this.tmxMap.Tiles[TmxMath.GetTileIdWithoutFlags(tileId)];

                    // What are the vertex and texture coorindates of this face on the mesh?
                    var position = this.tmxMap.GetMapPositionAt(x, y, tile);
                    var vertices = CalculateFaceVertices(position, tile.TileSize);

                    // If we're using depth shaders then we'll need to set a depth value of this face
                    float depth_z = 0.0f;
                    if (Tiled2Unity.Settings.DepthBufferEnabled)
                    {
                        depth_z = CalculateFaceDepth(position.Y + tmxMap.TileHeight, tmxMap.MapSizeInPixels.Height);
                    }

                    FaceVertices faceVertices = new FaceVertices {
                        Vertices = vertices, Depth_z = depth_z
                    };

                    // Is the tile being flipped or rotated (needed for texture cooridinates)
                    bool flipDiagonal   = TmxMath.IsTileFlippedDiagonally(tileId);
                    bool flipHorizontal = TmxMath.IsTileFlippedHorizontally(tileId);
                    bool flipVertical   = TmxMath.IsTileFlippedVertically(tileId);
                    var  uvs            = CalculateFaceTextureCoordinates(tile, flipDiagonal, flipHorizontal, flipVertical);

                    // Adds vertices and uvs to the database as we build the face strings
                    string v0 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V0) + 1, uvDatabase.Add(uvs[0]) + 1);
                    string v1 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V1) + 1, uvDatabase.Add(uvs[1]) + 1);
                    string v2 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V2) + 1, uvDatabase.Add(uvs[2]) + 1);
                    string v3 = String.Format("{0}/{1}/1", vertexDatabase.AddToDatabase(faceVertices.V3) + 1, uvDatabase.Add(uvs[3]) + 1);
                    faces.AppendFormat("f {0} {1} {2} {3}\n", v0, v1, v2, v3);
                }
            }

            // We have all the data we need to build the wavefront file format
            return(CreateWavefrontWriter(mesh, vertexDatabase, uvDatabase, faces));
        }
Exemple #7
0
        public static List <TmxMesh> ListFromTmxChunk(TmxChunk chunk)
        {
            List <TmxMesh> list = new List <TmxMesh>();

            for (int i = 0; i < chunk.TileIds.Count; i++)
            {
                uint    num  = chunk.TileIds[i];
                TmxTile tile = chunk.ParentData.ParentLayer.ParentMap.GetTileFromTileId(num);
                if (tile != null)
                {
                    int timeMs = 0;
                    foreach (TmxFrame frame in tile.Animation.Frames)
                    {
                        uint globalTileId = frame.GlobalTileId;
                        globalTileId |= (num & TmxMath.FLIPPED_HORIZONTALLY_FLAG);
                        globalTileId |= (num & TmxMath.FLIPPED_VERTICALLY_FLAG);
                        globalTileId |= (num & TmxMath.FLIPPED_DIAGONALLY_FLAG);
                        TmxMesh tmxMesh = list.Find((TmxMesh m) => m.CanAddFrame(tile, timeMs, frame.DurationMs, tile.Animation.TotalTimeMs));
                        if (tmxMesh == null)
                        {
                            TmxTile tileFromTileId = chunk.ParentData.ParentLayer.ParentMap.GetTileFromTileId(globalTileId);
                            tmxMesh                         = new TmxMesh();
                            tmxMesh.X                       = chunk.X;
                            tmxMesh.Y                       = chunk.Y;
                            tmxMesh.Width                   = chunk.Width;
                            tmxMesh.Height                  = chunk.Height;
                            tmxMesh.TileIds                 = new uint[chunk.TileIds.Count];
                            tmxMesh.UniqueMeshName          = string.Format("{0}_mesh_{1}", chunk.ParentData.ParentLayer.ParentMap.Name, chunk.ParentData.ParentLayer.ParentMap.GetUniqueId().ToString("D4"));
                            tmxMesh.TmxImage                = tileFromTileId.TmxImage;
                            tmxMesh.StartTimeMs             = timeMs;
                            tmxMesh.DurationMs              = frame.DurationMs;
                            tmxMesh.FullAnimationDurationMs = tile.Animation.TotalTimeMs;
                            tmxMesh.ObjectName              = Path.GetFileNameWithoutExtension(tileFromTileId.TmxImage.AbsolutePath);
                            if (tmxMesh.DurationMs != 0)
                            {
                                TmxMesh tmxMesh2 = tmxMesh;
                                tmxMesh2.ObjectName += $"[{timeMs}-{timeMs + tmxMesh.DurationMs}][{tmxMesh.FullAnimationDurationMs}]";
                            }
                            list.Add(tmxMesh);
                        }
                        tmxMesh.AddTile(i, globalTileId);
                        timeMs += frame.DurationMs;
                    }
                }
            }
            return(list);
        }
Exemple #8
0
        public static TmxLayer FromXml(XElement elem, TmxLayerNode parent, TmxMap tmxMap)
        {
            TmxLayer tmxLayer = new TmxLayer(parent, tmxMap);

            tmxLayer.FromXmlInternal(elem);
            if (elem.Name == (XName)"layer")
            {
                tmxLayer.ParseLayerXml(elem);
            }
            else if (elem.Name == (XName)"imagelayer")
            {
                tmxLayer.ParseImageLayerXml(elem);
            }
            tmxLayer.Meshes = TmxMesh.ListFromTmxLayer(tmxLayer);
            tmxLayer.BuildCollisionLayers();
            return(tmxLayer);
        }
Exemple #9
0
        protected override void InternalFromXml(System.Xml.Linq.XElement xml, TmxMap tmxMap)
        {
            // Get the tile
            uint gid = TmxHelper.GetAttributeAsUInt(xml, "gid");

            this.FlippedHorizontal = TmxMath.IsTileFlippedHorizontally(gid);
            this.FlippedVertical   = TmxMath.IsTileFlippedVertically(gid);
            uint rawTileId = TmxMath.GetTileIdWithoutFlags(gid);

            this.Tile = tmxMap.Tiles[rawTileId];

            // The tile needs to have a mesh on it.
            // Note: The tile may already be referenced by another TmxObjectTile instance, and as such will have its mesh data already made
            if (this.Tile.Meshes.Count() == 0)
            {
                this.Tile.Meshes = TmxMesh.FromTmxTile(this.Tile, tmxMap);
            }
        }
        protected override void InternalFromXml(XElement xml, TmxMap tmxMap)
        {
            uint attributeAsUInt = TmxHelper.GetAttributeAsUInt(xml, "gid");

            FlippedHorizontal = TmxMath.IsTileFlippedHorizontally(attributeAsUInt);
            FlippedVertical   = TmxMath.IsTileFlippedVertically(attributeAsUInt);
            uint tileIdWithoutFlags = TmxMath.GetTileIdWithoutFlags(attributeAsUInt);

            Tile = tmxMap.Tiles[tileIdWithoutFlags];
            if (Tile.Meshes.Count() == 0)
            {
                Tile.Meshes = TmxMesh.FromTmxTile(Tile, tmxMap);
            }
            ExplicitSortingLayerName = base.Properties.GetPropertyValueAsString("unity:sortingLayerName", "");
            if (base.Properties.PropertyMap.ContainsKey("unity:sortingOrder"))
            {
                ExplicitSortingOrder = base.Properties.GetPropertyValueAsInt("unity:sortingOrder");
            }
        }
Exemple #11
0
        // Creates a TmxMesh from a tile (for tile objects)
        public static List <TmxMesh> FromTmxTile(TmxTile tmxTile, TmxMap tmxMap)
        {
            List <TmxMesh> meshes = new List <TmxMesh>();

            int timeMs = 0;

            foreach (var frame in tmxTile.Animation.Frames)
            {
                uint    frameTileId = frame.GlobalTileId;
                TmxTile frameTile   = tmxMap.Tiles[frameTileId];

                TmxMesh mesh = new TmxMesh();
                mesh.TileIds    = new uint[1];
                mesh.TileIds[0] = frameTileId;

                mesh.UniqueMeshName = String.Format("{0}_mesh_tile_{1}", tmxMap.Name, TmxMath.GetTileIdWithoutFlags(frameTileId).ToString("D4"));
                mesh.TmxImage       = frameTile.TmxImage;
                mesh.ObjectName     = "tile_obj";

                // Keep track of the timing for this mesh (non-animating meshes will have a start time and duration of 0)
                mesh.StartTimeMs             = timeMs;
                mesh.DurationMs              = frame.DurationMs;
                mesh.FullAnimationDurationMs = tmxTile.Animation.TotalTimeMs;

                if (mesh.DurationMs != 0)
                {
                    // Decorate the name a bit with some animation details for the frame
                    mesh.ObjectName += string.Format("[{0}-{1}][{2}]", timeMs, timeMs + mesh.DurationMs, mesh.FullAnimationDurationMs);
                }

                // Advance time
                timeMs += frame.DurationMs;

                // Add the animation frame to our list of meshes
                meshes.Add(mesh);
            }

            return(meshes);
        }
        private StringWriter CreateWavefrontWriter(TmxMesh mesh, GenericListDatabase <Vertex3> vertexDatabase, HashIndexOf <PointF> uvDatabase, StringBuilder faces)
        {
            StringWriter wavefront = new StringWriter();

            wavefront.WriteLine("# Tiled2Unity generated file. Do not modify by hand.");
            wavefront.WriteLine("# Wavefront file for '{0}.obj'", mesh.UniqueMeshName);
            wavefront.WriteLine();

            wavefront.WriteLine("# Vertices (Count = {0})", vertexDatabase.List.Count());
            foreach (var v in vertexDatabase.List)
            {
                wavefront.WriteLine("v {0} {1} {2}", v.X, v.Y, v.Z);
            }
            wavefront.WriteLine();

            wavefront.WriteLine("# Texture cooridinates (Count = {0})", uvDatabase.List.Count());
            foreach (var uv in uvDatabase.List)
            {
                wavefront.WriteLine("vt {0} {1}", uv.X, uv.Y);
            }
            wavefront.WriteLine();

            // Write the one indexed normal
            wavefront.WriteLine("# Normal");
            wavefront.WriteLine("vn 0 0 -1");
            wavefront.WriteLine();

            // Now we can copy over the string used to build the databases
            wavefront.WriteLine("# Mesh description");
            wavefront.WriteLine("g {0}", mesh.UniqueMeshName);
            wavefront.WriteLine();
            wavefront.WriteLine("# Faces");
            wavefront.WriteLine(faces.ToString());

            return(wavefront);
        }
Exemple #13
0
        public static TmxLayer FromXml(XElement elem, TmxLayerNode parent, TmxMap tmxMap)
        {
            TmxLayer tmxLayer = new TmxLayer(parent, tmxMap);

            tmxLayer.FromXmlInternal(elem);

            // We can build a layer from a "tile layer" (default) or an "image layer"
            if (elem.Name == "layer")
            {
                tmxLayer.Width  = TmxHelper.GetAttributeAsInt(elem, "width");
                tmxLayer.Height = TmxHelper.GetAttributeAsInt(elem, "height");
                tmxLayer.ParseData(elem.Element("data"));
            }
            else if (elem.Name == "imagelayer")
            {
                XElement xmlImage = elem.Element("image");
                if (xmlImage == null)
                {
                    Logger.WriteWarning("Image Layer '{0}' is being ignored since it has no image.", tmxLayer.Name);
                    tmxLayer.Ignore = IgnoreSettings.True;
                    return(tmxLayer);
                }

                // An image layer is sort of like an tile layer but with just one tile
                tmxLayer.Width  = 1;
                tmxLayer.Height = 1;

                // Find the "tile" that matches our image
                string  imagePath = TmxHelper.GetAttributeAsFullPath(elem.Element("image"), "source");
                TmxTile tile      = tmxMap.Tiles.First(t => t.Value.TmxImage.AbsolutePath == imagePath).Value;
                tmxLayer.TileIds = new uint[1] {
                    tile.GlobalId
                };

                // The image layer needs to be tranlated in an interesting way when expressed as a tile layer
                PointF translated = tmxLayer.Offset;

                // Make up for height of a regular tile in the map
                translated.Y -= (float)tmxMap.TileHeight;

                // Make up for the height of this image
                translated.Y += (float)tile.TmxImage.Size.Height;

                // Correct for any orientation effects on the map (like isometric)
                // (We essentially undo the translation via orientation here)
                PointF orientation = TmxMath.TileCornerInScreenCoordinates(tmxMap, 0, 0);
                translated.X -= orientation.X;
                translated.Y -= orientation.Y;

                // Translate by the x and y coordiantes
                translated.X   += TmxHelper.GetAttributeAsFloat(elem, "x", 0);
                translated.Y   += TmxHelper.GetAttributeAsFloat(elem, "y", 0);
                tmxLayer.Offset = translated;
            }

            // Sometimes TMX files have "dead" tiles in them (tiles that were removed but are still referenced)
            // Remove these tiles from the layer by replacing them with zero
            for (int t = 0; t < tmxLayer.TileIds.Length; ++t)
            {
                uint tileId = tmxLayer.TileIds[t];
                tileId = TmxMath.GetTileIdWithoutFlags(tileId);
                if (!tmxMap.Tiles.ContainsKey(tileId))
                {
                    tmxLayer.TileIds[t] = 0;
                }
            }

            // Each layer will be broken down into "meshes" which are collections of tiles matching the same texture or animation
            tmxLayer.Meshes = TmxMesh.ListFromTmxLayer(tmxLayer);

            // Each layer may contain different collision types which are themselves put into "Collison Layers" to be processed later
            tmxLayer.BuildCollisionLayers();

            return(tmxLayer);
        }
Exemple #14
0
        public static TmxLayer FromXml(XElement elem, TmxMap tmxMap)
        {
            Program.WriteVerbose(elem.ToString());
            TmxLayer tmxLayer = new TmxLayer(tmxMap);

            // Order within Xml file is import for layer types
            tmxLayer.XmlElementIndex = elem.NodesBeforeSelf().Count();

            // Have to decorate layer names in order to force them into being unique
            // Also, can't have whitespace in the name because Unity will add underscores
            tmxLayer.Name = TmxHelper.GetAttributeAsString(elem, "name");

            tmxLayer.Visible = TmxHelper.GetAttributeAsInt(elem, "visible", 1) == 1;
            tmxLayer.Opacity = TmxHelper.GetAttributeAsFloat(elem, "opacity", 1);

            PointF offset = new PointF(0, 0);

            offset.X        = TmxHelper.GetAttributeAsFloat(elem, "offsetx", 0);
            offset.Y        = TmxHelper.GetAttributeAsFloat(elem, "offsety", 0);
            tmxLayer.Offset = offset;

            // Set our properties
            tmxLayer.Properties = TmxProperties.FromXml(elem);

            // Set the "ignore" setting on this layer
            tmxLayer.Ignore = tmxLayer.Properties.GetPropertyValueAsEnum <IgnoreSettings>("unity:ignore", IgnoreSettings.False);

            // We can build a layer from a "tile layer" (default) or an "image layer"
            if (elem.Name == "layer")
            {
                tmxLayer.Width  = TmxHelper.GetAttributeAsInt(elem, "width");
                tmxLayer.Height = TmxHelper.GetAttributeAsInt(elem, "height");
                tmxLayer.ParseData(elem.Element("data"));
            }
            else if (elem.Name == "imagelayer")
            {
                XElement xmlImage = elem.Element("image");
                if (xmlImage == null)
                {
                    Program.WriteWarning("Image Layer '{0}' is being ignored since it has no image.", tmxLayer.Name);
                    tmxLayer.Ignore = IgnoreSettings.True;
                    return(tmxLayer);
                }

                // An image layer is sort of like an tile layer but with just one tile
                tmxLayer.Width  = 1;
                tmxLayer.Height = 1;

                // Find the "tile" that matches our image
                string  imagePath = TmxHelper.GetAttributeAsFullPath(elem.Element("image"), "source");
                TmxTile tile      = tmxMap.Tiles.First(t => t.Value.TmxImage.AbsolutePath == imagePath).Value;
                tmxLayer.TileIds = new uint[1] {
                    tile.GlobalId
                };

                // The image layer needs to be tranlated in an interesting way when expressed as a tile layer
                PointF translated = tmxLayer.Offset;

                // Make up for height of a regular tile in the map
                translated.Y -= (float)tmxMap.TileHeight;

                // Make up for the height of this image
                translated.Y += (float)tile.TmxImage.Size.Height;

                // Correct for any orientation effects on the map (like isometric)
                // (We essentially undo the translation via orientation here)
                PointF orientation = TmxMath.TileCornerInScreenCoordinates(tmxMap, 0, 0);
                translated.X -= orientation.X;
                translated.Y -= orientation.Y;

                // Translate by the x and y coordiantes
                translated.X   += TmxHelper.GetAttributeAsFloat(elem, "x", 0);
                translated.Y   += TmxHelper.GetAttributeAsFloat(elem, "y", 0);
                tmxLayer.Offset = translated;
            }

            // Each layer will be broken down into "meshes" which are collections of tiles matching the same texture or animation
            tmxLayer.Meshes = TmxMesh.ListFromTmxLayer(tmxLayer);

            return(tmxLayer);
        }
Exemple #15
0
        // Creates a TmxMesh from a tile (for tile objects)
        public static List<TmxMesh> FromTmxTile(TmxTile tmxTile, TmxMap tmxMap)
        {
            List<TmxMesh> meshes = new List<TmxMesh>();

            int timeMs = 0;
            foreach (var frame in tmxTile.Animation.Frames)
            {
                uint frameTileId = frame.GlobalTileId;
                TmxTile frameTile = tmxMap.Tiles[frameTileId];

                TmxMesh mesh = new TmxMesh();
                mesh.TileIds = new uint[1];
                mesh.TileIds[0] = frameTileId;

                mesh.UniqueMeshName = String.Format("mesh_tile_{0}", TmxMath.GetTileIdWithoutFlags(frameTileId).ToString("D4"));
                mesh.TmxImage = frameTile.TmxImage;
                mesh.ObjectName = "tile_obj";

                // Keep track of the timing for this mesh (non-animating meshes will have a start time and duration of 0)
                mesh.StartTimeMs = timeMs;
                mesh.DurationMs = frame.DurationMs;
                mesh.FullAnimationDurationMs = tmxTile.Animation.TotalTimeMs;

                if (mesh.DurationMs != 0)
                {
                    // Decorate the name a bit with some animation details for the frame
                    mesh.ObjectName += string.Format("[{0}-{1}]", timeMs, timeMs + mesh.DurationMs);
                }

                // Advance time
                timeMs += frame.DurationMs;

                // Add the animation frame to our list of meshes
                meshes.Add(mesh);
            }

            return meshes;
        }