Node25D.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using Godot;
  2. using System;
  3. #if REAL_T_IS_DOUBLE
  4. using real_t = System.Double;
  5. #else
  6. using real_t = System.Single;
  7. #endif
  8. /// <summary>
  9. /// This node converts a 3D position to 2D using a 2.5D transformation matrix.
  10. /// The transformation of its 2D form is controlled by its 3D child.
  11. /// </summary>
  12. [Tool]
  13. public partial class Node25D : Node2D, IComparable<Node25D>
  14. {
  15. /// <summary>
  16. /// The number of 2D units in one 3D unit. Ideally, but not necessarily, an integer.
  17. /// </summary>
  18. public const int SCALE = 32;
  19. [Export] public Vector3 spatialPosition
  20. {
  21. get
  22. {
  23. if (spatialNode == null)
  24. {
  25. spatialNode = GetChild<Node3D>(0);
  26. }
  27. return spatialNode.Position;
  28. }
  29. set
  30. {
  31. transform25D.spatialPosition = value;
  32. if (spatialNode != null)
  33. {
  34. spatialNode.Position = value;
  35. }
  36. else if (GetChildCount() > 0)
  37. {
  38. spatialNode = GetChild<Node3D>(0);
  39. }
  40. }
  41. }
  42. private Node3D spatialNode;
  43. private Transform25D transform25D;
  44. public Basis25D Basis25D
  45. {
  46. get { return transform25D.basis; }
  47. }
  48. public Transform25D Transform25D
  49. {
  50. get { return transform25D; }
  51. }
  52. public override void _Ready()
  53. {
  54. Node25DReady();
  55. }
  56. public override void _Process(real_t delta)
  57. {
  58. Node25DProcess();
  59. }
  60. /// <summary>
  61. /// Call this method in _Ready, or before Node25DProcess is run.
  62. /// </summary>
  63. protected void Node25DReady()
  64. {
  65. if (GetChildCount() > 0)
  66. {
  67. spatialNode = GetChild<Node3D>(0);
  68. }
  69. // Changing the basis here will change the default for all Node25D instances.
  70. transform25D = new Transform25D(Basis25D.FortyFive * SCALE);
  71. }
  72. /// <summary>
  73. /// Call this method in _Process, or whenever the position of this object changes.
  74. /// </summary>
  75. protected void Node25DProcess()
  76. {
  77. if (transform25D.basis == new Basis25D())
  78. {
  79. SetViewMode(0);
  80. }
  81. CheckViewMode();
  82. if (spatialNode != null)
  83. {
  84. transform25D.spatialPosition = spatialNode.Position;
  85. }
  86. else if (GetChildCount() > 0)
  87. {
  88. spatialNode = GetChild<Node3D>(0);
  89. }
  90. GlobalPosition = transform25D.FlatPosition;
  91. }
  92. public void SetViewMode(int viewModeIndex)
  93. {
  94. switch (viewModeIndex)
  95. {
  96. case 0:
  97. transform25D.basis = Basis25D.FortyFive * SCALE;
  98. break;
  99. case 1:
  100. transform25D.basis = Basis25D.Isometric * SCALE;
  101. break;
  102. case 2:
  103. transform25D.basis = Basis25D.TopDown * SCALE;
  104. break;
  105. case 3:
  106. transform25D.basis = Basis25D.FrontSide * SCALE;
  107. break;
  108. case 4:
  109. transform25D.basis = Basis25D.ObliqueY * SCALE;
  110. break;
  111. case 5:
  112. transform25D.basis = Basis25D.ObliqueZ * SCALE;
  113. break;
  114. }
  115. }
  116. private void CheckViewMode()
  117. {
  118. if (!Engine.EditorHint)
  119. {
  120. if (Input.IsActionJustPressed("forty_five_mode"))
  121. {
  122. SetViewMode(0);
  123. }
  124. else if (Input.IsActionJustPressed("isometric_mode"))
  125. {
  126. SetViewMode(1);
  127. }
  128. else if (Input.IsActionJustPressed("top_down_mode"))
  129. {
  130. SetViewMode(2);
  131. }
  132. else if (Input.IsActionJustPressed("front_side_mode"))
  133. {
  134. SetViewMode(3);
  135. }
  136. else if (Input.IsActionJustPressed("oblique_y_mode"))
  137. {
  138. SetViewMode(4);
  139. }
  140. else if (Input.IsActionJustPressed("oblique_z_mode"))
  141. {
  142. SetViewMode(5);
  143. }
  144. }
  145. }
  146. public int CompareTo(object obj)
  147. {
  148. if (obj is Node25D)
  149. {
  150. return CompareTo((Node25D)obj);
  151. }
  152. return 1;
  153. }
  154. public int CompareTo(Node25D other)
  155. {
  156. real_t thisIndex = transform25D.spatialPosition.y + 0.001f * (transform25D.spatialPosition.x + transform25D.spatialPosition.z);
  157. real_t otherIndex = other.transform25D.spatialPosition.y + 0.001f * (other.transform25D.spatialPosition.x + other.transform25D.spatialPosition.z);
  158. real_t diff = thisIndex - otherIndex;
  159. if (diff > 0)
  160. {
  161. return 1;
  162. }
  163. if (diff < 0)
  164. {
  165. return -1;
  166. }
  167. return 0;
  168. }
  169. }