Path: blob/master/scene/2d/physics/collision_object_2d.cpp
9906 views
/**************************************************************************/1/* collision_object_2d.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "collision_object_2d.h"3132#include "scene/resources/world_2d.h"3334void CollisionObject2D::_notification(int p_what) {35switch (p_what) {36case NOTIFICATION_ENTER_TREE: {37Transform2D gl_transform = get_global_transform();3839if (area) {40PhysicsServer2D::get_singleton()->area_set_transform(rid, gl_transform);41} else {42PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, gl_transform);43}4445bool disabled = !is_enabled();4647if (disabled && (disable_mode != DISABLE_MODE_REMOVE)) {48_apply_disabled();49}5051if (!disabled || (disable_mode != DISABLE_MODE_REMOVE)) {52Ref<World2D> world_ref = get_world_2d();53ERR_FAIL_COND(world_ref.is_null());54RID space = world_ref->get_space();55if (area) {56PhysicsServer2D::get_singleton()->area_set_space(rid, space);57} else {58PhysicsServer2D::get_singleton()->body_set_space(rid, space);59}60_space_changed(space);61}6263_update_pickable();64} break;6566case NOTIFICATION_ENTER_CANVAS: {67if (area) {68PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id());69} else {70PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, get_canvas_layer_instance_id());71}72} break;7374case NOTIFICATION_VISIBILITY_CHANGED: {75_update_pickable();76} break;7778case NOTIFICATION_TRANSFORM_CHANGED: {79if (only_update_transform_changes) {80return;81}8283Transform2D gl_transform = get_global_transform();8485if (area) {86PhysicsServer2D::get_singleton()->area_set_transform(rid, gl_transform);87} else {88PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, gl_transform);89}90} break;9192case NOTIFICATION_EXIT_TREE: {93bool disabled = !is_enabled();9495if (!disabled || (disable_mode != DISABLE_MODE_REMOVE)) {96if (callback_lock > 0) {97ERR_PRINT("Removing a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Remove with call_deferred() instead.");98} else {99if (area) {100PhysicsServer2D::get_singleton()->area_set_space(rid, RID());101} else {102PhysicsServer2D::get_singleton()->body_set_space(rid, RID());103}104_space_changed(RID());105}106}107108if (disabled && (disable_mode != DISABLE_MODE_REMOVE)) {109_apply_enabled();110}111} break;112113case NOTIFICATION_EXIT_CANVAS: {114if (area) {115PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID());116} else {117PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, ObjectID());118}119} break;120121case NOTIFICATION_WORLD_2D_CHANGED: {122RID space = get_world_2d()->get_space();123if (area) {124PhysicsServer2D::get_singleton()->area_set_space(rid, space);125} else {126PhysicsServer2D::get_singleton()->body_set_space(rid, space);127}128_space_changed(space);129} break;130131case NOTIFICATION_DISABLED: {132_apply_disabled();133} break;134135case NOTIFICATION_ENABLED: {136_apply_enabled();137} break;138}139}140141void CollisionObject2D::set_collision_layer(uint32_t p_layer) {142collision_layer = p_layer;143if (area) {144PhysicsServer2D::get_singleton()->area_set_collision_layer(get_rid(), p_layer);145} else {146PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), p_layer);147}148}149150uint32_t CollisionObject2D::get_collision_layer() const {151return collision_layer;152}153154void CollisionObject2D::set_collision_mask(uint32_t p_mask) {155collision_mask = p_mask;156if (area) {157PhysicsServer2D::get_singleton()->area_set_collision_mask(get_rid(), p_mask);158} else {159PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), p_mask);160}161}162163uint32_t CollisionObject2D::get_collision_mask() const {164return collision_mask;165}166167void CollisionObject2D::set_collision_layer_value(int p_layer_number, bool p_value) {168ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");169ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");170uint32_t collision_layer_new = get_collision_layer();171if (p_value) {172collision_layer_new |= 1 << (p_layer_number - 1);173} else {174collision_layer_new &= ~(1 << (p_layer_number - 1));175}176set_collision_layer(collision_layer_new);177}178179bool CollisionObject2D::get_collision_layer_value(int p_layer_number) const {180ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");181ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");182return get_collision_layer() & (1 << (p_layer_number - 1));183}184185void CollisionObject2D::set_collision_mask_value(int p_layer_number, bool p_value) {186ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");187ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");188uint32_t mask = get_collision_mask();189if (p_value) {190mask |= 1 << (p_layer_number - 1);191} else {192mask &= ~(1 << (p_layer_number - 1));193}194set_collision_mask(mask);195}196197bool CollisionObject2D::get_collision_mask_value(int p_layer_number) const {198ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");199ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");200return get_collision_mask() & (1 << (p_layer_number - 1));201}202203void CollisionObject2D::set_collision_priority(real_t p_priority) {204collision_priority = p_priority;205if (!area) {206PhysicsServer2D::get_singleton()->body_set_collision_priority(get_rid(), p_priority);207}208}209210real_t CollisionObject2D::get_collision_priority() const {211return collision_priority;212}213214void CollisionObject2D::set_disable_mode(DisableMode p_mode) {215if (disable_mode == p_mode) {216return;217}218219bool disabled = is_inside_tree() && !is_enabled();220221if (disabled) {222// Cancel previous disable mode.223_apply_enabled();224}225226disable_mode = p_mode;227228if (disabled) {229// Apply new disable mode.230_apply_disabled();231}232}233234CollisionObject2D::DisableMode CollisionObject2D::get_disable_mode() const {235return disable_mode;236}237238void CollisionObject2D::_apply_disabled() {239switch (disable_mode) {240case DISABLE_MODE_REMOVE: {241if (is_inside_tree()) {242if (callback_lock > 0) {243ERR_PRINT("Disabling a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Disable with call_deferred() instead.");244} else {245if (area) {246PhysicsServer2D::get_singleton()->area_set_space(rid, RID());247} else {248PhysicsServer2D::get_singleton()->body_set_space(rid, RID());249}250_space_changed(RID());251}252}253} break;254255case DISABLE_MODE_MAKE_STATIC: {256if (!area && (body_mode != PhysicsServer2D::BODY_MODE_STATIC)) {257PhysicsServer2D::get_singleton()->body_set_mode(rid, PhysicsServer2D::BODY_MODE_STATIC);258}259} break;260261case DISABLE_MODE_KEEP_ACTIVE: {262// Nothing to do.263} break;264}265}266267void CollisionObject2D::_apply_enabled() {268switch (disable_mode) {269case DISABLE_MODE_REMOVE: {270if (is_inside_tree()) {271RID space = get_world_2d()->get_space();272if (area) {273PhysicsServer2D::get_singleton()->area_set_space(rid, space);274} else {275PhysicsServer2D::get_singleton()->body_set_space(rid, space);276}277_space_changed(space);278}279} break;280281case DISABLE_MODE_MAKE_STATIC: {282if (!area && (body_mode != PhysicsServer2D::BODY_MODE_STATIC)) {283PhysicsServer2D::get_singleton()->body_set_mode(rid, body_mode);284}285} break;286287case DISABLE_MODE_KEEP_ACTIVE: {288// Nothing to do.289} break;290}291}292293uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) {294ShapeData sd;295uint32_t id;296297if (shapes.is_empty()) {298id = 0;299} else {300id = shapes.back()->key() + 1;301}302303sd.owner_id = p_owner ? p_owner->get_instance_id() : ObjectID();304305shapes[id] = sd;306307return id;308}309310void CollisionObject2D::remove_shape_owner(uint32_t owner) {311ERR_FAIL_COND(!shapes.has(owner));312313shape_owner_clear_shapes(owner);314315shapes.erase(owner);316}317318void CollisionObject2D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabled) {319ERR_FAIL_COND(!shapes.has(p_owner));320321ShapeData &sd = shapes[p_owner];322sd.disabled = p_disabled;323for (int i = 0; i < sd.shapes.size(); i++) {324if (area) {325PhysicsServer2D::get_singleton()->area_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);326} else {327PhysicsServer2D::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);328}329}330}331332bool CollisionObject2D::is_shape_owner_disabled(uint32_t p_owner) const {333ERR_FAIL_COND_V(!shapes.has(p_owner), false);334335return shapes[p_owner].disabled;336}337338void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable) {339if (area) {340return; //not for areas341}342343ERR_FAIL_COND(!shapes.has(p_owner));344345ShapeData &sd = shapes[p_owner];346sd.one_way_collision = p_enable;347for (int i = 0; i < sd.shapes.size(); i++) {348PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin);349}350}351352bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const {353ERR_FAIL_COND_V(!shapes.has(p_owner), false);354355return shapes[p_owner].one_way_collision;356}357358void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin) {359if (area) {360return; //not for areas361}362363ERR_FAIL_COND(!shapes.has(p_owner));364365ShapeData &sd = shapes[p_owner];366sd.one_way_collision_margin = p_margin;367for (int i = 0; i < sd.shapes.size(); i++) {368PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin);369}370}371372real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const {373ERR_FAIL_COND_V(!shapes.has(p_owner), 0);374375return shapes[p_owner].one_way_collision_margin;376}377378void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) {379for (const KeyValue<uint32_t, ShapeData> &E : shapes) {380r_owners->push_back(E.key);381}382}383384PackedInt32Array CollisionObject2D::_get_shape_owners() {385PackedInt32Array ret;386for (const KeyValue<uint32_t, ShapeData> &E : shapes) {387ret.push_back(E.key);388}389390return ret;391}392393void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transform2D &p_transform) {394ERR_FAIL_COND(!shapes.has(p_owner));395396ShapeData &sd = shapes[p_owner];397398sd.xform = p_transform;399for (int i = 0; i < sd.shapes.size(); i++) {400if (area) {401PhysicsServer2D::get_singleton()->area_set_shape_transform(rid, sd.shapes[i].index, sd.xform);402} else {403PhysicsServer2D::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, sd.xform);404}405}406}407408Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const {409ERR_FAIL_COND_V(!shapes.has(p_owner), Transform2D());410411return shapes[p_owner].xform;412}413414Object *CollisionObject2D::shape_owner_get_owner(uint32_t p_owner) const {415ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);416417return ObjectDB::get_instance(shapes[p_owner].owner_id);418}419420void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape) {421ERR_FAIL_COND(!shapes.has(p_owner));422ERR_FAIL_COND(p_shape.is_null());423424ShapeData &sd = shapes[p_owner];425ShapeData::Shape s;426s.index = total_subshapes;427s.shape = p_shape;428if (area) {429PhysicsServer2D::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);430} else {431PhysicsServer2D::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);432}433sd.shapes.push_back(s);434435total_subshapes++;436}437438int CollisionObject2D::shape_owner_get_shape_count(uint32_t p_owner) const {439ERR_FAIL_COND_V(!shapes.has(p_owner), 0);440441return shapes[p_owner].shapes.size();442}443444Ref<Shape2D> CollisionObject2D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const {445ERR_FAIL_COND_V(!shapes.has(p_owner), Ref<Shape2D>());446ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), Ref<Shape2D>());447448return shapes[p_owner].shapes[p_shape].shape;449}450451int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const {452ERR_FAIL_COND_V(!shapes.has(p_owner), -1);453ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), -1);454455return shapes[p_owner].shapes[p_shape].index;456}457458void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) {459ERR_FAIL_COND(!shapes.has(p_owner));460ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());461462int index_to_remove = shapes[p_owner].shapes[p_shape].index;463if (area) {464PhysicsServer2D::get_singleton()->area_remove_shape(rid, index_to_remove);465} else {466PhysicsServer2D::get_singleton()->body_remove_shape(rid, index_to_remove);467}468469shapes[p_owner].shapes.remove_at(p_shape);470471for (KeyValue<uint32_t, ShapeData> &E : shapes) {472for (int i = 0; i < E.value.shapes.size(); i++) {473if (E.value.shapes[i].index > index_to_remove) {474E.value.shapes.write[i].index -= 1;475}476}477}478479total_subshapes--;480}481482void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) {483ERR_FAIL_COND(!shapes.has(p_owner));484485while (shape_owner_get_shape_count(p_owner) > 0) {486shape_owner_remove_shape(p_owner, 0);487}488}489490uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const {491ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, UINT32_MAX);492493for (const KeyValue<uint32_t, ShapeData> &E : shapes) {494for (int i = 0; i < E.value.shapes.size(); i++) {495if (E.value.shapes[i].index == p_shape_index) {496return E.key;497}498}499}500501//in theory it should be unreachable502ERR_FAIL_V_MSG(UINT32_MAX, "Can't find owner for shape index " + itos(p_shape_index) + ".");503}504505void CollisionObject2D::set_pickable(bool p_enabled) {506if (pickable == p_enabled) {507return;508}509510pickable = p_enabled;511_update_pickable();512}513514bool CollisionObject2D::is_pickable() const {515return pickable;516}517518void CollisionObject2D::_input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) {519GDVIRTUAL_CALL(_input_event, p_viewport, p_input_event, p_shape);520emit_signal(SceneStringName(input_event), p_viewport, p_input_event, p_shape);521}522523void CollisionObject2D::_mouse_enter() {524GDVIRTUAL_CALL(_mouse_enter);525emit_signal(SceneStringName(mouse_entered));526}527528void CollisionObject2D::_mouse_exit() {529GDVIRTUAL_CALL(_mouse_exit);530emit_signal(SceneStringName(mouse_exited));531}532533void CollisionObject2D::_mouse_shape_enter(int p_shape) {534GDVIRTUAL_CALL(_mouse_shape_enter, p_shape);535emit_signal(SceneStringName(mouse_shape_entered), p_shape);536}537538void CollisionObject2D::_mouse_shape_exit(int p_shape) {539GDVIRTUAL_CALL(_mouse_shape_exit, p_shape);540emit_signal(SceneStringName(mouse_shape_exited), p_shape);541}542543void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {544only_update_transform_changes = p_enable;545}546547bool CollisionObject2D::is_only_update_transform_changes_enabled() const {548return only_update_transform_changes;549}550551void CollisionObject2D::set_body_mode(PhysicsServer2D::BodyMode p_mode) {552ERR_FAIL_COND(area);553554if (body_mode == p_mode) {555return;556}557558body_mode = p_mode;559560if (is_inside_tree() && !is_enabled() && (disable_mode == DISABLE_MODE_MAKE_STATIC)) {561return;562}563564PhysicsServer2D::get_singleton()->body_set_mode(rid, p_mode);565}566567void CollisionObject2D::_space_changed(const RID &p_new_space) {568}569570void CollisionObject2D::_update_pickable() {571if (!is_inside_tree()) {572return;573}574575bool is_pickable = pickable && is_visible_in_tree();576if (area) {577PhysicsServer2D::get_singleton()->area_set_pickable(rid, is_pickable);578} else {579PhysicsServer2D::get_singleton()->body_set_pickable(rid, is_pickable);580}581}582583PackedStringArray CollisionObject2D::get_configuration_warnings() const {584PackedStringArray warnings = Node2D::get_configuration_warnings();585586if (shapes.is_empty()) {587warnings.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."));588}589590return warnings;591}592593void CollisionObject2D::_bind_methods() {594ClassDB::bind_method(D_METHOD("get_rid"), &CollisionObject2D::get_rid);595ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &CollisionObject2D::set_collision_layer);596ClassDB::bind_method(D_METHOD("get_collision_layer"), &CollisionObject2D::get_collision_layer);597ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &CollisionObject2D::set_collision_mask);598ClassDB::bind_method(D_METHOD("get_collision_mask"), &CollisionObject2D::get_collision_mask);599ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &CollisionObject2D::set_collision_layer_value);600ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &CollisionObject2D::get_collision_layer_value);601ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &CollisionObject2D::set_collision_mask_value);602ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &CollisionObject2D::get_collision_mask_value);603ClassDB::bind_method(D_METHOD("set_collision_priority", "priority"), &CollisionObject2D::set_collision_priority);604ClassDB::bind_method(D_METHOD("get_collision_priority"), &CollisionObject2D::get_collision_priority);605ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &CollisionObject2D::set_disable_mode);606ClassDB::bind_method(D_METHOD("get_disable_mode"), &CollisionObject2D::get_disable_mode);607ClassDB::bind_method(D_METHOD("set_pickable", "enabled"), &CollisionObject2D::set_pickable);608ClassDB::bind_method(D_METHOD("is_pickable"), &CollisionObject2D::is_pickable);609ClassDB::bind_method(D_METHOD("create_shape_owner", "owner"), &CollisionObject2D::create_shape_owner);610ClassDB::bind_method(D_METHOD("remove_shape_owner", "owner_id"), &CollisionObject2D::remove_shape_owner);611ClassDB::bind_method(D_METHOD("get_shape_owners"), &CollisionObject2D::_get_shape_owners);612ClassDB::bind_method(D_METHOD("shape_owner_set_transform", "owner_id", "transform"), &CollisionObject2D::shape_owner_set_transform);613ClassDB::bind_method(D_METHOD("shape_owner_get_transform", "owner_id"), &CollisionObject2D::shape_owner_get_transform);614ClassDB::bind_method(D_METHOD("shape_owner_get_owner", "owner_id"), &CollisionObject2D::shape_owner_get_owner);615ClassDB::bind_method(D_METHOD("shape_owner_set_disabled", "owner_id", "disabled"), &CollisionObject2D::shape_owner_set_disabled);616ClassDB::bind_method(D_METHOD("is_shape_owner_disabled", "owner_id"), &CollisionObject2D::is_shape_owner_disabled);617ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision", "owner_id", "enable"), &CollisionObject2D::shape_owner_set_one_way_collision);618ClassDB::bind_method(D_METHOD("is_shape_owner_one_way_collision_enabled", "owner_id"), &CollisionObject2D::is_shape_owner_one_way_collision_enabled);619ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision_margin", "owner_id", "margin"), &CollisionObject2D::shape_owner_set_one_way_collision_margin);620ClassDB::bind_method(D_METHOD("get_shape_owner_one_way_collision_margin", "owner_id"), &CollisionObject2D::get_shape_owner_one_way_collision_margin);621ClassDB::bind_method(D_METHOD("shape_owner_add_shape", "owner_id", "shape"), &CollisionObject2D::shape_owner_add_shape);622ClassDB::bind_method(D_METHOD("shape_owner_get_shape_count", "owner_id"), &CollisionObject2D::shape_owner_get_shape_count);623ClassDB::bind_method(D_METHOD("shape_owner_get_shape", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_get_shape);624ClassDB::bind_method(D_METHOD("shape_owner_get_shape_index", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_get_shape_index);625ClassDB::bind_method(D_METHOD("shape_owner_remove_shape", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_remove_shape);626ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject2D::shape_owner_clear_shapes);627ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject2D::shape_find_owner);628629GDVIRTUAL_BIND(_input_event, "viewport", "event", "shape_idx");630GDVIRTUAL_BIND(_mouse_enter);631GDVIRTUAL_BIND(_mouse_exit);632GDVIRTUAL_BIND(_mouse_shape_enter, "shape_idx");633GDVIRTUAL_BIND(_mouse_shape_exit, "shape_idx");634635ADD_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")));636ADD_SIGNAL(MethodInfo("mouse_entered"));637ADD_SIGNAL(MethodInfo("mouse_exited"));638ADD_SIGNAL(MethodInfo("mouse_shape_entered", PropertyInfo(Variant::INT, "shape_idx")));639ADD_SIGNAL(MethodInfo("mouse_shape_exited", PropertyInfo(Variant::INT, "shape_idx")));640641ADD_PROPERTY(PropertyInfo(Variant::INT, "disable_mode", PROPERTY_HINT_ENUM, "Remove,Make Static,Keep Active"), "set_disable_mode", "get_disable_mode");642643ADD_GROUP("Collision", "collision_");644ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");645ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");646ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority");647648ADD_GROUP("Input", "input_");649ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input_pickable"), "set_pickable", "is_pickable");650651BIND_ENUM_CONSTANT(DISABLE_MODE_REMOVE);652BIND_ENUM_CONSTANT(DISABLE_MODE_MAKE_STATIC);653BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);654}655656CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {657rid = p_rid;658area = p_area;659pickable = true;660set_notify_transform(true);661set_hide_clip_children(true);662total_subshapes = 0;663only_update_transform_changes = false;664665if (p_area) {666PhysicsServer2D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id());667} else {668PhysicsServer2D::get_singleton()->body_attach_object_instance_id(rid, get_instance_id());669PhysicsServer2D::get_singleton()->body_set_mode(rid, body_mode);670}671}672673CollisionObject2D::CollisionObject2D() {674//owner=675676set_notify_transform(true);677}678679CollisionObject2D::~CollisionObject2D() {680ERR_FAIL_NULL(PhysicsServer2D::get_singleton());681PhysicsServer2D::get_singleton()->free(rid);682}683684685