test_path_follow_3d.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*************************************************************************/
  2. /* test_path_follow_3d.h */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
  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_3D_H
  31. #define TEST_PATH_FOLLOW_3D_H
  32. #include "scene/3d/path_3d.h"
  33. #include "scene/resources/curve.h"
  34. #include "tests/test_macros.h"
  35. namespace TestPathFollow3D {
  36. TEST_CASE("[PathFollow3D] Sampling with unit offset") {
  37. const Ref<Curve3D> &curve = memnew(Curve3D());
  38. curve->add_point(Vector3(0, 0, 0));
  39. curve->add_point(Vector3(100, 0, 0));
  40. curve->add_point(Vector3(100, 100, 0));
  41. curve->add_point(Vector3(100, 100, 100));
  42. curve->add_point(Vector3(100, 0, 100));
  43. const Path3D *path = memnew(Path3D);
  44. path->set_curve(curve);
  45. const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
  46. path->add_child(path_follow_3d);
  47. path_follow_3d->set_unit_offset(0);
  48. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0));
  49. path_follow_3d->set_unit_offset(0.125);
  50. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0));
  51. path_follow_3d->set_unit_offset(0.25);
  52. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0);
  53. path_follow_3d->set_unit_offset(0.375);
  54. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0)));
  55. path_follow_3d->set_unit_offset(0.5);
  56. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0)));
  57. path_follow_3d->set_unit_offset(0.625);
  58. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50)));
  59. path_follow_3d->set_unit_offset(0.75);
  60. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100)));
  61. path_follow_3d->set_unit_offset(0.875);
  62. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100)));
  63. path_follow_3d->set_unit_offset(1);
  64. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100)));
  65. memdelete(path);
  66. }
  67. TEST_CASE("[PathFollow3D] Sampling with offset") {
  68. const Ref<Curve3D> &curve = memnew(Curve3D());
  69. curve->add_point(Vector3(0, 0, 0));
  70. curve->add_point(Vector3(100, 0, 0));
  71. curve->add_point(Vector3(100, 100, 0));
  72. curve->add_point(Vector3(100, 100, 100));
  73. curve->add_point(Vector3(100, 0, 100));
  74. const Path3D *path = memnew(Path3D);
  75. path->set_curve(curve);
  76. const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
  77. path->add_child(path_follow_3d);
  78. path_follow_3d->set_offset(0);
  79. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0));
  80. path_follow_3d->set_offset(50);
  81. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0));
  82. path_follow_3d->set_offset(100);
  83. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0);
  84. path_follow_3d->set_offset(150);
  85. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0)));
  86. path_follow_3d->set_offset(200);
  87. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0)));
  88. path_follow_3d->set_offset(250);
  89. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50)));
  90. path_follow_3d->set_offset(300);
  91. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100)));
  92. path_follow_3d->set_offset(350);
  93. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100)));
  94. path_follow_3d->set_offset(400);
  95. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100)));
  96. memdelete(path);
  97. }
  98. TEST_CASE("[PathFollow3D] Removal of a point in curve") {
  99. const Ref<Curve3D> &curve = memnew(Curve3D());
  100. curve->add_point(Vector3(0, 0, 0));
  101. curve->add_point(Vector3(100, 0, 0));
  102. curve->add_point(Vector3(100, 100, 0));
  103. const Path3D *path = memnew(Path3D);
  104. path->set_curve(curve);
  105. const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
  106. path->add_child(path_follow_3d);
  107. path_follow_3d->set_unit_offset(0.5);
  108. CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(100, 0, 0)));
  109. curve->remove_point(1);
  110. CHECK_MESSAGE(
  111. path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(50, 50, 0)),
  112. "Path follow's position should be updated after removing a point from the curve");
  113. memdelete(path);
  114. }
  115. TEST_CASE("[PathFollow3D] Unit offset out of range") {
  116. const Ref<Curve3D> &curve = memnew(Curve3D());
  117. curve->add_point(Vector3(0, 0, 0));
  118. curve->add_point(Vector3(100, 0, 0));
  119. const Path3D *path = memnew(Path3D);
  120. path->set_curve(curve);
  121. const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
  122. path->add_child(path_follow_3d);
  123. path_follow_3d->set_loop(true);
  124. path_follow_3d->set_unit_offset(-0.3);
  125. CHECK_MESSAGE(
  126. path_follow_3d->get_unit_offset() == 0.7,
  127. "Unit Offset should loop back from the end in the opposite direction");
  128. path_follow_3d->set_unit_offset(1.3);
  129. CHECK_MESSAGE(
  130. path_follow_3d->get_unit_offset() == 0.3,
  131. "Unit Offset should loop back from the end in the opposite direction");
  132. path_follow_3d->set_loop(false);
  133. path_follow_3d->set_unit_offset(-0.3);
  134. CHECK_MESSAGE(
  135. path_follow_3d->get_unit_offset() == 0,
  136. "Unit Offset should be clamped at 0");
  137. path_follow_3d->set_unit_offset(1.3);
  138. CHECK_MESSAGE(
  139. path_follow_3d->get_unit_offset() == 1,
  140. "Unit Offset should be clamped at 1");
  141. memdelete(path);
  142. }
  143. TEST_CASE("[PathFollow3D] Offset out of range") {
  144. const Ref<Curve3D> &curve = memnew(Curve3D());
  145. curve->add_point(Vector3(0, 0, 0));
  146. curve->add_point(Vector3(100, 0, 0));
  147. const Path3D *path = memnew(Path3D);
  148. path->set_curve(curve);
  149. const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
  150. path->add_child(path_follow_3d);
  151. path_follow_3d->set_loop(true);
  152. path_follow_3d->set_offset(-50);
  153. CHECK_MESSAGE(
  154. path_follow_3d->get_offset() == 50,
  155. "Offset should loop back from the end in the opposite direction");
  156. path_follow_3d->set_offset(150);
  157. CHECK_MESSAGE(
  158. path_follow_3d->get_offset() == 50,
  159. "Offset should loop back from the end in the opposite direction");
  160. path_follow_3d->set_loop(false);
  161. path_follow_3d->set_offset(-50);
  162. CHECK_MESSAGE(
  163. path_follow_3d->get_offset() == 0,
  164. "Offset should be clamped at 0");
  165. path_follow_3d->set_offset(150);
  166. CHECK_MESSAGE(
  167. path_follow_3d->get_offset() == 100,
  168. "Offset should be clamped at max value of curve");
  169. memdelete(path);
  170. }
  171. } // namespace TestPathFollow3D
  172. #endif // TEST_PATH_FOLLOW_3D_H