test_path_follow_2d.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /**************************************************************************/
  2. /* test_path_follow_2d.h */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #ifndef TEST_PATH_FOLLOW_2D_H
  31. #define TEST_PATH_FOLLOW_2D_H
  32. #include "scene/2d/path_2d.h"
  33. #include "scene/main/window.h"
  34. #include "tests/test_macros.h"
  35. namespace TestPathFollow2D {
  36. bool is_equal_approx(const Vector2 &p_a, const Vector2 &p_b) {
  37. const real_t tolerance = 0.001;
  38. return Math::is_equal_approx(p_a.x, p_b.x, tolerance) &&
  39. Math::is_equal_approx(p_a.y, p_b.y, tolerance);
  40. }
  41. TEST_CASE("[SceneTree][PathFollow2D] Sampling with progress ratio") {
  42. Ref<Curve2D> curve = memnew(Curve2D);
  43. curve->set_bake_interval(1);
  44. curve->add_point(Vector2(0, 0));
  45. curve->add_point(Vector2(100, 0));
  46. curve->add_point(Vector2(100, 100));
  47. curve->add_point(Vector2(0, 100));
  48. curve->add_point(Vector2(0, 0));
  49. Path2D *path = memnew(Path2D);
  50. path->set_curve(curve);
  51. PathFollow2D *path_follow_2d = memnew(PathFollow2D);
  52. path_follow_2d->set_loop(false);
  53. path->add_child(path_follow_2d);
  54. SceneTree::get_singleton()->get_root()->add_child(path);
  55. path_follow_2d->set_progress_ratio(0);
  56. CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
  57. path_follow_2d->set_progress_ratio(0.125);
  58. CHECK(is_equal_approx(Vector2(50, 0), path_follow_2d->get_transform().get_origin()));
  59. path_follow_2d->set_progress_ratio(0.25);
  60. CHECK(is_equal_approx(Vector2(100, 0), path_follow_2d->get_transform().get_origin()));
  61. path_follow_2d->set_progress_ratio(0.375);
  62. CHECK(is_equal_approx(Vector2(100, 50), path_follow_2d->get_transform().get_origin()));
  63. path_follow_2d->set_progress_ratio(0.5);
  64. CHECK(is_equal_approx(Vector2(100, 100), path_follow_2d->get_transform().get_origin()));
  65. path_follow_2d->set_progress_ratio(0.625);
  66. CHECK(is_equal_approx(Vector2(50, 100), path_follow_2d->get_transform().get_origin()));
  67. path_follow_2d->set_progress_ratio(0.75);
  68. CHECK(is_equal_approx(Vector2(0, 100), path_follow_2d->get_transform().get_origin()));
  69. path_follow_2d->set_progress_ratio(0.875);
  70. CHECK(is_equal_approx(Vector2(0, 50), path_follow_2d->get_transform().get_origin()));
  71. path_follow_2d->set_progress_ratio(1);
  72. CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
  73. memdelete(path);
  74. }
  75. TEST_CASE("[SceneTree][PathFollow2D] Sampling with progress") {
  76. Ref<Curve2D> curve = memnew(Curve2D);
  77. curve->set_bake_interval(1);
  78. curve->add_point(Vector2(0, 0));
  79. curve->add_point(Vector2(100, 0));
  80. curve->add_point(Vector2(100, 100));
  81. curve->add_point(Vector2(0, 100));
  82. curve->add_point(Vector2(0, 0));
  83. Path2D *path = memnew(Path2D);
  84. path->set_curve(curve);
  85. PathFollow2D *path_follow_2d = memnew(PathFollow2D);
  86. path_follow_2d->set_loop(false);
  87. path->add_child(path_follow_2d);
  88. SceneTree::get_singleton()->get_root()->add_child(path);
  89. path_follow_2d->set_progress(0);
  90. CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
  91. path_follow_2d->set_progress(50);
  92. CHECK(is_equal_approx(Vector2(50, 0), path_follow_2d->get_transform().get_origin()));
  93. path_follow_2d->set_progress(100);
  94. CHECK(is_equal_approx(Vector2(100, 0), path_follow_2d->get_transform().get_origin()));
  95. path_follow_2d->set_progress(150);
  96. CHECK(is_equal_approx(Vector2(100, 50), path_follow_2d->get_transform().get_origin()));
  97. path_follow_2d->set_progress(200);
  98. CHECK(is_equal_approx(Vector2(100, 100), path_follow_2d->get_transform().get_origin()));
  99. path_follow_2d->set_progress(250);
  100. CHECK(is_equal_approx(Vector2(50, 100), path_follow_2d->get_transform().get_origin()));
  101. path_follow_2d->set_progress(300);
  102. CHECK(is_equal_approx(Vector2(0, 100), path_follow_2d->get_transform().get_origin()));
  103. path_follow_2d->set_progress(350);
  104. CHECK(is_equal_approx(Vector2(0, 50), path_follow_2d->get_transform().get_origin()));
  105. path_follow_2d->set_progress(400);
  106. CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
  107. memdelete(path);
  108. }
  109. TEST_CASE("[SceneTree][PathFollow2D] Removal of a point in curve") {
  110. Ref<Curve2D> curve = memnew(Curve2D);
  111. curve->add_point(Vector2(0, 0));
  112. curve->add_point(Vector2(100, 0));
  113. curve->add_point(Vector2(100, 100));
  114. Path2D *path = memnew(Path2D);
  115. path->set_curve(curve);
  116. PathFollow2D *path_follow_2d = memnew(PathFollow2D);
  117. path->add_child(path_follow_2d);
  118. SceneTree::get_singleton()->get_root()->add_child(path);
  119. path_follow_2d->set_progress_ratio(0.5);
  120. CHECK(is_equal_approx(Vector2(100, 0), path_follow_2d->get_transform().get_origin()));
  121. curve->remove_point(1);
  122. path_follow_2d->set_progress_ratio(0.5);
  123. CHECK_MESSAGE(
  124. is_equal_approx(Vector2(50, 50), path_follow_2d->get_transform().get_origin()),
  125. "Path follow's position should be updated after removing a point from the curve");
  126. memdelete(path);
  127. }
  128. TEST_CASE("[SceneTree][PathFollow2D] Setting h_offset and v_offset") {
  129. Ref<Curve2D> curve = memnew(Curve2D);
  130. curve->add_point(Vector2(0, 0));
  131. curve->add_point(Vector2(100, 0));
  132. Path2D *path = memnew(Path2D);
  133. path->set_curve(curve);
  134. PathFollow2D *path_follow_2d = memnew(PathFollow2D);
  135. path->add_child(path_follow_2d);
  136. SceneTree::get_singleton()->get_root()->add_child(path);
  137. path_follow_2d->set_progress_ratio(0.5);
  138. CHECK(is_equal_approx(Vector2(50, 0), path_follow_2d->get_transform().get_origin()));
  139. path_follow_2d->set_h_offset(25);
  140. CHECK(is_equal_approx(Vector2(75, 0), path_follow_2d->get_transform().get_origin()));
  141. path_follow_2d->set_v_offset(25);
  142. CHECK(is_equal_approx(Vector2(75, 25), path_follow_2d->get_transform().get_origin()));
  143. memdelete(path);
  144. }
  145. TEST_CASE("[SceneTree][PathFollow2D] Progress ratio out of range") {
  146. Ref<Curve2D> curve = memnew(Curve2D);
  147. curve->add_point(Vector2(0, 0));
  148. curve->add_point(Vector2(100, 0));
  149. Path2D *path = memnew(Path2D);
  150. path->set_curve(curve);
  151. PathFollow2D *path_follow_2d = memnew(PathFollow2D);
  152. path->add_child(path_follow_2d);
  153. SceneTree::get_singleton()->get_root()->add_child(path);
  154. path_follow_2d->set_loop(true);
  155. path_follow_2d->set_progress_ratio(-0.3);
  156. CHECK_MESSAGE(
  157. Math::is_equal_approx(path_follow_2d->get_progress_ratio(), (real_t)0.7),
  158. "Progress Ratio should loop back from the end in the opposite direction");
  159. path_follow_2d->set_progress_ratio(1.3);
  160. CHECK_MESSAGE(
  161. Math::is_equal_approx(path_follow_2d->get_progress_ratio(), (real_t)0.3),
  162. "Progress Ratio should loop back from the end in the opposite direction");
  163. path_follow_2d->set_loop(false);
  164. path_follow_2d->set_progress_ratio(-0.3);
  165. CHECK_MESSAGE(
  166. Math::is_equal_approx(path_follow_2d->get_progress_ratio(), 0),
  167. "Progress Ratio should be clamped at 0");
  168. path_follow_2d->set_progress_ratio(1.3);
  169. CHECK_MESSAGE(
  170. Math::is_equal_approx(path_follow_2d->get_progress_ratio(), 1),
  171. "Progress Ratio should be clamped at 1");
  172. memdelete(path);
  173. }
  174. TEST_CASE("[SceneTree][PathFollow2D] Progress out of range") {
  175. Ref<Curve2D> curve = memnew(Curve2D);
  176. curve->add_point(Vector2(0, 0));
  177. curve->add_point(Vector2(100, 0));
  178. Path2D *path = memnew(Path2D);
  179. path->set_curve(curve);
  180. PathFollow2D *path_follow_2d = memnew(PathFollow2D);
  181. path->add_child(path_follow_2d);
  182. SceneTree::get_singleton()->get_root()->add_child(path);
  183. path_follow_2d->set_loop(true);
  184. path_follow_2d->set_progress(-50);
  185. CHECK_MESSAGE(
  186. Math::is_equal_approx(path_follow_2d->get_progress(), 50),
  187. "Progress should loop back from the end in the opposite direction");
  188. path_follow_2d->set_progress(150);
  189. CHECK_MESSAGE(
  190. Math::is_equal_approx(path_follow_2d->get_progress(), 50),
  191. "Progress should loop back from the end in the opposite direction");
  192. path_follow_2d->set_loop(false);
  193. path_follow_2d->set_progress(-50);
  194. CHECK_MESSAGE(
  195. Math::is_equal_approx(path_follow_2d->get_progress(), 0),
  196. "Progress should be clamped at 0");
  197. path_follow_2d->set_progress(150);
  198. CHECK_MESSAGE(
  199. Math::is_equal_approx(path_follow_2d->get_progress(), 100),
  200. "Progress should be clamped at 1");
  201. memdelete(path);
  202. }
  203. } // namespace TestPathFollow2D
  204. #endif // TEST_PATH_FOLLOW_2D_H