Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/scene/test_path_follow_2d.cpp
45987 views
1
/**************************************************************************/
2
/* test_path_follow_2d.cpp */
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
31
#include "tests/test_macros.h"
32
33
TEST_FORCE_LINK(test_path_follow_2d)
34
35
#include "scene/2d/path_2d.h"
36
#include "scene/main/scene_tree.h"
37
#include "scene/main/window.h"
38
39
namespace TestPathFollow2D {
40
41
bool is_equal_approx(const Vector2 &p_a, const Vector2 &p_b) {
42
const real_t tolerance = 0.001;
43
return Math::is_equal_approx(p_a.x, p_b.x, tolerance) &&
44
Math::is_equal_approx(p_a.y, p_b.y, tolerance);
45
}
46
47
TEST_CASE("[SceneTree][PathFollow2D] Sampling with progress ratio") {
48
Ref<Curve2D> curve = memnew(Curve2D);
49
curve->set_bake_interval(1);
50
curve->add_point(Vector2(0, 0));
51
curve->add_point(Vector2(100, 0));
52
curve->add_point(Vector2(100, 100));
53
curve->add_point(Vector2(0, 100));
54
curve->add_point(Vector2(0, 0));
55
Path2D *path = memnew(Path2D);
56
path->set_curve(curve);
57
PathFollow2D *path_follow_2d = memnew(PathFollow2D);
58
path_follow_2d->set_loop(false);
59
path->add_child(path_follow_2d);
60
SceneTree::get_singleton()->get_root()->add_child(path);
61
62
path_follow_2d->set_progress_ratio(0);
63
CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
64
65
path_follow_2d->set_progress_ratio(0.125);
66
CHECK(is_equal_approx(Vector2(50, 0), path_follow_2d->get_transform().get_origin()));
67
68
path_follow_2d->set_progress_ratio(0.25);
69
CHECK(is_equal_approx(Vector2(100, 0), path_follow_2d->get_transform().get_origin()));
70
71
path_follow_2d->set_progress_ratio(0.375);
72
CHECK(is_equal_approx(Vector2(100, 50), path_follow_2d->get_transform().get_origin()));
73
74
path_follow_2d->set_progress_ratio(0.5);
75
CHECK(is_equal_approx(Vector2(100, 100), path_follow_2d->get_transform().get_origin()));
76
77
path_follow_2d->set_progress_ratio(0.625);
78
CHECK(is_equal_approx(Vector2(50, 100), path_follow_2d->get_transform().get_origin()));
79
80
path_follow_2d->set_progress_ratio(0.75);
81
CHECK(is_equal_approx(Vector2(0, 100), path_follow_2d->get_transform().get_origin()));
82
83
path_follow_2d->set_progress_ratio(0.875);
84
CHECK(is_equal_approx(Vector2(0, 50), path_follow_2d->get_transform().get_origin()));
85
86
path_follow_2d->set_progress_ratio(1);
87
CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
88
89
memdelete(path);
90
}
91
92
TEST_CASE("[SceneTree][PathFollow2D] Sampling with progress") {
93
Ref<Curve2D> curve = memnew(Curve2D);
94
curve->set_bake_interval(1);
95
curve->add_point(Vector2(0, 0));
96
curve->add_point(Vector2(100, 0));
97
curve->add_point(Vector2(100, 100));
98
curve->add_point(Vector2(0, 100));
99
curve->add_point(Vector2(0, 0));
100
Path2D *path = memnew(Path2D);
101
path->set_curve(curve);
102
PathFollow2D *path_follow_2d = memnew(PathFollow2D);
103
path_follow_2d->set_loop(false);
104
path->add_child(path_follow_2d);
105
SceneTree::get_singleton()->get_root()->add_child(path);
106
107
path_follow_2d->set_progress(0);
108
CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
109
110
path_follow_2d->set_progress(50);
111
CHECK(is_equal_approx(Vector2(50, 0), path_follow_2d->get_transform().get_origin()));
112
113
path_follow_2d->set_progress(100);
114
CHECK(is_equal_approx(Vector2(100, 0), path_follow_2d->get_transform().get_origin()));
115
116
path_follow_2d->set_progress(150);
117
CHECK(is_equal_approx(Vector2(100, 50), path_follow_2d->get_transform().get_origin()));
118
119
path_follow_2d->set_progress(200);
120
CHECK(is_equal_approx(Vector2(100, 100), path_follow_2d->get_transform().get_origin()));
121
122
path_follow_2d->set_progress(250);
123
CHECK(is_equal_approx(Vector2(50, 100), path_follow_2d->get_transform().get_origin()));
124
125
path_follow_2d->set_progress(300);
126
CHECK(is_equal_approx(Vector2(0, 100), path_follow_2d->get_transform().get_origin()));
127
128
path_follow_2d->set_progress(350);
129
CHECK(is_equal_approx(Vector2(0, 50), path_follow_2d->get_transform().get_origin()));
130
131
path_follow_2d->set_progress(400);
132
CHECK(is_equal_approx(Vector2(0, 0), path_follow_2d->get_transform().get_origin()));
133
134
memdelete(path);
135
}
136
137
TEST_CASE("[SceneTree][PathFollow2D] Removal of a point in curve") {
138
Ref<Curve2D> curve = memnew(Curve2D);
139
curve->add_point(Vector2(0, 0));
140
curve->add_point(Vector2(100, 0));
141
curve->add_point(Vector2(100, 100));
142
Path2D *path = memnew(Path2D);
143
path->set_curve(curve);
144
PathFollow2D *path_follow_2d = memnew(PathFollow2D);
145
path->add_child(path_follow_2d);
146
SceneTree::get_singleton()->get_root()->add_child(path);
147
148
path_follow_2d->set_progress_ratio(0.5);
149
CHECK(is_equal_approx(Vector2(100, 0), path_follow_2d->get_transform().get_origin()));
150
151
curve->remove_point(1);
152
153
path_follow_2d->set_progress_ratio(0.5);
154
CHECK_MESSAGE(
155
is_equal_approx(Vector2(50, 50), path_follow_2d->get_transform().get_origin()),
156
"Path follow's position should be updated after removing a point from the curve");
157
158
memdelete(path);
159
}
160
161
TEST_CASE("[SceneTree][PathFollow2D] Setting h_offset and v_offset") {
162
Ref<Curve2D> curve = memnew(Curve2D);
163
curve->add_point(Vector2(0, 0));
164
curve->add_point(Vector2(100, 0));
165
Path2D *path = memnew(Path2D);
166
path->set_curve(curve);
167
PathFollow2D *path_follow_2d = memnew(PathFollow2D);
168
path->add_child(path_follow_2d);
169
SceneTree::get_singleton()->get_root()->add_child(path);
170
171
path_follow_2d->set_progress_ratio(0.5);
172
CHECK(is_equal_approx(Vector2(50, 0), path_follow_2d->get_transform().get_origin()));
173
174
path_follow_2d->set_h_offset(25);
175
CHECK(is_equal_approx(Vector2(75, 0), path_follow_2d->get_transform().get_origin()));
176
177
path_follow_2d->set_v_offset(25);
178
CHECK(is_equal_approx(Vector2(75, 25), path_follow_2d->get_transform().get_origin()));
179
180
memdelete(path);
181
}
182
183
TEST_CASE("[SceneTree][PathFollow2D] Progress ratio out of range") {
184
Ref<Curve2D> curve = memnew(Curve2D);
185
curve->add_point(Vector2(0, 0));
186
curve->add_point(Vector2(100, 0));
187
Path2D *path = memnew(Path2D);
188
path->set_curve(curve);
189
PathFollow2D *path_follow_2d = memnew(PathFollow2D);
190
path->add_child(path_follow_2d);
191
SceneTree::get_singleton()->get_root()->add_child(path);
192
193
path_follow_2d->set_loop(true);
194
195
path_follow_2d->set_progress_ratio(-0.3);
196
CHECK_MESSAGE(
197
Math::is_equal_approx(path_follow_2d->get_progress_ratio(), (real_t)0.7),
198
"Progress Ratio should loop back from the end in the opposite direction");
199
200
path_follow_2d->set_progress_ratio(1.3);
201
CHECK_MESSAGE(
202
Math::is_equal_approx(path_follow_2d->get_progress_ratio(), (real_t)0.3),
203
"Progress Ratio should loop back from the end in the opposite direction");
204
205
path_follow_2d->set_loop(false);
206
207
path_follow_2d->set_progress_ratio(-0.3);
208
CHECK_MESSAGE(
209
Math::is_equal_approx(path_follow_2d->get_progress_ratio(), 0),
210
"Progress Ratio should be clamped at 0");
211
212
path_follow_2d->set_progress_ratio(1.3);
213
CHECK_MESSAGE(
214
Math::is_equal_approx(path_follow_2d->get_progress_ratio(), 1),
215
"Progress Ratio should be clamped at 1");
216
217
memdelete(path);
218
}
219
220
TEST_CASE("[SceneTree][PathFollow2D] Progress out of range") {
221
Ref<Curve2D> curve = memnew(Curve2D);
222
curve->add_point(Vector2(0, 0));
223
curve->add_point(Vector2(100, 0));
224
Path2D *path = memnew(Path2D);
225
path->set_curve(curve);
226
PathFollow2D *path_follow_2d = memnew(PathFollow2D);
227
path->add_child(path_follow_2d);
228
SceneTree::get_singleton()->get_root()->add_child(path);
229
230
path_follow_2d->set_loop(true);
231
232
path_follow_2d->set_progress(-50);
233
CHECK_MESSAGE(
234
Math::is_equal_approx(path_follow_2d->get_progress(), 50),
235
"Progress should loop back from the end in the opposite direction");
236
237
path_follow_2d->set_progress(150);
238
CHECK_MESSAGE(
239
Math::is_equal_approx(path_follow_2d->get_progress(), 50),
240
"Progress should loop back from the end in the opposite direction");
241
242
path_follow_2d->set_loop(false);
243
244
path_follow_2d->set_progress(-50);
245
CHECK_MESSAGE(
246
Math::is_equal_approx(path_follow_2d->get_progress(), 0),
247
"Progress should be clamped at 0");
248
249
path_follow_2d->set_progress(150);
250
CHECK_MESSAGE(
251
Math::is_equal_approx(path_follow_2d->get_progress(), 100),
252
"Progress should be clamped at 1");
253
254
memdelete(path);
255
}
256
257
} // namespace TestPathFollow2D
258
259