TiledMapLayerModelContent.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright (c) Craftwork Games. All rights reserved.
  2. // Licensed under the MIT license.
  3. // See LICENSE file in the project root for full license information.
  4. using System.Collections.Generic;
  5. using System.Collections.ObjectModel;
  6. using System.Diagnostics;
  7. using System.IO;
  8. using Microsoft.Xna.Framework;
  9. using Microsoft.Xna.Framework.Graphics;
  10. using MonoGame.Extended.Tiled;
  11. namespace MonoGame.Extended.Content.Tiled;
  12. public class TiledMapLayerModelContent
  13. {
  14. private readonly List<VertexPositionTexture> _vertices;
  15. private readonly List<ushort> _indices;
  16. public string LayerName { get; }
  17. public ReadOnlyCollection<VertexPositionTexture> Vertices { get; }
  18. public ReadOnlyCollection<ushort> Indices { get; }
  19. public SizeF ImageSize { get; }
  20. public string TextureAssetName { get; }
  21. public TiledMapLayerModelContent(string layerName, TiledMapImageContent image)
  22. {
  23. LayerName = layerName;
  24. _vertices = new List<VertexPositionTexture>();
  25. Vertices = new ReadOnlyCollection<VertexPositionTexture>(_vertices);
  26. _indices = new List<ushort>();
  27. Indices = new ReadOnlyCollection<ushort>(_indices);
  28. ImageSize = new SizeF(image.Width, image.Height);
  29. TextureAssetName = Path.ChangeExtension(image.Source, null);
  30. }
  31. public TiledMapLayerModelContent(string layerName, TiledMapTilesetContent tileset)
  32. : this(layerName, tileset.Image)
  33. {
  34. }
  35. public void AddTileVertices(Vector2 position, Rectangle? sourceRectangle = null, TiledMapTileFlipFlags flags = TiledMapTileFlipFlags.None)
  36. {
  37. float texelLeft, texelTop, texelRight, texelBottom;
  38. var sourceRectangle1 = sourceRectangle ?? new Rectangle(0, 0, (int)ImageSize.Width, (int)ImageSize.Height);
  39. if (sourceRectangle.HasValue)
  40. {
  41. var reciprocalWidth = 1f / ImageSize.Width;
  42. var reciprocalHeight = 1f / ImageSize.Height;
  43. texelLeft = sourceRectangle1.X * reciprocalWidth;
  44. texelTop = sourceRectangle1.Y * reciprocalHeight;
  45. texelRight = (sourceRectangle1.X + sourceRectangle1.Width) * reciprocalWidth;
  46. texelBottom = (sourceRectangle1.Y + sourceRectangle1.Height) * reciprocalHeight;
  47. }
  48. else
  49. {
  50. texelLeft = 0;
  51. texelTop = 0;
  52. texelBottom = 1;
  53. texelRight = 1;
  54. }
  55. VertexPositionTexture vertexTopLeft, vertexTopRight, vertexBottomLeft, vertexBottomRight;
  56. vertexTopLeft.Position = new Vector3(position, 0);
  57. vertexTopRight.Position = new Vector3(position + new Vector2(sourceRectangle1.Width, 0), 0);
  58. vertexBottomLeft.Position = new Vector3(position + new Vector2(0, sourceRectangle1.Height), 0);
  59. vertexBottomRight.Position =
  60. new Vector3(position + new Vector2(sourceRectangle1.Width, sourceRectangle1.Height), 0);
  61. vertexTopLeft.TextureCoordinate.Y = texelTop;
  62. vertexTopLeft.TextureCoordinate.X = texelLeft;
  63. vertexTopRight.TextureCoordinate.Y = texelTop;
  64. vertexTopRight.TextureCoordinate.X = texelRight;
  65. vertexBottomLeft.TextureCoordinate.Y = texelBottom;
  66. vertexBottomLeft.TextureCoordinate.X = texelLeft;
  67. vertexBottomRight.TextureCoordinate.Y = texelBottom;
  68. vertexBottomRight.TextureCoordinate.X = texelRight;
  69. var flipDiagonally = (flags & TiledMapTileFlipFlags.FlipDiagonally) != 0;
  70. var flipHorizontally = (flags & TiledMapTileFlipFlags.FlipHorizontally) != 0;
  71. var flipVertically = (flags & TiledMapTileFlipFlags.FlipVertically) != 0;
  72. if (flipDiagonally)
  73. {
  74. FloatHelper.Swap(ref vertexTopRight.TextureCoordinate.X, ref vertexBottomLeft.TextureCoordinate.X);
  75. FloatHelper.Swap(ref vertexTopRight.TextureCoordinate.Y, ref vertexBottomLeft.TextureCoordinate.Y);
  76. }
  77. if (flipHorizontally)
  78. {
  79. if (flipDiagonally)
  80. {
  81. FloatHelper.Swap(ref vertexTopLeft.TextureCoordinate.Y, ref vertexTopRight.TextureCoordinate.Y);
  82. FloatHelper.Swap(ref vertexBottomLeft.TextureCoordinate.Y, ref vertexBottomRight.TextureCoordinate.Y);
  83. }
  84. else
  85. {
  86. FloatHelper.Swap(ref vertexTopLeft.TextureCoordinate.X, ref vertexTopRight.TextureCoordinate.X);
  87. FloatHelper.Swap(ref vertexBottomLeft.TextureCoordinate.X, ref vertexBottomRight.TextureCoordinate.X);
  88. }
  89. }
  90. if (flipVertically)
  91. if (flipDiagonally)
  92. {
  93. FloatHelper.Swap(ref vertexTopLeft.TextureCoordinate.X, ref vertexBottomLeft.TextureCoordinate.X);
  94. FloatHelper.Swap(ref vertexTopRight.TextureCoordinate.X, ref vertexBottomRight.TextureCoordinate.X);
  95. }
  96. else
  97. {
  98. FloatHelper.Swap(ref vertexTopLeft.TextureCoordinate.Y, ref vertexBottomLeft.TextureCoordinate.Y);
  99. FloatHelper.Swap(ref vertexTopRight.TextureCoordinate.Y, ref vertexBottomRight.TextureCoordinate.Y);
  100. }
  101. _vertices.Add(vertexTopLeft);
  102. _vertices.Add(vertexTopRight);
  103. _vertices.Add(vertexBottomLeft);
  104. _vertices.Add(vertexBottomRight);
  105. Debug.Assert(Vertices.Count <= TiledMapHelper.MaximumVerticesPerModel);
  106. }
  107. public void AddTileIndices()
  108. {
  109. var indexOffset = Vertices.Count;
  110. Debug.Assert(3 + indexOffset <= TiledMapHelper.MaximumVerticesPerModel);
  111. _indices.Add((ushort)(0 + indexOffset));
  112. _indices.Add((ushort)(1 + indexOffset));
  113. _indices.Add((ushort)(2 + indexOffset));
  114. _indices.Add((ushort)(1 + indexOffset));
  115. _indices.Add((ushort)(3 + indexOffset));
  116. _indices.Add((ushort)(2 + indexOffset));
  117. Debug.Assert(Indices.Count <= TiledMapHelper.MaximumIndicesPerModel);
  118. }
  119. }