diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-11-07 17:51:27 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-07 17:51:27 -0300 |
commit | daa168677233e32d4f6125f3ee5e478892d10e73 (patch) | |
tree | 596b3f037ece65dd93f46c5a5ca0b999f35defc8 | |
parent | 8ca90d718e79557408a352335b67bc6219740a34 (diff) | |
parent | 6d0f4a4ad70bc20e2653c144d630f19507edb164 (diff) |
Merge pull request #21386 from RandomShaper/fix-picking-in-canvas-layers
Fix picking in CanvasLayer
-rw-r--r-- | scene/2d/canvas_item.cpp | 9 | ||||
-rw-r--r-- | scene/2d/canvas_item.h | 1 | ||||
-rw-r--r-- | scene/2d/collision_object_2d.cpp | 16 | ||||
-rw-r--r-- | scene/main/canvas_layer.cpp | 5 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 59 | ||||
-rw-r--r-- | scene/main/viewport.h | 6 | ||||
-rw-r--r-- | servers/physics_2d/collision_object_2d_sw.cpp | 1 | ||||
-rw-r--r-- | servers/physics_2d/collision_object_2d_sw.h | 4 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.cpp | 37 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.h | 6 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_wrap_mt.h | 6 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.cpp | 15 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.h | 3 | ||||
-rw-r--r-- | servers/physics_2d_server.cpp | 26 | ||||
-rw-r--r-- | servers/physics_2d_server.h | 10 |
15 files changed, 184 insertions, 20 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index d6d190fe4a..8dc2f57685 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -965,6 +965,15 @@ RID CanvasItem::get_canvas() const { return get_viewport()->find_world_2d()->get_canvas(); } +ObjectID CanvasItem::get_canvas_layer_instance_id() const { + + if (canvas_layer) { + return canvas_layer->get_instance_id(); + } else { + return 0; + } +} + CanvasItem *CanvasItem::get_toplevel() const { CanvasItem *ci = const_cast<CanvasItem *>(this); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 9e2a93a8ee..9fe7cb1e00 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -352,6 +352,7 @@ public: Rect2 get_viewport_rect() const; RID get_viewport_rid() const; RID get_canvas() const; + ObjectID get_canvas_layer_instance_id() const; Ref<World2D> get_world_2d() const; virtual void set_material(const Ref<Material> &p_material); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 7ade74e8a6..738f7ddf59 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -58,6 +58,14 @@ void CollisionObject2D::_notification(int p_what) { //get space } + case NOTIFICATION_ENTER_CANVAS: { + + if (area) + Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); + else + Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, get_canvas_layer_instance_id()); + } + case NOTIFICATION_VISIBILITY_CHANGED: { _update_pickable(); @@ -86,6 +94,14 @@ void CollisionObject2D::_notification(int p_what) { Physics2DServer::get_singleton()->body_set_space(rid, RID()); } break; + + case NOTIFICATION_EXIT_CANVAS: { + + if (area) + Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, 0); + else + Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, 0); + } } } diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 0f5fd99281..93f51a44f4 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -146,6 +146,8 @@ void CanvasLayer::_notification(int p_what) { vp = Node::get_viewport(); } ERR_FAIL_COND(!vp); + + vp->_canvas_layer_add(this); viewport = vp->get_viewport_rid(); VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas); @@ -155,6 +157,7 @@ void CanvasLayer::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { + vp->_canvas_layer_remove(this); VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas); viewport = RID(); @@ -183,6 +186,7 @@ RID CanvasLayer::get_viewport() const { void CanvasLayer::set_custom_viewport(Node *p_viewport) { ERR_FAIL_NULL(p_viewport); if (is_inside_tree()) { + vp->_canvas_layer_remove(this); VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas); viewport = RID(); } @@ -202,6 +206,7 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) { else vp = Node::get_viewport(); + vp->_canvas_layer_add(this); viewport = vp->get_viewport_rid(); VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index a28b6fd6de..f8cc1bdd77 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -45,6 +45,7 @@ #include "scene/gui/panel.h" #include "scene/gui/panel_container.h" #include "scene/gui/popup_menu.h" +#include "scene/main/canvas_layer.h" #include "scene/main/timer.h" #include "scene/resources/mesh.h" #include "scene/scene_string_names.h" @@ -443,24 +444,39 @@ void Viewport::_notification(int p_what) { uint64_t frame = get_tree()->get_frame(); - Vector2 point = get_canvas_transform().affine_inverse().xform(pos); Physics2DDirectSpaceState::ShapeResult res[64]; - int rc = ss2d->intersect_point(point, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); - for (int i = 0; i < rc; i++) { - - if (res[i].collider_id && res[i].collider) { - CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); - if (co) { - - Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.find(res[i].collider_id); - if (!E) { - E = physics_2d_mouseover.insert(res[i].collider_id, frame); - co->_mouse_enter(); - } else { - E->get() = frame; - } + for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) { + Transform2D canvas_transform; + ObjectID canvas_layer_id; + if (E->get()) { + // A descendant CanvasLayer + canvas_transform = E->get()->get_transform(); + canvas_layer_id = E->get()->get_instance_id(); + } else { + // This Viewport's builtin canvas + canvas_transform = get_canvas_transform(); + canvas_layer_id = 0; + } + + Vector2 point = canvas_transform.affine_inverse().xform(pos); + + int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); + for (int i = 0; i < rc; i++) { + + if (res[i].collider_id && res[i].collider) { + CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); + if (co) { + + Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.find(res[i].collider_id); + if (!E) { + E = physics_2d_mouseover.insert(res[i].collider_id, frame); + co->_mouse_enter(); + } else { + E->get() = frame; + } - co->_input_event(this, ev, res[i].shape); + co->_input_event(this, ev, res[i].shape); + } } } } @@ -854,6 +870,16 @@ void Viewport::_camera_make_next_current(Camera *p_exclude) { } #endif +void Viewport::_canvas_layer_add(CanvasLayer *p_canvas_layer) { + + canvas_layers.insert(p_canvas_layer); +} + +void Viewport::_canvas_layer_remove(CanvasLayer *p_canvas_layer) { + + canvas_layers.erase(p_canvas_layer); +} + void Viewport::set_transparent_background(bool p_enable) { transparent_bg = p_enable; @@ -2911,6 +2937,7 @@ Viewport::Viewport() { parent = NULL; listener = NULL; camera = NULL; + canvas_layers.insert(NULL); // This eases picking code (interpreted as the canvas of the Viewport) arvr = false; size_override = false; size_override_stretch = false; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index c1a4c0e3eb..08c1ac1d12 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -45,6 +45,7 @@ class Camera2D; class Listener; class Control; class CanvasItem; +class CanvasLayer; class Panel; class Label; class Timer; @@ -163,6 +164,7 @@ private: Camera *camera; Set<Camera *> cameras; + Set<CanvasLayer *> canvas_layers; RID viewport; RID current_canvas; @@ -354,6 +356,10 @@ private: void _camera_remove(Camera *p_camera); void _camera_make_next_current(Camera *p_exclude); + friend class CanvasLayer; + void _canvas_layer_add(CanvasLayer *p_canvas_layer); + void _canvas_layer_remove(CanvasLayer *p_canvas_layer); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index 4dd5b2040f..2f5b484040 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -244,6 +244,7 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) { type = p_type; space = NULL; instance_id = 0; + canvas_instance_id = 0; collision_mask = 1; collision_layer = 1; pickable = true; diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index f2b2363499..f256910f52 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -49,6 +49,7 @@ private: Type type; RID self; ObjectID instance_id; + ObjectID canvas_instance_id; bool pickable; struct Shape { @@ -102,6 +103,9 @@ public: _FORCE_INLINE_ void set_instance_id(const ObjectID &p_instance_id) { instance_id = p_instance_id; } _FORCE_INLINE_ ObjectID get_instance_id() const { return instance_id; } + _FORCE_INLINE_ void set_canvas_instance_id(const ObjectID &p_canvas_instance_id) { canvas_instance_id = p_canvas_instance_id; } + _FORCE_INLINE_ ObjectID get_canvas_instance_id() const { return canvas_instance_id; } + void _shape_changed(); _FORCE_INLINE_ Type get_type() const { return type; } diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index dd114ed72f..80588c05e6 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -469,6 +469,27 @@ ObjectID Physics2DServerSW::area_get_object_instance_id(RID p_area) const { return area->get_instance_id(); } +void Physics2DServerSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_ID) { + + if (space_owner.owns(p_area)) { + Space2DSW *space = space_owner.get(p_area); + p_area = space->get_default_area()->get_self(); + } + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + area->set_canvas_instance_id(p_ID); +} +ObjectID Physics2DServerSW::area_get_canvas_instance_id(RID p_area) const { + + if (space_owner.owns(p_area)) { + Space2DSW *space = space_owner.get(p_area); + p_area = space->get_default_area()->get_self(); + } + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND_V(!area, 0); + return area->get_canvas_instance_id(); +} + void Physics2DServerSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { if (space_owner.owns(p_area)) { @@ -744,6 +765,22 @@ uint32_t Physics2DServerSW::body_get_object_instance_id(RID p_body) const { return body->get_instance_id(); }; +void Physics2DServerSW::body_attach_canvas_instance_id(RID p_body, uint32_t p_ID) { + + Body2DSW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + + body->set_canvas_instance_id(p_ID); +}; + +uint32_t Physics2DServerSW::body_get_canvas_instance_id(RID p_body) const { + + Body2DSW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_canvas_instance_id(); +}; + void Physics2DServerSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { Body2DSW *body = body_owner.get(p_body); diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index d4fc44b1d7..f41c599579 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -144,6 +144,9 @@ public: virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID); virtual ObjectID area_get_object_instance_id(RID p_area) const; + virtual void area_attach_canvas_instance_id(RID p_area, ObjectID p_ID); + virtual ObjectID area_get_canvas_instance_id(RID p_area) const; + virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value); virtual void area_set_transform(RID p_area, const Transform2D &p_transform); @@ -188,6 +191,9 @@ public: virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID); virtual uint32_t body_get_object_instance_id(RID p_body) const; + virtual void body_attach_canvas_instance_id(RID p_body, uint32_t p_ID); + virtual uint32_t body_get_canvas_instance_id(RID p_body) const; + virtual void body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode); virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const; diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 5f5fd3866f..58517bf1a7 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -154,6 +154,9 @@ public: FUNC2(area_attach_object_instance_id, RID, ObjectID); FUNC1RC(ObjectID, area_get_object_instance_id, RID); + FUNC2(area_attach_canvas_instance_id, RID, ObjectID); + FUNC1RC(ObjectID, area_get_canvas_instance_id, RID); + FUNC3(area_set_param, RID, AreaParameter, const Variant &); FUNC2(area_set_transform, RID, const Transform2D &); @@ -199,6 +202,9 @@ public: FUNC2(body_attach_object_instance_id, RID, uint32_t); FUNC1RC(uint32_t, body_get_object_instance_id, RID); + FUNC2(body_attach_canvas_instance_id, RID, uint32_t); + FUNC1RC(uint32_t, body_get_canvas_instance_id, RID); + FUNC2(body_set_continuous_collision_detection_mode, RID, CCDMode); FUNC1RC(CCDMode, body_get_continuous_collision_detection_mode, RID); diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index ab9916095b..0e83993472 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -49,7 +49,7 @@ _FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint return true; } -int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { +int Physics2DDirectSpaceStateSW::_intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) { if (p_result_max <= 0) return 0; @@ -75,6 +75,9 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe if (p_pick_point && !col_obj->is_pickable()) continue; + if (p_filter_by_canvas && col_obj->get_canvas_instance_id() != p_canvas_instance_id) + continue; + int shape_idx = space->intersection_query_subindex_results[i]; Shape2DSW *shape = col_obj->get_shape(shape_idx); @@ -100,6 +103,16 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe return cc; } +int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { + + return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point); +} + +int Physics2DDirectSpaceStateSW::intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { + + return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point, true, p_canvas_instance_id); +} + bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ERR_FAIL_COND_V(space->locked, false); diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index c894eb9c40..bf4ea12eb5 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -45,10 +45,13 @@ class Physics2DDirectSpaceStateSW : public Physics2DDirectSpaceState { GDCLASS(Physics2DDirectSpaceStateSW, Physics2DDirectSpaceState); + int _intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = 0); + public: Space2DSW *space; virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false); + virtual int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false); virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 3ca6e29f0b..2ed8a4c478 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -328,7 +328,7 @@ Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParam return ret; } -Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { +Array Physics2DDirectSpaceState::_intersect_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) { Set<RID> exclude; for (int i = 0; i < p_exclude.size(); i++) @@ -337,7 +337,12 @@ Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_ Vector<ShapeResult> ret; ret.resize(p_max_results); - int rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); + int rc; + if (p_filter_by_canvas) + rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); + else + rc = intersect_point_on_canvas(p_point, p_canvas_instance_id, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); + if (rc == 0) return Array(); @@ -356,6 +361,16 @@ Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_ return r; } +Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { + + return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); +} + +Array Physics2DDirectSpaceState::_intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { + + return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas, true, p_canvas_intance_id); +} + Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results) { ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array()); @@ -400,6 +415,7 @@ Physics2DDirectSpaceState::Physics2DDirectSpaceState() { void Physics2DDirectSpaceState::_bind_methods() { ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("intersect_point_on_canvas", "point", "canvas_instance_id", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_point_on_canvas, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &Physics2DDirectSpaceState::_intersect_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("cast_motion", "shape"), &Physics2DDirectSpaceState::_cast_motion); @@ -575,6 +591,9 @@ void Physics2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("area_attach_object_instance_id", "area", "id"), &Physics2DServer::area_attach_object_instance_id); ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &Physics2DServer::area_get_object_instance_id); + ClassDB::bind_method(D_METHOD("area_attach_canvas_instance_id", "area", "id"), &Physics2DServer::area_attach_canvas_instance_id); + ClassDB::bind_method(D_METHOD("area_get_canvas_instance_id", "area"), &Physics2DServer::area_get_canvas_instance_id); + ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_monitor_callback); ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_area_monitor_callback); ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &Physics2DServer::area_set_monitorable); @@ -606,6 +625,9 @@ void Physics2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_attach_object_instance_id", "body", "id"), &Physics2DServer::body_attach_object_instance_id); ClassDB::bind_method(D_METHOD("body_get_object_instance_id", "body"), &Physics2DServer::body_get_object_instance_id); + ClassDB::bind_method(D_METHOD("body_attach_canvas_instance_id", "body", "id"), &Physics2DServer::body_attach_canvas_instance_id); + ClassDB::bind_method(D_METHOD("body_get_canvas_instance_id", "body"), &Physics2DServer::body_get_canvas_instance_id); + ClassDB::bind_method(D_METHOD("body_set_continuous_collision_detection_mode", "body", "mode"), &Physics2DServer::body_set_continuous_collision_detection_mode); ClassDB::bind_method(D_METHOD("body_get_continuous_collision_detection_mode", "body"), &Physics2DServer::body_get_continuous_collision_detection_mode); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 7c23fcdaea..2e91d89c53 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -147,8 +147,9 @@ class Physics2DDirectSpaceState : public Object { GDCLASS(Physics2DDirectSpaceState, Object); Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); - Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + Array _intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + Array _intersect_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclud, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = 0); Array _intersect_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32); Array _cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query); Array _collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32); @@ -181,6 +182,7 @@ public: }; virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; + virtual int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; @@ -348,6 +350,9 @@ public: virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID) = 0; virtual ObjectID area_get_object_instance_id(RID p_area) const = 0; + virtual void area_attach_canvas_instance_id(RID p_area, ObjectID p_ID) = 0; + virtual ObjectID area_get_canvas_instance_id(RID p_area) const = 0; + virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) = 0; virtual void area_set_transform(RID p_area, const Transform2D &p_transform) = 0; @@ -401,6 +406,9 @@ public: virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID) = 0; virtual uint32_t body_get_object_instance_id(RID p_body) const = 0; + virtual void body_attach_canvas_instance_id(RID p_body, uint32_t p_ID) = 0; + virtual uint32_t body_get_canvas_instance_id(RID p_body) const = 0; + enum CCDMode { CCD_MODE_DISABLED, CCD_MODE_CAST_RAY, |