Texture2DRegion.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Graphics;
  7. namespace MonoGame.Extended.Graphics;
  8. /// <summary>
  9. /// Represents a region of a texture.
  10. /// </summary>
  11. public class Texture2DRegion
  12. {
  13. /// <summary>
  14. /// Gets the name assigned to this texture region when it was created.
  15. /// </summary>
  16. public string Name { get; }
  17. /// <summary>
  18. /// Gets the texture associated with this texture region.
  19. /// </summary>
  20. public Texture2D Texture { get; }
  21. /// <summary>
  22. /// Gets the top-left x-coordinate of the texture region within the texture.
  23. /// </summary>
  24. public int X { get; }
  25. /// <summary>
  26. /// Gets the top-left y-coordinate of the texture region within the texture.
  27. /// </summary>
  28. public int Y { get; }
  29. /// <summary>
  30. /// Gets the width, in pixels, of the texture region.
  31. /// </summary>
  32. public int Width { get; }
  33. /// <summary>
  34. /// Gets the height, in pixels, of the texture region.
  35. /// </summary>
  36. public int Height { get; }
  37. /// <summary>
  38. /// Gets the size of the texture region.
  39. /// </summary>
  40. public Size Size { get; }
  41. /// <summary>
  42. /// Gets or sets the user-defined data associated with this texture region.
  43. /// </summary>
  44. public object Tag { get; set; }
  45. /// <summary>
  46. /// Gets the bounds of the texture region within the texture.
  47. /// </summary>
  48. public Rectangle Bounds { get; }
  49. /// <summary>
  50. /// Gets the top UV coordinate of the texture region.
  51. /// </summary>
  52. public float TopUV { get; }
  53. /// <summary>
  54. /// Gets the right UV coordinate of the texture region.
  55. /// </summary>
  56. public float RightUV { get; }
  57. /// <summary>
  58. /// Gets the bottom UV coordinate of the texture region.
  59. /// </summary>
  60. public float BottomUV { get; }
  61. /// <summary>
  62. /// Gets the left UV coordinate of the texture region.
  63. /// </summary>
  64. public float LeftUV { get; }
  65. /// <summary>
  66. /// Gets a value indicating whether this texture region is rotated 90 degrees clockwise in the atlas.
  67. /// </summary>
  68. public bool IsRotated { get; }
  69. /// <summary>
  70. /// Gets the original size of the texture region before trimming.
  71. /// </summary>
  72. public Size OriginalSize { get; }
  73. /// <summary>
  74. /// Gets the offset between the top-left corner of the original sprite and the top-left corner of the trimmed sprite.
  75. /// </summary>
  76. public Vector2 Offset { get; }
  77. /// <summary>
  78. /// Gets the normalized origin point of the texture region, or null if no origin is specified.
  79. /// </summary>
  80. public Vector2? OriginNormalized { get; }
  81. /// <summary>
  82. /// Initializes a new instance of the <see cref="Texture2DRegion"/> class representing the entire texture.
  83. /// </summary>
  84. /// <param name="texture">The texture to create the region from.</param>
  85. /// <exception cref="ArgumentNullException">
  86. /// Thrown if <paramref name="texture"/> is <see langword="null"/>.
  87. /// </exception>
  88. /// <exception cref="ObjectDisposedException">
  89. /// Thrown if <paramref name="texture"/> has been disposed prior.
  90. /// </exception>
  91. public Texture2DRegion(Texture2D texture)
  92. : this(texture, 0, 0, texture.Width, texture.Height, null) { }
  93. /// <summary>
  94. /// Initializes a new instance of the <see cref="Texture2DRegion"/> class representing the entire texture with the
  95. /// specified name.
  96. /// </summary>
  97. /// <param name="texture">The texture to create the region from.</param>
  98. /// <param name="name">The name of the texture region.</param>
  99. /// <exception cref="ArgumentNullException">
  100. /// Thrown if <paramref name="texture"/> is <see langword="null"/>.
  101. /// </exception>
  102. /// <exception cref="ObjectDisposedException">
  103. /// Thrown if <paramref name="texture"/> has been disposed prior.
  104. /// </exception>
  105. public Texture2DRegion(Texture2D texture, string name)
  106. : this(texture, 0, 0, texture.Bounds.Width, texture.Bounds.Height, null) { }
  107. /// <summary>
  108. /// Initializes a new instance of the <see cref="Texture2DRegion"/> class with the specified region of the texture.
  109. /// </summary>
  110. /// <param name="texture">The texture to create the region from.</param>
  111. /// <param name="region">The region of the texture to use.</param>
  112. /// <exception cref="ArgumentNullException">
  113. /// Thrown if <paramref name="texture"/> is <see langword="null"/>.
  114. /// </exception>
  115. /// <exception cref="ObjectDisposedException">
  116. /// Thrown if <paramref name="texture"/> has been disposed prior.
  117. /// </exception>
  118. public Texture2DRegion(Texture2D texture, Rectangle region)
  119. : this(texture, region.X, region.Y, region.Width, region.Height, null) { }
  120. /// <summary>
  121. /// Initializes a new instance of the <see cref="Texture2DRegion"/> class with the specified region of the texture.
  122. /// </summary>
  123. /// <param name="texture">The texture to create the region from.</param>
  124. /// <param name="x">The top-left x-coordinate of the region within the texture.</param>
  125. /// <param name="y">The top-left y-coordinate of the region within the texture.</param>
  126. /// <param name="width">The width, in pixels, of the region.</param>
  127. /// <param name="height">The height, in pixels, of the region.</param>
  128. /// <exception cref="ArgumentNullException">
  129. /// Thrown if <paramref name="texture"/> is <see langword="null"/>.
  130. /// </exception>
  131. /// <exception cref="ObjectDisposedException">
  132. /// Thrown if <paramref name="texture"/> has been disposed prior.
  133. /// </exception>
  134. public Texture2DRegion(Texture2D texture, int x, int y, int width, int height)
  135. : this(texture, x, y, width, height, null) { }
  136. /// <summary>
  137. /// Initializes a new instance of the <see cref="Texture2DRegion"/> class with the specified region of the texture and
  138. /// name.
  139. /// </summary>
  140. /// <param name="texture">The texture to create the region from.</param>
  141. /// <param name="region">The region of the texture to use.</param>
  142. /// <param name="name">The name of the texture region.</param>
  143. /// <exception cref="ArgumentNullException">
  144. /// Thrown if <paramref name="texture"/> is <see langword="null"/>.
  145. /// </exception>
  146. /// <exception cref="ObjectDisposedException">
  147. /// Thrown if <paramref name="texture"/> has been disposed prior.
  148. /// </exception>
  149. public Texture2DRegion(Texture2D texture, Rectangle region, string name)
  150. : this(texture, region.X, region.Y, region.Width, region.Height, name) { }
  151. /// <summary>
  152. /// Initializes a new instance of the <see cref="Texture2DRegion"/> class with the specified region of the texture and
  153. /// name.
  154. /// </summary>
  155. /// <param name="texture">The texture to create the region from.</param>
  156. /// <param name="x">The top-left x-coordinate of the region within the texture.</param>
  157. /// <param name="y">The top-left y-coordinate of the region within the texture.</param>
  158. /// <param name="width">The width, in pixels, of the region.</param>
  159. /// <param name="height">The height, in pixels, of the region.</param>
  160. /// <param name="name">The name of the texture region.</param>
  161. /// <exception cref="ArgumentNullException">
  162. /// Thrown if <paramref name="texture"/> is <see langword="null"/>.
  163. /// </exception>
  164. /// <exception cref="ObjectDisposedException">
  165. /// Thrown if <paramref name="texture"/> has been disposed prior.
  166. /// </exception>
  167. public Texture2DRegion(Texture2D texture,int x, int y, int width, int height, string name)
  168. : this(texture, x, y, width, height, false, new Size(width, height), Vector2.Zero, null, name) { }
  169. /// <summary>
  170. /// Initializes a new instance of the <see cref="Texture2DRegion"/> class with the specified region of the texture,
  171. /// original size, offset, origin, and name.
  172. /// </summary>
  173. /// <param name="texture">The texture to create the region from.</param>
  174. /// <param name="x">The top-left x-coordinate of the region within the texture.</param>
  175. /// <param name="y">The top-left y-coordinate of the region within the texture.</param>
  176. /// <param name="width">The width, in pixels, of the region.</param>
  177. /// <param name="height">The height, in pixels, of the region.</param>
  178. /// <param name="isRotated">A value indicating whether this texture region is rotated 90 degrees clockwise in the atlas.</param>
  179. /// <param name="originalSize">The original size of the texture region before trimming.</param>
  180. /// <param name="offset">The offset between the top-left corner of the original sprite and the top-left corner of the trimmed sprite.</param>
  181. /// <param name="originNormalized">The origin point of the texture region, or null if no origin is specified.</param>
  182. /// <param name="name">The name of the texture region.</param>
  183. /// <exception cref="ArgumentNullException">
  184. /// Thrown if <paramref name="texture"/> is <see langword="null"/>.
  185. /// </exception>
  186. /// <exception cref="ObjectDisposedException">
  187. /// Thrown if <paramref name="texture"/> has been disposed prior.
  188. /// </exception>
  189. public Texture2DRegion(Texture2D texture, int x, int y, int width, int height, bool isRotated, Size originalSize, Vector2 offset, Vector2? originNormalized, string name)
  190. {
  191. ArgumentNullException.ThrowIfNull(texture);
  192. if (texture.IsDisposed)
  193. {
  194. throw new ObjectDisposedException(nameof(texture));
  195. }
  196. if (string.IsNullOrEmpty(name))
  197. {
  198. name = $"{texture.Name}";
  199. }
  200. Name = name;
  201. Texture = texture;
  202. X = x;
  203. Y = y;
  204. Width = width;
  205. Height = height;
  206. IsRotated = isRotated;
  207. OriginalSize = originalSize;
  208. Offset = offset;
  209. OriginNormalized = originNormalized;
  210. Bounds = new Rectangle(x, y, width, height);
  211. Size = new Size(width, height);
  212. TopUV = Bounds.Top / (float)texture.Height;
  213. RightUV = Bounds.Right / (float)texture.Width;
  214. BottomUV = Bounds.Bottom / (float)texture.Height;
  215. LeftUV = Bounds.Left / (float)texture.Width;
  216. }
  217. // Used for unit tests only
  218. internal Texture2DRegion(string name, Rectangle bounds) : this(name, bounds.X, bounds.Y, bounds.Width, bounds.Height) { }
  219. // Used for unit tests only
  220. internal Texture2DRegion(string name, int x, int y, int width, int height)
  221. {
  222. Name = name;
  223. Texture = null;
  224. X = x;
  225. Y = y;
  226. Width = width;
  227. Height = height;
  228. Bounds = new Rectangle(x, y, width, height);
  229. Size = new Size(width, height);
  230. OriginalSize = Size;
  231. Offset = Vector2.Zero;
  232. OriginNormalized = null;
  233. TopUV = Bounds.Top / 1.0f;
  234. RightUV = Bounds.Right / 1.0f;
  235. BottomUV = Bounds.Bottom / 1.0f;
  236. LeftUV = Bounds.Left / 1.0f;
  237. }
  238. /// <inheritdoc/>
  239. public override string ToString()
  240. {
  241. return $"{Name ?? string.Empty} {Bounds}";
  242. }
  243. }