Basis25D.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. using Godot;
  2. using System;
  3. using System.Runtime.InteropServices;
  4. #if GODOT_REAL_T_IS_DOUBLE
  5. using real_t = System.Double;
  6. #else
  7. using real_t = System.Single;
  8. #endif
  9. /// <summary>
  10. /// Basis25D structure for performing 2.5D transform math.
  11. /// Note: All code assumes that Y is UP in 3D, and DOWN in 2D.
  12. /// A top-down view has a Y axis component of (0, 0), with a Z axis component of (0, 1).
  13. /// For a front side view, Y is (0, -1) and Z is (0, 0).
  14. /// Remember that Godot's 2D mode has the Y axis pointing DOWN on the screen.
  15. /// </summary>
  16. [Serializable]
  17. [StructLayout(LayoutKind.Sequential)]
  18. public struct Basis25D : IEquatable<Basis25D>
  19. {
  20. // Also matrix columns, the directions to move on screen for each unit change in 3D.
  21. public Vector2 x;
  22. public Vector2 y;
  23. public Vector2 z;
  24. // Also matrix rows, the parts of each vector that contribute to moving in a screen direction.
  25. // Setting a row to zero means no movement in that direction.
  26. public Vector3 Row0
  27. {
  28. get { return new Vector3(x.x, y.x, z.x); }
  29. set
  30. {
  31. x.x = value.x;
  32. y.x = value.y;
  33. z.x = value.z;
  34. }
  35. }
  36. public Vector3 Row1
  37. {
  38. get { return new Vector3(x.y, y.y, z.y); }
  39. set
  40. {
  41. x.y = value.x;
  42. y.y = value.y;
  43. z.y = value.z;
  44. }
  45. }
  46. public Vector2 this[int columnIndex]
  47. {
  48. get
  49. {
  50. switch (columnIndex)
  51. {
  52. case 0: return x;
  53. case 1: return y;
  54. case 2: return z;
  55. default: throw new IndexOutOfRangeException();
  56. }
  57. }
  58. set
  59. {
  60. switch (columnIndex)
  61. {
  62. case 0: x = value; return;
  63. case 1: y = value; return;
  64. case 2: z = value; return;
  65. default: throw new IndexOutOfRangeException();
  66. }
  67. }
  68. }
  69. public real_t this[int columnIndex, int rowIndex]
  70. {
  71. get
  72. {
  73. return this[columnIndex][rowIndex];
  74. }
  75. set
  76. {
  77. Vector2 v = this[columnIndex];
  78. v[rowIndex] = value;
  79. this[columnIndex] = v;
  80. }
  81. }
  82. private static readonly Basis25D _topDown = new Basis25D(1, 0, 0, 0, 0, 1);
  83. private static readonly Basis25D _frontSide = new Basis25D(1, 0, 0, -1, 0, 0);
  84. private static readonly Basis25D _fortyFive = new Basis25D(1, 0, 0, -0.70710678118f, 0, 0.70710678118f);
  85. private static readonly Basis25D _isometric = new Basis25D(0.86602540378f, 0.5f, 0, -1, -0.86602540378f, 0.5f);
  86. private static readonly Basis25D _obliqueY = new Basis25D(1, 0, -0.70710678118f, -0.70710678118f, 0, 1);
  87. private static readonly Basis25D _obliqueZ = new Basis25D(1, 0, 0, -1, -0.70710678118f, 0.70710678118f);
  88. public static Basis25D TopDown { get { return _topDown; } }
  89. public static Basis25D FrontSide { get { return _frontSide; } }
  90. public static Basis25D FortyFive { get { return _fortyFive; } }
  91. public static Basis25D Isometric { get { return _isometric; } }
  92. public static Basis25D ObliqueY { get { return _obliqueY; } }
  93. public static Basis25D ObliqueZ { get { return _obliqueZ; } }
  94. /// <summary>
  95. /// Creates a Dimetric Basis25D from the angle between the Y axis and the others.
  96. /// Dimetric(Tau/3) or Dimetric(2.09439510239) is the same as Isometric.
  97. /// Try to keep this number away from a multiple of Tau/4 (or Pi/2) radians.
  98. /// </summary>
  99. /// <param name="angle">The angle, in radians, between the Y axis and the X/Z axes.</param>
  100. public static Basis25D Dimetric(real_t angle)
  101. {
  102. real_t sin = Mathf.Sin(angle);
  103. real_t cos = Mathf.Cos(angle);
  104. return new Basis25D(sin, -cos, 0, -1, -sin, -cos);
  105. }
  106. // Constructors
  107. public Basis25D(Basis25D b)
  108. {
  109. x = b.x;
  110. y = b.y;
  111. z = b.z;
  112. }
  113. public Basis25D(Vector2 xAxis, Vector2 yAxis, Vector2 zAxis)
  114. {
  115. x = xAxis;
  116. y = yAxis;
  117. z = zAxis;
  118. }
  119. public Basis25D(real_t xx, real_t xy, real_t yx, real_t yy, real_t zx, real_t zy)
  120. {
  121. x = new Vector2(xx, xy);
  122. y = new Vector2(yx, yy);
  123. z = new Vector2(zx, zy);
  124. }
  125. public static Basis25D operator *(Basis25D b, real_t s)
  126. {
  127. b.x *= s;
  128. b.y *= s;
  129. b.z *= s;
  130. return b;
  131. }
  132. public static Basis25D operator /(Basis25D b, real_t s)
  133. {
  134. b.x /= s;
  135. b.y /= s;
  136. b.z /= s;
  137. return b;
  138. }
  139. public static bool operator ==(Basis25D left, Basis25D right)
  140. {
  141. return left.Equals(right);
  142. }
  143. public static bool operator !=(Basis25D left, Basis25D right)
  144. {
  145. return !left.Equals(right);
  146. }
  147. public override bool Equals(object obj)
  148. {
  149. if (obj is Basis25D)
  150. {
  151. return Equals((Basis25D)obj);
  152. }
  153. return false;
  154. }
  155. public bool Equals(Basis25D other)
  156. {
  157. return x.Equals(other.x) && y.Equals(other.y) && z.Equals(other.z);
  158. }
  159. public bool IsEqualApprox(Basis25D other)
  160. {
  161. return x.IsEqualApprox(other.x) && y.IsEqualApprox(other.y) && z.IsEqualApprox(other.z);
  162. }
  163. public override int GetHashCode()
  164. {
  165. return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode();
  166. }
  167. public override string ToString()
  168. {
  169. string s = String.Format("({0}, {1}, {2})", new object[]
  170. {
  171. x.ToString(),
  172. y.ToString(),
  173. z.ToString()
  174. });
  175. return s;
  176. }
  177. public string ToString(string format)
  178. {
  179. string s = String.Format("({0}, {1}, {2})", new object[]
  180. {
  181. x.ToString(format),
  182. y.ToString(format),
  183. z.ToString(format)
  184. });
  185. return s;
  186. }
  187. }