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)); }
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"); } }
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); }
// 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); }
// 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)); }
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); }
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); }
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"); } }
// 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); }
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); }
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); }
// 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; }