Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/scene/test_camera_2d.h
10277 views
1
/**************************************************************************/
2
/* test_camera_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
31
#pragma once
32
33
#include "scene/2d/camera_2d.h"
34
#include "scene/main/viewport.h"
35
#include "scene/main/window.h"
36
#include "tests/test_macros.h"
37
38
namespace TestCamera2D {
39
40
TEST_CASE("[SceneTree][Camera2D] Getters and setters") {
41
Camera2D *test_camera = memnew(Camera2D);
42
43
SUBCASE("AnchorMode") {
44
test_camera->set_anchor_mode(Camera2D::AnchorMode::ANCHOR_MODE_FIXED_TOP_LEFT);
45
CHECK(test_camera->get_anchor_mode() == Camera2D::AnchorMode::ANCHOR_MODE_FIXED_TOP_LEFT);
46
test_camera->set_anchor_mode(Camera2D::AnchorMode::ANCHOR_MODE_DRAG_CENTER);
47
CHECK(test_camera->get_anchor_mode() == Camera2D::AnchorMode::ANCHOR_MODE_DRAG_CENTER);
48
}
49
50
SUBCASE("ProcessCallback") {
51
test_camera->set_process_callback(Camera2D::Camera2DProcessCallback::CAMERA2D_PROCESS_PHYSICS);
52
CHECK(test_camera->get_process_callback() == Camera2D::Camera2DProcessCallback::CAMERA2D_PROCESS_PHYSICS);
53
test_camera->set_process_callback(Camera2D::Camera2DProcessCallback::CAMERA2D_PROCESS_IDLE);
54
CHECK(test_camera->get_process_callback() == Camera2D::Camera2DProcessCallback::CAMERA2D_PROCESS_IDLE);
55
}
56
57
SUBCASE("Drag") {
58
constexpr float drag_left_margin = 0.8f;
59
constexpr float drag_top_margin = 0.8f;
60
constexpr float drag_right_margin = 0.8f;
61
constexpr float drag_bottom_margin = 0.8f;
62
constexpr float drag_horizontal_offset1 = 0.5f;
63
constexpr float drag_horizontal_offset2 = -0.5f;
64
constexpr float drag_vertical_offset1 = 0.5f;
65
constexpr float drag_vertical_offset2 = -0.5f;
66
test_camera->set_drag_margin(SIDE_LEFT, drag_left_margin);
67
CHECK(test_camera->get_drag_margin(SIDE_LEFT) == drag_left_margin);
68
test_camera->set_drag_margin(SIDE_TOP, drag_top_margin);
69
CHECK(test_camera->get_drag_margin(SIDE_TOP) == drag_top_margin);
70
test_camera->set_drag_margin(SIDE_RIGHT, drag_right_margin);
71
CHECK(test_camera->get_drag_margin(SIDE_RIGHT) == drag_right_margin);
72
test_camera->set_drag_margin(SIDE_BOTTOM, drag_bottom_margin);
73
CHECK(test_camera->get_drag_margin(SIDE_BOTTOM) == drag_bottom_margin);
74
test_camera->set_drag_horizontal_enabled(true);
75
CHECK(test_camera->is_drag_horizontal_enabled());
76
test_camera->set_drag_horizontal_enabled(false);
77
CHECK_FALSE(test_camera->is_drag_horizontal_enabled());
78
test_camera->set_drag_horizontal_offset(drag_horizontal_offset1);
79
CHECK(test_camera->get_drag_horizontal_offset() == drag_horizontal_offset1);
80
test_camera->set_drag_horizontal_offset(drag_horizontal_offset2);
81
CHECK(test_camera->get_drag_horizontal_offset() == drag_horizontal_offset2);
82
test_camera->set_drag_vertical_enabled(true);
83
CHECK(test_camera->is_drag_vertical_enabled());
84
test_camera->set_drag_vertical_enabled(false);
85
CHECK_FALSE(test_camera->is_drag_vertical_enabled());
86
test_camera->set_drag_vertical_offset(drag_vertical_offset1);
87
CHECK(test_camera->get_drag_vertical_offset() == drag_vertical_offset1);
88
test_camera->set_drag_vertical_offset(drag_vertical_offset2);
89
CHECK(test_camera->get_drag_vertical_offset() == drag_vertical_offset2);
90
}
91
92
SUBCASE("Drawing") {
93
test_camera->set_margin_drawing_enabled(true);
94
CHECK(test_camera->is_margin_drawing_enabled());
95
test_camera->set_margin_drawing_enabled(false);
96
CHECK_FALSE(test_camera->is_margin_drawing_enabled());
97
test_camera->set_limit_drawing_enabled(true);
98
CHECK(test_camera->is_limit_drawing_enabled());
99
test_camera->set_limit_drawing_enabled(false);
100
CHECK_FALSE(test_camera->is_limit_drawing_enabled());
101
test_camera->set_screen_drawing_enabled(true);
102
CHECK(test_camera->is_screen_drawing_enabled());
103
test_camera->set_screen_drawing_enabled(false);
104
CHECK_FALSE(test_camera->is_screen_drawing_enabled());
105
}
106
107
SUBCASE("Enabled") {
108
test_camera->set_enabled(true);
109
CHECK(test_camera->is_enabled());
110
test_camera->set_enabled(false);
111
CHECK_FALSE(test_camera->is_enabled());
112
}
113
114
SUBCASE("Rotation") {
115
constexpr float rotation_smoothing_speed = 20.0f;
116
test_camera->set_ignore_rotation(true);
117
CHECK(test_camera->is_ignoring_rotation());
118
test_camera->set_ignore_rotation(false);
119
CHECK_FALSE(test_camera->is_ignoring_rotation());
120
test_camera->set_rotation_smoothing_enabled(true);
121
CHECK(test_camera->is_rotation_smoothing_enabled());
122
test_camera->set_rotation_smoothing_speed(rotation_smoothing_speed);
123
CHECK(test_camera->get_rotation_smoothing_speed() == rotation_smoothing_speed);
124
}
125
126
SUBCASE("Zoom") {
127
const Vector2 zoom = Vector2(4, 4);
128
test_camera->set_zoom(zoom);
129
CHECK(test_camera->get_zoom() == zoom);
130
}
131
132
SUBCASE("Offset") {
133
const Vector2 offset = Vector2(100, 100);
134
test_camera->set_offset(offset);
135
CHECK(test_camera->get_offset() == offset);
136
}
137
138
SUBCASE("Limit") {
139
constexpr int limit_left = 100;
140
constexpr int limit_top = 100;
141
constexpr int limit_right = 100;
142
constexpr int limit_bottom = 100;
143
test_camera->set_limit_smoothing_enabled(true);
144
CHECK(test_camera->is_limit_smoothing_enabled());
145
test_camera->set_limit_smoothing_enabled(false);
146
CHECK_FALSE(test_camera->is_limit_smoothing_enabled());
147
test_camera->set_limit(SIDE_LEFT, limit_left);
148
CHECK(test_camera->get_limit(SIDE_LEFT) == limit_left);
149
test_camera->set_limit(SIDE_TOP, limit_top);
150
CHECK(test_camera->get_limit(SIDE_TOP) == limit_top);
151
test_camera->set_limit(SIDE_RIGHT, limit_right);
152
CHECK(test_camera->get_limit(SIDE_RIGHT) == limit_right);
153
test_camera->set_limit(SIDE_BOTTOM, limit_bottom);
154
CHECK(test_camera->get_limit(SIDE_BOTTOM) == limit_bottom);
155
}
156
157
SUBCASE("Position") {
158
constexpr float smoothing_speed = 20.0f;
159
test_camera->set_position_smoothing_enabled(true);
160
CHECK(test_camera->is_position_smoothing_enabled());
161
test_camera->set_position_smoothing_speed(smoothing_speed);
162
CHECK(test_camera->get_position_smoothing_speed() == smoothing_speed);
163
}
164
165
memdelete(test_camera);
166
}
167
168
TEST_CASE("[SceneTree][Camera2D] Camera positioning") {
169
SubViewport *mock_viewport = memnew(SubViewport);
170
Camera2D *test_camera = memnew(Camera2D);
171
172
mock_viewport->set_size(Vector2(400, 200));
173
SceneTree::get_singleton()->get_root()->add_child(mock_viewport);
174
mock_viewport->add_child(test_camera);
175
176
SUBCASE("Anchor mode") {
177
test_camera->set_anchor_mode(Camera2D::ANCHOR_MODE_DRAG_CENTER);
178
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(0, 0)));
179
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
180
181
test_camera->set_anchor_mode(Camera2D::ANCHOR_MODE_FIXED_TOP_LEFT);
182
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(200, 100)));
183
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
184
}
185
186
SUBCASE("Offset") {
187
test_camera->set_offset(Vector2(100, 100));
188
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(100, 100)));
189
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
190
191
test_camera->set_offset(Vector2(-100, 300));
192
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(-100, 300)));
193
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
194
195
test_camera->set_offset(Vector2(0, 0));
196
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(0, 0)));
197
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
198
}
199
200
SUBCASE("Limits") {
201
test_camera->set_limit(SIDE_LEFT, 100);
202
test_camera->set_limit(SIDE_TOP, 50);
203
204
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(300, 150)));
205
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
206
207
test_camera->set_limit(SIDE_LEFT, 0);
208
test_camera->set_limit(SIDE_TOP, 0);
209
210
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(200, 100)));
211
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
212
}
213
214
SUBCASE("Drag") {
215
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(0, 0)));
216
217
// horizontal
218
test_camera->set_drag_horizontal_enabled(true);
219
test_camera->set_drag_margin(SIDE_RIGHT, 0.5);
220
221
test_camera->set_position(Vector2(100, 100));
222
test_camera->force_update_scroll();
223
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 100)));
224
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(0, 100)));
225
test_camera->set_position(Vector2(101, 101));
226
test_camera->force_update_scroll();
227
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(1, 101)));
228
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(1, 101)));
229
230
// test align
231
test_camera->set_position(Vector2(0, 0));
232
test_camera->align();
233
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(0, 0)));
234
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(0, 0)));
235
236
// vertical
237
test_camera->set_drag_vertical_enabled(true);
238
test_camera->set_drag_horizontal_enabled(false);
239
test_camera->set_drag_margin(SIDE_TOP, 0.3);
240
241
test_camera->set_position(Vector2(200, -20));
242
test_camera->force_update_scroll();
243
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(200, 0)));
244
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(200, 0)));
245
test_camera->set_position(Vector2(250, -55));
246
test_camera->force_update_scroll();
247
CHECK(test_camera->get_camera_position().is_equal_approx(Vector2(250, -25)));
248
CHECK(test_camera->get_camera_screen_center().is_equal_approx(Vector2(250, -25)));
249
}
250
251
memdelete(test_camera);
252
memdelete(mock_viewport);
253
}
254
255
TEST_CASE("[SceneTree][Camera2D] Transforms") {
256
SubViewport *mock_viewport = memnew(SubViewport);
257
Camera2D *test_camera = memnew(Camera2D);
258
259
mock_viewport->set_size(Vector2(400, 200));
260
SceneTree::get_singleton()->get_root()->add_child(mock_viewport);
261
mock_viewport->add_child(test_camera);
262
263
SUBCASE("Default camera") {
264
Transform2D xform = mock_viewport->get_canvas_transform();
265
// x,y are basis vectors, origin = screen center
266
Transform2D test_xform = Transform2D(Vector2(1, 0), Vector2(0, 1), Vector2(200, 100));
267
CHECK(xform.is_equal_approx(test_xform));
268
}
269
270
SUBCASE("Zoom") {
271
test_camera->set_zoom(Vector2(0.5, 2));
272
Transform2D xform = mock_viewport->get_canvas_transform();
273
Transform2D test_xform = Transform2D(Vector2(0.5, 0), Vector2(0, 2), Vector2(200, 100));
274
CHECK(xform.is_equal_approx(test_xform));
275
276
test_camera->set_zoom(Vector2(10, 10));
277
xform = mock_viewport->get_canvas_transform();
278
test_xform = Transform2D(Vector2(10, 0), Vector2(0, 10), Vector2(200, 100));
279
CHECK(xform.is_equal_approx(test_xform));
280
281
test_camera->set_zoom(Vector2(1, 1));
282
xform = mock_viewport->get_canvas_transform();
283
test_xform = Transform2D(Vector2(1, 0), Vector2(0, 1), Vector2(200, 100));
284
CHECK(xform.is_equal_approx(test_xform));
285
}
286
287
SUBCASE("Rotation") {
288
test_camera->set_rotation(Math::PI / 2);
289
Transform2D xform = mock_viewport->get_canvas_transform();
290
Transform2D test_xform = Transform2D(Vector2(1, 0), Vector2(0, 1), Vector2(200, 100));
291
CHECK(xform.is_equal_approx(test_xform));
292
293
test_camera->set_ignore_rotation(false);
294
xform = mock_viewport->get_canvas_transform();
295
test_xform = Transform2D(Vector2(0, -1), Vector2(1, 0), Vector2(200, 100));
296
CHECK(xform.is_equal_approx(test_xform));
297
298
test_camera->set_rotation(-1 * Math::PI);
299
test_camera->force_update_scroll();
300
xform = mock_viewport->get_canvas_transform();
301
test_xform = Transform2D(Vector2(-1, 0), Vector2(0, -1), Vector2(200, 100));
302
CHECK(xform.is_equal_approx(test_xform));
303
304
test_camera->set_rotation(0);
305
test_camera->force_update_scroll();
306
xform = mock_viewport->get_canvas_transform();
307
test_xform = Transform2D(Vector2(1, 0), Vector2(0, 1), Vector2(200, 100));
308
CHECK(xform.is_equal_approx(test_xform));
309
}
310
311
memdelete(test_camera);
312
memdelete(mock_viewport);
313
}
314
315
} // namespace TestCamera2D
316
317