Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/2d/physics/area_2d.cpp
9906 views
1
/**************************************************************************/
2
/* area_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 "area_2d.h"
32
33
#include "servers/audio_server.h"
34
35
void Area2D::set_gravity_space_override_mode(SpaceOverride p_mode) {
36
gravity_space_override = p_mode;
37
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_OVERRIDE_MODE, p_mode);
38
}
39
40
Area2D::SpaceOverride Area2D::get_gravity_space_override_mode() const {
41
return gravity_space_override;
42
}
43
44
void Area2D::set_gravity_is_point(bool p_enabled) {
45
gravity_is_point = p_enabled;
46
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT, p_enabled);
47
}
48
49
bool Area2D::is_gravity_a_point() const {
50
return gravity_is_point;
51
}
52
53
void Area2D::set_gravity_point_unit_distance(real_t p_scale) {
54
gravity_point_unit_distance = p_scale;
55
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_UNIT_DISTANCE, p_scale);
56
}
57
58
real_t Area2D::get_gravity_point_unit_distance() const {
59
return gravity_point_unit_distance;
60
}
61
62
void Area2D::set_gravity_point_center(const Vector2 &p_center) {
63
gravity_vec = p_center;
64
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, p_center);
65
}
66
67
const Vector2 &Area2D::get_gravity_point_center() const {
68
return gravity_vec;
69
}
70
71
void Area2D::set_gravity_direction(const Vector2 &p_direction) {
72
gravity_vec = p_direction;
73
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, p_direction);
74
}
75
76
const Vector2 &Area2D::get_gravity_direction() const {
77
return gravity_vec;
78
}
79
80
void Area2D::set_gravity(real_t p_gravity) {
81
gravity = p_gravity;
82
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY, p_gravity);
83
}
84
85
real_t Area2D::get_gravity() const {
86
return gravity;
87
}
88
89
void Area2D::set_linear_damp_space_override_mode(SpaceOverride p_mode) {
90
linear_damp_space_override = p_mode;
91
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_LINEAR_DAMP_OVERRIDE_MODE, p_mode);
92
}
93
94
Area2D::SpaceOverride Area2D::get_linear_damp_space_override_mode() const {
95
return linear_damp_space_override;
96
}
97
98
void Area2D::set_angular_damp_space_override_mode(SpaceOverride p_mode) {
99
angular_damp_space_override = p_mode;
100
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP_OVERRIDE_MODE, p_mode);
101
}
102
103
Area2D::SpaceOverride Area2D::get_angular_damp_space_override_mode() const {
104
return angular_damp_space_override;
105
}
106
107
void Area2D::set_linear_damp(real_t p_linear_damp) {
108
linear_damp = p_linear_damp;
109
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, p_linear_damp);
110
}
111
112
real_t Area2D::get_linear_damp() const {
113
return linear_damp;
114
}
115
116
void Area2D::set_angular_damp(real_t p_angular_damp) {
117
angular_damp = p_angular_damp;
118
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, p_angular_damp);
119
}
120
121
real_t Area2D::get_angular_damp() const {
122
return angular_damp;
123
}
124
125
void Area2D::set_priority(int p_priority) {
126
priority = p_priority;
127
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_PRIORITY, p_priority);
128
}
129
130
int Area2D::get_priority() const {
131
return priority;
132
}
133
134
void Area2D::_body_enter_tree(ObjectID p_id) {
135
Object *obj = ObjectDB::get_instance(p_id);
136
Node *node = Object::cast_to<Node>(obj);
137
ERR_FAIL_NULL(node);
138
139
HashMap<ObjectID, BodyState>::Iterator E = body_map.find(p_id);
140
ERR_FAIL_COND(!E);
141
ERR_FAIL_COND(E->value.in_tree);
142
143
E->value.in_tree = true;
144
emit_signal(SceneStringName(body_entered), node);
145
for (int i = 0; i < E->value.shapes.size(); i++) {
146
emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
147
}
148
}
149
150
void Area2D::_body_exit_tree(ObjectID p_id) {
151
Object *obj = ObjectDB::get_instance(p_id);
152
Node *node = Object::cast_to<Node>(obj);
153
ERR_FAIL_NULL(node);
154
HashMap<ObjectID, BodyState>::Iterator E = body_map.find(p_id);
155
ERR_FAIL_COND(!E);
156
ERR_FAIL_COND(!E->value.in_tree);
157
E->value.in_tree = false;
158
emit_signal(SceneStringName(body_exited), node);
159
for (int i = 0; i < E->value.shapes.size(); i++) {
160
emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
161
}
162
}
163
164
void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) {
165
bool body_in = p_status == PhysicsServer2D::AREA_BODY_ADDED;
166
ObjectID objid = p_instance;
167
168
// Exit early if instance is invalid.
169
if (objid.is_null()) {
170
// Emit the appropriate signals.
171
lock_callback();
172
locked = true;
173
if (body_in) {
174
emit_signal(SceneStringName(body_shape_entered), p_body, (Node *)nullptr, p_body_shape, p_area_shape);
175
} else {
176
emit_signal(SceneStringName(body_shape_exited), p_body, (Node *)nullptr, p_body_shape, p_area_shape);
177
}
178
locked = false;
179
unlock_callback();
180
return;
181
}
182
183
Object *obj = ObjectDB::get_instance(objid);
184
Node *node = Object::cast_to<Node>(obj);
185
186
HashMap<ObjectID, BodyState>::Iterator E = body_map.find(objid);
187
188
if (!body_in && !E) {
189
return; //does not exist because it was likely removed from the tree
190
}
191
192
lock_callback();
193
locked = true;
194
195
if (body_in) {
196
if (!E) {
197
E = body_map.insert(objid, BodyState());
198
E->value.rid = p_body;
199
E->value.rc = 0;
200
E->value.in_tree = node && node->is_inside_tree();
201
if (node) {
202
node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree).bind(objid));
203
node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree).bind(objid));
204
if (E->value.in_tree) {
205
emit_signal(SceneStringName(body_entered), node);
206
}
207
}
208
}
209
E->value.rc++;
210
if (node) {
211
E->value.shapes.insert(ShapePair(p_body_shape, p_area_shape));
212
}
213
214
if (!node || E->value.in_tree) {
215
emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_area_shape);
216
}
217
218
} else {
219
E->value.rc--;
220
221
if (node) {
222
E->value.shapes.erase(ShapePair(p_body_shape, p_area_shape));
223
}
224
225
bool in_tree = E->value.in_tree;
226
if (E->value.rc == 0) {
227
body_map.remove(E);
228
if (node) {
229
node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree));
230
node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree));
231
if (in_tree) {
232
emit_signal(SceneStringName(body_exited), obj);
233
}
234
}
235
}
236
if (!node || in_tree) {
237
emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_area_shape);
238
}
239
}
240
241
locked = false;
242
unlock_callback();
243
}
244
245
void Area2D::_area_enter_tree(ObjectID p_id) {
246
Object *obj = ObjectDB::get_instance(p_id);
247
Node *node = Object::cast_to<Node>(obj);
248
ERR_FAIL_NULL(node);
249
250
HashMap<ObjectID, AreaState>::Iterator E = area_map.find(p_id);
251
ERR_FAIL_COND(!E);
252
ERR_FAIL_COND(E->value.in_tree);
253
254
E->value.in_tree = true;
255
emit_signal(SceneStringName(area_entered), node);
256
for (int i = 0; i < E->value.shapes.size(); i++) {
257
emit_signal(SceneStringName(area_shape_entered), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
258
}
259
}
260
261
void Area2D::_area_exit_tree(ObjectID p_id) {
262
Object *obj = ObjectDB::get_instance(p_id);
263
Node *node = Object::cast_to<Node>(obj);
264
ERR_FAIL_NULL(node);
265
HashMap<ObjectID, AreaState>::Iterator E = area_map.find(p_id);
266
ERR_FAIL_COND(!E);
267
ERR_FAIL_COND(!E->value.in_tree);
268
E->value.in_tree = false;
269
emit_signal(SceneStringName(area_exited), node);
270
for (int i = 0; i < E->value.shapes.size(); i++) {
271
emit_signal(SceneStringName(area_shape_exited), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
272
}
273
}
274
275
void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) {
276
bool area_in = p_status == PhysicsServer2D::AREA_BODY_ADDED;
277
ObjectID objid = p_instance;
278
279
// Exit early if instance is invalid.
280
if (objid.is_null()) {
281
// Emit the appropriate signals.
282
lock_callback();
283
locked = true;
284
if (area_in) {
285
emit_signal(SceneStringName(area_shape_entered), p_area, (Node *)nullptr, p_area_shape, p_self_shape);
286
} else {
287
emit_signal(SceneStringName(area_shape_exited), p_area, (Node *)nullptr, p_area_shape, p_self_shape);
288
}
289
locked = false;
290
unlock_callback();
291
return;
292
}
293
294
Object *obj = ObjectDB::get_instance(objid);
295
Node *node = Object::cast_to<Node>(obj);
296
297
HashMap<ObjectID, AreaState>::Iterator E = area_map.find(objid);
298
299
if (!area_in && !E) {
300
return; //likely removed from the tree
301
}
302
303
lock_callback();
304
locked = true;
305
306
if (area_in) {
307
if (!E) {
308
E = area_map.insert(objid, AreaState());
309
E->value.rid = p_area;
310
E->value.rc = 0;
311
E->value.in_tree = node && node->is_inside_tree();
312
if (node) {
313
node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree).bind(objid));
314
node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree).bind(objid));
315
if (E->value.in_tree) {
316
emit_signal(SceneStringName(area_entered), node);
317
}
318
}
319
}
320
E->value.rc++;
321
if (node) {
322
E->value.shapes.insert(AreaShapePair(p_area_shape, p_self_shape));
323
}
324
325
if (!node || E->value.in_tree) {
326
emit_signal(SceneStringName(area_shape_entered), p_area, node, p_area_shape, p_self_shape);
327
}
328
329
} else {
330
E->value.rc--;
331
332
if (node) {
333
E->value.shapes.erase(AreaShapePair(p_area_shape, p_self_shape));
334
}
335
336
bool in_tree = E->value.in_tree;
337
if (E->value.rc == 0) {
338
area_map.remove(E);
339
if (node) {
340
node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree));
341
node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree));
342
if (in_tree) {
343
emit_signal(SceneStringName(area_exited), obj);
344
}
345
}
346
}
347
if (!node || in_tree) {
348
emit_signal(SceneStringName(area_shape_exited), p_area, obj, p_area_shape, p_self_shape);
349
}
350
}
351
352
locked = false;
353
unlock_callback();
354
}
355
356
void Area2D::_clear_monitoring() {
357
ERR_FAIL_COND_MSG(locked, "This function can't be used during the in/out signal.");
358
359
{
360
HashMap<ObjectID, BodyState> bmcopy = body_map;
361
body_map.clear();
362
//disconnect all monitored stuff
363
364
for (const KeyValue<ObjectID, BodyState> &E : bmcopy) {
365
Object *obj = ObjectDB::get_instance(E.key);
366
Node *node = Object::cast_to<Node>(obj);
367
368
if (!node) { //node may have been deleted in previous frame or at other legitimate point
369
continue;
370
}
371
372
node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree));
373
node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree));
374
375
if (!E.value.in_tree) {
376
continue;
377
}
378
379
for (int i = 0; i < E.value.shapes.size(); i++) {
380
emit_signal(SceneStringName(body_shape_exited), E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape);
381
}
382
383
emit_signal(SceneStringName(body_exited), obj);
384
}
385
}
386
387
{
388
HashMap<ObjectID, AreaState> bmcopy = area_map;
389
area_map.clear();
390
//disconnect all monitored stuff
391
392
for (const KeyValue<ObjectID, AreaState> &E : bmcopy) {
393
Object *obj = ObjectDB::get_instance(E.key);
394
Node *node = Object::cast_to<Node>(obj);
395
396
if (!node) { //node may have been deleted in previous frame or at other legitimate point
397
continue;
398
}
399
400
node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree));
401
node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree));
402
403
if (!E.value.in_tree) {
404
continue;
405
}
406
407
for (int i = 0; i < E.value.shapes.size(); i++) {
408
emit_signal(SceneStringName(area_shape_exited), E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape);
409
}
410
411
emit_signal(SceneStringName(area_exited), obj);
412
}
413
}
414
}
415
416
void Area2D::_space_changed(const RID &p_new_space) {
417
if (p_new_space.is_null()) {
418
_clear_monitoring();
419
}
420
}
421
422
void Area2D::set_monitoring(bool p_enable) {
423
if (p_enable == monitoring) {
424
return;
425
}
426
ERR_FAIL_COND_MSG(locked, "Function blocked during in/out signal. Use set_deferred(\"monitoring\", true/false).");
427
428
monitoring = p_enable;
429
430
if (monitoring) {
431
PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), callable_mp(this, &Area2D::_body_inout));
432
PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), callable_mp(this, &Area2D::_area_inout));
433
} else {
434
PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), Callable());
435
PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), Callable());
436
_clear_monitoring();
437
}
438
}
439
440
bool Area2D::is_monitoring() const {
441
return monitoring;
442
}
443
444
void Area2D::set_monitorable(bool p_enable) {
445
ERR_FAIL_COND_MSG(locked || (is_inside_tree() && PhysicsServer2D::get_singleton()->is_flushing_queries()), "Function blocked during in/out signal. Use set_deferred(\"monitorable\", true/false).");
446
447
if (p_enable == monitorable) {
448
return;
449
}
450
451
monitorable = p_enable;
452
453
PhysicsServer2D::get_singleton()->area_set_monitorable(get_rid(), monitorable);
454
}
455
456
bool Area2D::is_monitorable() const {
457
return monitorable;
458
}
459
460
TypedArray<Node2D> Area2D::get_overlapping_bodies() const {
461
TypedArray<Node2D> ret;
462
ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping bodies when monitoring is off.");
463
ret.resize(body_map.size());
464
int idx = 0;
465
for (const KeyValue<ObjectID, BodyState> &E : body_map) {
466
Object *obj = ObjectDB::get_instance(E.key);
467
if (obj) {
468
ret[idx] = obj;
469
idx++;
470
}
471
}
472
473
ret.resize(idx);
474
return ret;
475
}
476
477
TypedArray<Area2D> Area2D::get_overlapping_areas() const {
478
TypedArray<Area2D> ret;
479
ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping areas when monitoring is off.");
480
ret.resize(area_map.size());
481
int idx = 0;
482
for (const KeyValue<ObjectID, AreaState> &E : area_map) {
483
Object *obj = ObjectDB::get_instance(E.key);
484
if (obj) {
485
ret[idx] = obj;
486
idx++;
487
}
488
}
489
490
ret.resize(idx);
491
return ret;
492
}
493
494
bool Area2D::has_overlapping_bodies() const {
495
ERR_FAIL_COND_V_MSG(!monitoring, false, "Can't find overlapping bodies when monitoring is off.");
496
return !body_map.is_empty();
497
}
498
499
bool Area2D::has_overlapping_areas() const {
500
ERR_FAIL_COND_V_MSG(!monitoring, false, "Can't find overlapping areas when monitoring is off.");
501
return !area_map.is_empty();
502
}
503
504
bool Area2D::overlaps_area(Node *p_area) const {
505
ERR_FAIL_NULL_V(p_area, false);
506
HashMap<ObjectID, AreaState>::ConstIterator E = area_map.find(p_area->get_instance_id());
507
if (!E) {
508
return false;
509
}
510
return E->value.in_tree;
511
}
512
513
bool Area2D::overlaps_body(Node *p_body) const {
514
ERR_FAIL_NULL_V(p_body, false);
515
HashMap<ObjectID, BodyState>::ConstIterator E = body_map.find(p_body->get_instance_id());
516
if (!E) {
517
return false;
518
}
519
return E->value.in_tree;
520
}
521
522
void Area2D::set_audio_bus_override(bool p_override) {
523
audio_bus_override = p_override;
524
}
525
526
bool Area2D::is_overriding_audio_bus() const {
527
return audio_bus_override;
528
}
529
530
void Area2D::set_audio_bus_name(const StringName &p_audio_bus) {
531
audio_bus = p_audio_bus;
532
}
533
534
StringName Area2D::get_audio_bus_name() const {
535
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
536
if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) {
537
return audio_bus;
538
}
539
}
540
return SceneStringName(Master);
541
}
542
543
void Area2D::_validate_property(PropertyInfo &p_property) const {
544
if (!Engine::get_singleton()->is_editor_hint()) {
545
return;
546
}
547
if (p_property.name == "audio_bus_name") {
548
String options;
549
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
550
if (i > 0) {
551
options += ",";
552
}
553
String name = AudioServer::get_singleton()->get_bus_name(i);
554
options += name;
555
}
556
557
p_property.hint_string = options;
558
} else if (p_property.name.begins_with("gravity") && p_property.name != "gravity_space_override") {
559
if (gravity_space_override == SPACE_OVERRIDE_DISABLED) {
560
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
561
} else {
562
if (gravity_is_point) {
563
if (p_property.name == "gravity_direction") {
564
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
565
}
566
} else {
567
if (p_property.name.begins_with("gravity_point_")) {
568
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
569
}
570
}
571
}
572
} else if (p_property.name.begins_with("linear_damp") && p_property.name != "linear_damp_space_override") {
573
if (linear_damp_space_override == SPACE_OVERRIDE_DISABLED) {
574
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
575
}
576
} else if (p_property.name.begins_with("angular_damp") && p_property.name != "angular_damp_space_override") {
577
if (angular_damp_space_override == SPACE_OVERRIDE_DISABLED) {
578
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
579
}
580
}
581
}
582
583
void Area2D::_bind_methods() {
584
ClassDB::bind_method(D_METHOD("set_gravity_space_override_mode", "space_override_mode"), &Area2D::set_gravity_space_override_mode);
585
ClassDB::bind_method(D_METHOD("get_gravity_space_override_mode"), &Area2D::get_gravity_space_override_mode);
586
587
ClassDB::bind_method(D_METHOD("set_gravity_is_point", "enable"), &Area2D::set_gravity_is_point);
588
ClassDB::bind_method(D_METHOD("is_gravity_a_point"), &Area2D::is_gravity_a_point);
589
590
ClassDB::bind_method(D_METHOD("set_gravity_point_unit_distance", "distance_scale"), &Area2D::set_gravity_point_unit_distance);
591
ClassDB::bind_method(D_METHOD("get_gravity_point_unit_distance"), &Area2D::get_gravity_point_unit_distance);
592
593
ClassDB::bind_method(D_METHOD("set_gravity_point_center", "center"), &Area2D::set_gravity_point_center);
594
ClassDB::bind_method(D_METHOD("get_gravity_point_center"), &Area2D::get_gravity_point_center);
595
596
ClassDB::bind_method(D_METHOD("set_gravity_direction", "direction"), &Area2D::set_gravity_direction);
597
ClassDB::bind_method(D_METHOD("get_gravity_direction"), &Area2D::get_gravity_direction);
598
599
ClassDB::bind_method(D_METHOD("set_gravity", "gravity"), &Area2D::set_gravity);
600
ClassDB::bind_method(D_METHOD("get_gravity"), &Area2D::get_gravity);
601
602
ClassDB::bind_method(D_METHOD("set_linear_damp_space_override_mode", "space_override_mode"), &Area2D::set_linear_damp_space_override_mode);
603
ClassDB::bind_method(D_METHOD("get_linear_damp_space_override_mode"), &Area2D::get_linear_damp_space_override_mode);
604
605
ClassDB::bind_method(D_METHOD("set_angular_damp_space_override_mode", "space_override_mode"), &Area2D::set_angular_damp_space_override_mode);
606
ClassDB::bind_method(D_METHOD("get_angular_damp_space_override_mode"), &Area2D::get_angular_damp_space_override_mode);
607
608
ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &Area2D::set_linear_damp);
609
ClassDB::bind_method(D_METHOD("get_linear_damp"), &Area2D::get_linear_damp);
610
611
ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &Area2D::set_angular_damp);
612
ClassDB::bind_method(D_METHOD("get_angular_damp"), &Area2D::get_angular_damp);
613
614
ClassDB::bind_method(D_METHOD("set_priority", "priority"), &Area2D::set_priority);
615
ClassDB::bind_method(D_METHOD("get_priority"), &Area2D::get_priority);
616
617
ClassDB::bind_method(D_METHOD("set_monitoring", "enable"), &Area2D::set_monitoring);
618
ClassDB::bind_method(D_METHOD("is_monitoring"), &Area2D::is_monitoring);
619
620
ClassDB::bind_method(D_METHOD("set_monitorable", "enable"), &Area2D::set_monitorable);
621
ClassDB::bind_method(D_METHOD("is_monitorable"), &Area2D::is_monitorable);
622
623
ClassDB::bind_method(D_METHOD("get_overlapping_bodies"), &Area2D::get_overlapping_bodies);
624
ClassDB::bind_method(D_METHOD("get_overlapping_areas"), &Area2D::get_overlapping_areas);
625
626
ClassDB::bind_method(D_METHOD("has_overlapping_bodies"), &Area2D::has_overlapping_bodies);
627
ClassDB::bind_method(D_METHOD("has_overlapping_areas"), &Area2D::has_overlapping_areas);
628
629
ClassDB::bind_method(D_METHOD("overlaps_body", "body"), &Area2D::overlaps_body);
630
ClassDB::bind_method(D_METHOD("overlaps_area", "area"), &Area2D::overlaps_area);
631
632
ClassDB::bind_method(D_METHOD("set_audio_bus_name", "name"), &Area2D::set_audio_bus_name);
633
ClassDB::bind_method(D_METHOD("get_audio_bus_name"), &Area2D::get_audio_bus_name);
634
635
ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area2D::set_audio_bus_override);
636
ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area2D::is_overriding_audio_bus);
637
638
ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
639
ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
640
ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
641
ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
642
643
ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
644
ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
645
ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
646
ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
647
648
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
649
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
650
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,100000,1,or_greater,or_less"), "set_priority", "get_priority");
651
652
ADD_GROUP("Gravity", "gravity_");
653
ADD_PROPERTY(PropertyInfo(Variant::INT, "gravity_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_space_override_mode", "get_gravity_space_override_mode");
654
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_is_point", "is_gravity_a_point");
655
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_unit_distance", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp,suffix:px"), "set_gravity_point_unit_distance", "get_gravity_point_unit_distance");
656
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:px"), "set_gravity_point_center", "get_gravity_point_center");
657
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_direction"), "set_gravity_direction", "get_gravity_direction");
658
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-4096,4096,0.001,or_less,or_greater,suffix:px/s\u00B2"), "set_gravity", "get_gravity");
659
660
ADD_GROUP("Linear Damp", "linear_damp_");
661
ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_linear_damp_space_override_mode", "get_linear_damp_space_override_mode");
662
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
663
664
ADD_GROUP("Angular Damp", "angular_damp_");
665
ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_angular_damp_space_override_mode", "get_angular_damp_space_override_mode");
666
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
667
668
ADD_GROUP("Audio Bus", "audio_bus_");
669
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus");
670
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus_name", "get_audio_bus_name");
671
672
BIND_ENUM_CONSTANT(SPACE_OVERRIDE_DISABLED);
673
BIND_ENUM_CONSTANT(SPACE_OVERRIDE_COMBINE);
674
BIND_ENUM_CONSTANT(SPACE_OVERRIDE_COMBINE_REPLACE);
675
BIND_ENUM_CONSTANT(SPACE_OVERRIDE_REPLACE);
676
BIND_ENUM_CONSTANT(SPACE_OVERRIDE_REPLACE_COMBINE);
677
}
678
679
Area2D::Area2D() :
680
CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) {
681
set_gravity(980);
682
set_gravity_direction(Vector2(0, 1));
683
set_monitoring(true);
684
set_monitorable(true);
685
set_hide_clip_children(true);
686
}
687
688
Area2D::~Area2D() {
689
}
690
691