Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/2d/physics/collision_object_2d.cpp
9906 views
1
/**************************************************************************/
2
/* collision_object_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 "collision_object_2d.h"
32
33
#include "scene/resources/world_2d.h"
34
35
void CollisionObject2D::_notification(int p_what) {
36
switch (p_what) {
37
case NOTIFICATION_ENTER_TREE: {
38
Transform2D gl_transform = get_global_transform();
39
40
if (area) {
41
PhysicsServer2D::get_singleton()->area_set_transform(rid, gl_transform);
42
} else {
43
PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, gl_transform);
44
}
45
46
bool disabled = !is_enabled();
47
48
if (disabled && (disable_mode != DISABLE_MODE_REMOVE)) {
49
_apply_disabled();
50
}
51
52
if (!disabled || (disable_mode != DISABLE_MODE_REMOVE)) {
53
Ref<World2D> world_ref = get_world_2d();
54
ERR_FAIL_COND(world_ref.is_null());
55
RID space = world_ref->get_space();
56
if (area) {
57
PhysicsServer2D::get_singleton()->area_set_space(rid, space);
58
} else {
59
PhysicsServer2D::get_singleton()->body_set_space(rid, space);
60
}
61
_space_changed(space);
62
}
63
64
_update_pickable();
65
} break;
66
67
case NOTIFICATION_ENTER_CANVAS: {
68
if (area) {
69
PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id());
70
} else {
71
PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, get_canvas_layer_instance_id());
72
}
73
} break;
74
75
case NOTIFICATION_VISIBILITY_CHANGED: {
76
_update_pickable();
77
} break;
78
79
case NOTIFICATION_TRANSFORM_CHANGED: {
80
if (only_update_transform_changes) {
81
return;
82
}
83
84
Transform2D gl_transform = get_global_transform();
85
86
if (area) {
87
PhysicsServer2D::get_singleton()->area_set_transform(rid, gl_transform);
88
} else {
89
PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, gl_transform);
90
}
91
} break;
92
93
case NOTIFICATION_EXIT_TREE: {
94
bool disabled = !is_enabled();
95
96
if (!disabled || (disable_mode != DISABLE_MODE_REMOVE)) {
97
if (callback_lock > 0) {
98
ERR_PRINT("Removing a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Remove with call_deferred() instead.");
99
} else {
100
if (area) {
101
PhysicsServer2D::get_singleton()->area_set_space(rid, RID());
102
} else {
103
PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
104
}
105
_space_changed(RID());
106
}
107
}
108
109
if (disabled && (disable_mode != DISABLE_MODE_REMOVE)) {
110
_apply_enabled();
111
}
112
} break;
113
114
case NOTIFICATION_EXIT_CANVAS: {
115
if (area) {
116
PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID());
117
} else {
118
PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, ObjectID());
119
}
120
} break;
121
122
case NOTIFICATION_WORLD_2D_CHANGED: {
123
RID space = get_world_2d()->get_space();
124
if (area) {
125
PhysicsServer2D::get_singleton()->area_set_space(rid, space);
126
} else {
127
PhysicsServer2D::get_singleton()->body_set_space(rid, space);
128
}
129
_space_changed(space);
130
} break;
131
132
case NOTIFICATION_DISABLED: {
133
_apply_disabled();
134
} break;
135
136
case NOTIFICATION_ENABLED: {
137
_apply_enabled();
138
} break;
139
}
140
}
141
142
void CollisionObject2D::set_collision_layer(uint32_t p_layer) {
143
collision_layer = p_layer;
144
if (area) {
145
PhysicsServer2D::get_singleton()->area_set_collision_layer(get_rid(), p_layer);
146
} else {
147
PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), p_layer);
148
}
149
}
150
151
uint32_t CollisionObject2D::get_collision_layer() const {
152
return collision_layer;
153
}
154
155
void CollisionObject2D::set_collision_mask(uint32_t p_mask) {
156
collision_mask = p_mask;
157
if (area) {
158
PhysicsServer2D::get_singleton()->area_set_collision_mask(get_rid(), p_mask);
159
} else {
160
PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), p_mask);
161
}
162
}
163
164
uint32_t CollisionObject2D::get_collision_mask() const {
165
return collision_mask;
166
}
167
168
void CollisionObject2D::set_collision_layer_value(int p_layer_number, bool p_value) {
169
ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");
170
ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");
171
uint32_t collision_layer_new = get_collision_layer();
172
if (p_value) {
173
collision_layer_new |= 1 << (p_layer_number - 1);
174
} else {
175
collision_layer_new &= ~(1 << (p_layer_number - 1));
176
}
177
set_collision_layer(collision_layer_new);
178
}
179
180
bool CollisionObject2D::get_collision_layer_value(int p_layer_number) const {
181
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");
182
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");
183
return get_collision_layer() & (1 << (p_layer_number - 1));
184
}
185
186
void CollisionObject2D::set_collision_mask_value(int p_layer_number, bool p_value) {
187
ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");
188
ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");
189
uint32_t mask = get_collision_mask();
190
if (p_value) {
191
mask |= 1 << (p_layer_number - 1);
192
} else {
193
mask &= ~(1 << (p_layer_number - 1));
194
}
195
set_collision_mask(mask);
196
}
197
198
bool CollisionObject2D::get_collision_mask_value(int p_layer_number) const {
199
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");
200
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");
201
return get_collision_mask() & (1 << (p_layer_number - 1));
202
}
203
204
void CollisionObject2D::set_collision_priority(real_t p_priority) {
205
collision_priority = p_priority;
206
if (!area) {
207
PhysicsServer2D::get_singleton()->body_set_collision_priority(get_rid(), p_priority);
208
}
209
}
210
211
real_t CollisionObject2D::get_collision_priority() const {
212
return collision_priority;
213
}
214
215
void CollisionObject2D::set_disable_mode(DisableMode p_mode) {
216
if (disable_mode == p_mode) {
217
return;
218
}
219
220
bool disabled = is_inside_tree() && !is_enabled();
221
222
if (disabled) {
223
// Cancel previous disable mode.
224
_apply_enabled();
225
}
226
227
disable_mode = p_mode;
228
229
if (disabled) {
230
// Apply new disable mode.
231
_apply_disabled();
232
}
233
}
234
235
CollisionObject2D::DisableMode CollisionObject2D::get_disable_mode() const {
236
return disable_mode;
237
}
238
239
void CollisionObject2D::_apply_disabled() {
240
switch (disable_mode) {
241
case DISABLE_MODE_REMOVE: {
242
if (is_inside_tree()) {
243
if (callback_lock > 0) {
244
ERR_PRINT("Disabling a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Disable with call_deferred() instead.");
245
} else {
246
if (area) {
247
PhysicsServer2D::get_singleton()->area_set_space(rid, RID());
248
} else {
249
PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
250
}
251
_space_changed(RID());
252
}
253
}
254
} break;
255
256
case DISABLE_MODE_MAKE_STATIC: {
257
if (!area && (body_mode != PhysicsServer2D::BODY_MODE_STATIC)) {
258
PhysicsServer2D::get_singleton()->body_set_mode(rid, PhysicsServer2D::BODY_MODE_STATIC);
259
}
260
} break;
261
262
case DISABLE_MODE_KEEP_ACTIVE: {
263
// Nothing to do.
264
} break;
265
}
266
}
267
268
void CollisionObject2D::_apply_enabled() {
269
switch (disable_mode) {
270
case DISABLE_MODE_REMOVE: {
271
if (is_inside_tree()) {
272
RID space = get_world_2d()->get_space();
273
if (area) {
274
PhysicsServer2D::get_singleton()->area_set_space(rid, space);
275
} else {
276
PhysicsServer2D::get_singleton()->body_set_space(rid, space);
277
}
278
_space_changed(space);
279
}
280
} break;
281
282
case DISABLE_MODE_MAKE_STATIC: {
283
if (!area && (body_mode != PhysicsServer2D::BODY_MODE_STATIC)) {
284
PhysicsServer2D::get_singleton()->body_set_mode(rid, body_mode);
285
}
286
} break;
287
288
case DISABLE_MODE_KEEP_ACTIVE: {
289
// Nothing to do.
290
} break;
291
}
292
}
293
294
uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) {
295
ShapeData sd;
296
uint32_t id;
297
298
if (shapes.is_empty()) {
299
id = 0;
300
} else {
301
id = shapes.back()->key() + 1;
302
}
303
304
sd.owner_id = p_owner ? p_owner->get_instance_id() : ObjectID();
305
306
shapes[id] = sd;
307
308
return id;
309
}
310
311
void CollisionObject2D::remove_shape_owner(uint32_t owner) {
312
ERR_FAIL_COND(!shapes.has(owner));
313
314
shape_owner_clear_shapes(owner);
315
316
shapes.erase(owner);
317
}
318
319
void CollisionObject2D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabled) {
320
ERR_FAIL_COND(!shapes.has(p_owner));
321
322
ShapeData &sd = shapes[p_owner];
323
sd.disabled = p_disabled;
324
for (int i = 0; i < sd.shapes.size(); i++) {
325
if (area) {
326
PhysicsServer2D::get_singleton()->area_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
327
} else {
328
PhysicsServer2D::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
329
}
330
}
331
}
332
333
bool CollisionObject2D::is_shape_owner_disabled(uint32_t p_owner) const {
334
ERR_FAIL_COND_V(!shapes.has(p_owner), false);
335
336
return shapes[p_owner].disabled;
337
}
338
339
void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable) {
340
if (area) {
341
return; //not for areas
342
}
343
344
ERR_FAIL_COND(!shapes.has(p_owner));
345
346
ShapeData &sd = shapes[p_owner];
347
sd.one_way_collision = p_enable;
348
for (int i = 0; i < sd.shapes.size(); i++) {
349
PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin);
350
}
351
}
352
353
bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const {
354
ERR_FAIL_COND_V(!shapes.has(p_owner), false);
355
356
return shapes[p_owner].one_way_collision;
357
}
358
359
void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin) {
360
if (area) {
361
return; //not for areas
362
}
363
364
ERR_FAIL_COND(!shapes.has(p_owner));
365
366
ShapeData &sd = shapes[p_owner];
367
sd.one_way_collision_margin = p_margin;
368
for (int i = 0; i < sd.shapes.size(); i++) {
369
PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin);
370
}
371
}
372
373
real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const {
374
ERR_FAIL_COND_V(!shapes.has(p_owner), 0);
375
376
return shapes[p_owner].one_way_collision_margin;
377
}
378
379
void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) {
380
for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
381
r_owners->push_back(E.key);
382
}
383
}
384
385
PackedInt32Array CollisionObject2D::_get_shape_owners() {
386
PackedInt32Array ret;
387
for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
388
ret.push_back(E.key);
389
}
390
391
return ret;
392
}
393
394
void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transform2D &p_transform) {
395
ERR_FAIL_COND(!shapes.has(p_owner));
396
397
ShapeData &sd = shapes[p_owner];
398
399
sd.xform = p_transform;
400
for (int i = 0; i < sd.shapes.size(); i++) {
401
if (area) {
402
PhysicsServer2D::get_singleton()->area_set_shape_transform(rid, sd.shapes[i].index, sd.xform);
403
} else {
404
PhysicsServer2D::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, sd.xform);
405
}
406
}
407
}
408
409
Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const {
410
ERR_FAIL_COND_V(!shapes.has(p_owner), Transform2D());
411
412
return shapes[p_owner].xform;
413
}
414
415
Object *CollisionObject2D::shape_owner_get_owner(uint32_t p_owner) const {
416
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
417
418
return ObjectDB::get_instance(shapes[p_owner].owner_id);
419
}
420
421
void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape) {
422
ERR_FAIL_COND(!shapes.has(p_owner));
423
ERR_FAIL_COND(p_shape.is_null());
424
425
ShapeData &sd = shapes[p_owner];
426
ShapeData::Shape s;
427
s.index = total_subshapes;
428
s.shape = p_shape;
429
if (area) {
430
PhysicsServer2D::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);
431
} else {
432
PhysicsServer2D::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);
433
}
434
sd.shapes.push_back(s);
435
436
total_subshapes++;
437
}
438
439
int CollisionObject2D::shape_owner_get_shape_count(uint32_t p_owner) const {
440
ERR_FAIL_COND_V(!shapes.has(p_owner), 0);
441
442
return shapes[p_owner].shapes.size();
443
}
444
445
Ref<Shape2D> CollisionObject2D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const {
446
ERR_FAIL_COND_V(!shapes.has(p_owner), Ref<Shape2D>());
447
ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), Ref<Shape2D>());
448
449
return shapes[p_owner].shapes[p_shape].shape;
450
}
451
452
int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const {
453
ERR_FAIL_COND_V(!shapes.has(p_owner), -1);
454
ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), -1);
455
456
return shapes[p_owner].shapes[p_shape].index;
457
}
458
459
void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) {
460
ERR_FAIL_COND(!shapes.has(p_owner));
461
ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
462
463
int index_to_remove = shapes[p_owner].shapes[p_shape].index;
464
if (area) {
465
PhysicsServer2D::get_singleton()->area_remove_shape(rid, index_to_remove);
466
} else {
467
PhysicsServer2D::get_singleton()->body_remove_shape(rid, index_to_remove);
468
}
469
470
shapes[p_owner].shapes.remove_at(p_shape);
471
472
for (KeyValue<uint32_t, ShapeData> &E : shapes) {
473
for (int i = 0; i < E.value.shapes.size(); i++) {
474
if (E.value.shapes[i].index > index_to_remove) {
475
E.value.shapes.write[i].index -= 1;
476
}
477
}
478
}
479
480
total_subshapes--;
481
}
482
483
void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) {
484
ERR_FAIL_COND(!shapes.has(p_owner));
485
486
while (shape_owner_get_shape_count(p_owner) > 0) {
487
shape_owner_remove_shape(p_owner, 0);
488
}
489
}
490
491
uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const {
492
ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, UINT32_MAX);
493
494
for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
495
for (int i = 0; i < E.value.shapes.size(); i++) {
496
if (E.value.shapes[i].index == p_shape_index) {
497
return E.key;
498
}
499
}
500
}
501
502
//in theory it should be unreachable
503
ERR_FAIL_V_MSG(UINT32_MAX, "Can't find owner for shape index " + itos(p_shape_index) + ".");
504
}
505
506
void CollisionObject2D::set_pickable(bool p_enabled) {
507
if (pickable == p_enabled) {
508
return;
509
}
510
511
pickable = p_enabled;
512
_update_pickable();
513
}
514
515
bool CollisionObject2D::is_pickable() const {
516
return pickable;
517
}
518
519
void CollisionObject2D::_input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) {
520
GDVIRTUAL_CALL(_input_event, p_viewport, p_input_event, p_shape);
521
emit_signal(SceneStringName(input_event), p_viewport, p_input_event, p_shape);
522
}
523
524
void CollisionObject2D::_mouse_enter() {
525
GDVIRTUAL_CALL(_mouse_enter);
526
emit_signal(SceneStringName(mouse_entered));
527
}
528
529
void CollisionObject2D::_mouse_exit() {
530
GDVIRTUAL_CALL(_mouse_exit);
531
emit_signal(SceneStringName(mouse_exited));
532
}
533
534
void CollisionObject2D::_mouse_shape_enter(int p_shape) {
535
GDVIRTUAL_CALL(_mouse_shape_enter, p_shape);
536
emit_signal(SceneStringName(mouse_shape_entered), p_shape);
537
}
538
539
void CollisionObject2D::_mouse_shape_exit(int p_shape) {
540
GDVIRTUAL_CALL(_mouse_shape_exit, p_shape);
541
emit_signal(SceneStringName(mouse_shape_exited), p_shape);
542
}
543
544
void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
545
only_update_transform_changes = p_enable;
546
}
547
548
bool CollisionObject2D::is_only_update_transform_changes_enabled() const {
549
return only_update_transform_changes;
550
}
551
552
void CollisionObject2D::set_body_mode(PhysicsServer2D::BodyMode p_mode) {
553
ERR_FAIL_COND(area);
554
555
if (body_mode == p_mode) {
556
return;
557
}
558
559
body_mode = p_mode;
560
561
if (is_inside_tree() && !is_enabled() && (disable_mode == DISABLE_MODE_MAKE_STATIC)) {
562
return;
563
}
564
565
PhysicsServer2D::get_singleton()->body_set_mode(rid, p_mode);
566
}
567
568
void CollisionObject2D::_space_changed(const RID &p_new_space) {
569
}
570
571
void CollisionObject2D::_update_pickable() {
572
if (!is_inside_tree()) {
573
return;
574
}
575
576
bool is_pickable = pickable && is_visible_in_tree();
577
if (area) {
578
PhysicsServer2D::get_singleton()->area_set_pickable(rid, is_pickable);
579
} else {
580
PhysicsServer2D::get_singleton()->body_set_pickable(rid, is_pickable);
581
}
582
}
583
584
PackedStringArray CollisionObject2D::get_configuration_warnings() const {
585
PackedStringArray warnings = Node2D::get_configuration_warnings();
586
587
if (shapes.is_empty()) {
588
warnings.push_back(RTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape2D or CollisionPolygon2D as a child to define its shape."));
589
}
590
591
return warnings;
592
}
593
594
void CollisionObject2D::_bind_methods() {
595
ClassDB::bind_method(D_METHOD("get_rid"), &CollisionObject2D::get_rid);
596
ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &CollisionObject2D::set_collision_layer);
597
ClassDB::bind_method(D_METHOD("get_collision_layer"), &CollisionObject2D::get_collision_layer);
598
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &CollisionObject2D::set_collision_mask);
599
ClassDB::bind_method(D_METHOD("get_collision_mask"), &CollisionObject2D::get_collision_mask);
600
ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &CollisionObject2D::set_collision_layer_value);
601
ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &CollisionObject2D::get_collision_layer_value);
602
ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &CollisionObject2D::set_collision_mask_value);
603
ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &CollisionObject2D::get_collision_mask_value);
604
ClassDB::bind_method(D_METHOD("set_collision_priority", "priority"), &CollisionObject2D::set_collision_priority);
605
ClassDB::bind_method(D_METHOD("get_collision_priority"), &CollisionObject2D::get_collision_priority);
606
ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &CollisionObject2D::set_disable_mode);
607
ClassDB::bind_method(D_METHOD("get_disable_mode"), &CollisionObject2D::get_disable_mode);
608
ClassDB::bind_method(D_METHOD("set_pickable", "enabled"), &CollisionObject2D::set_pickable);
609
ClassDB::bind_method(D_METHOD("is_pickable"), &CollisionObject2D::is_pickable);
610
ClassDB::bind_method(D_METHOD("create_shape_owner", "owner"), &CollisionObject2D::create_shape_owner);
611
ClassDB::bind_method(D_METHOD("remove_shape_owner", "owner_id"), &CollisionObject2D::remove_shape_owner);
612
ClassDB::bind_method(D_METHOD("get_shape_owners"), &CollisionObject2D::_get_shape_owners);
613
ClassDB::bind_method(D_METHOD("shape_owner_set_transform", "owner_id", "transform"), &CollisionObject2D::shape_owner_set_transform);
614
ClassDB::bind_method(D_METHOD("shape_owner_get_transform", "owner_id"), &CollisionObject2D::shape_owner_get_transform);
615
ClassDB::bind_method(D_METHOD("shape_owner_get_owner", "owner_id"), &CollisionObject2D::shape_owner_get_owner);
616
ClassDB::bind_method(D_METHOD("shape_owner_set_disabled", "owner_id", "disabled"), &CollisionObject2D::shape_owner_set_disabled);
617
ClassDB::bind_method(D_METHOD("is_shape_owner_disabled", "owner_id"), &CollisionObject2D::is_shape_owner_disabled);
618
ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision", "owner_id", "enable"), &CollisionObject2D::shape_owner_set_one_way_collision);
619
ClassDB::bind_method(D_METHOD("is_shape_owner_one_way_collision_enabled", "owner_id"), &CollisionObject2D::is_shape_owner_one_way_collision_enabled);
620
ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision_margin", "owner_id", "margin"), &CollisionObject2D::shape_owner_set_one_way_collision_margin);
621
ClassDB::bind_method(D_METHOD("get_shape_owner_one_way_collision_margin", "owner_id"), &CollisionObject2D::get_shape_owner_one_way_collision_margin);
622
ClassDB::bind_method(D_METHOD("shape_owner_add_shape", "owner_id", "shape"), &CollisionObject2D::shape_owner_add_shape);
623
ClassDB::bind_method(D_METHOD("shape_owner_get_shape_count", "owner_id"), &CollisionObject2D::shape_owner_get_shape_count);
624
ClassDB::bind_method(D_METHOD("shape_owner_get_shape", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_get_shape);
625
ClassDB::bind_method(D_METHOD("shape_owner_get_shape_index", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_get_shape_index);
626
ClassDB::bind_method(D_METHOD("shape_owner_remove_shape", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_remove_shape);
627
ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject2D::shape_owner_clear_shapes);
628
ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject2D::shape_find_owner);
629
630
GDVIRTUAL_BIND(_input_event, "viewport", "event", "shape_idx");
631
GDVIRTUAL_BIND(_mouse_enter);
632
GDVIRTUAL_BIND(_mouse_exit);
633
GDVIRTUAL_BIND(_mouse_shape_enter, "shape_idx");
634
GDVIRTUAL_BIND(_mouse_shape_exit, "shape_idx");
635
636
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "viewport", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::INT, "shape_idx")));
637
ADD_SIGNAL(MethodInfo("mouse_entered"));
638
ADD_SIGNAL(MethodInfo("mouse_exited"));
639
ADD_SIGNAL(MethodInfo("mouse_shape_entered", PropertyInfo(Variant::INT, "shape_idx")));
640
ADD_SIGNAL(MethodInfo("mouse_shape_exited", PropertyInfo(Variant::INT, "shape_idx")));
641
642
ADD_PROPERTY(PropertyInfo(Variant::INT, "disable_mode", PROPERTY_HINT_ENUM, "Remove,Make Static,Keep Active"), "set_disable_mode", "get_disable_mode");
643
644
ADD_GROUP("Collision", "collision_");
645
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");
646
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
647
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority");
648
649
ADD_GROUP("Input", "input_");
650
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input_pickable"), "set_pickable", "is_pickable");
651
652
BIND_ENUM_CONSTANT(DISABLE_MODE_REMOVE);
653
BIND_ENUM_CONSTANT(DISABLE_MODE_MAKE_STATIC);
654
BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);
655
}
656
657
CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
658
rid = p_rid;
659
area = p_area;
660
pickable = true;
661
set_notify_transform(true);
662
set_hide_clip_children(true);
663
total_subshapes = 0;
664
only_update_transform_changes = false;
665
666
if (p_area) {
667
PhysicsServer2D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id());
668
} else {
669
PhysicsServer2D::get_singleton()->body_attach_object_instance_id(rid, get_instance_id());
670
PhysicsServer2D::get_singleton()->body_set_mode(rid, body_mode);
671
}
672
}
673
674
CollisionObject2D::CollisionObject2D() {
675
//owner=
676
677
set_notify_transform(true);
678
}
679
680
CollisionObject2D::~CollisionObject2D() {
681
ERR_FAIL_NULL(PhysicsServer2D::get_singleton());
682
PhysicsServer2D::get_singleton()->free(rid);
683
}
684
685