summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2018-11-07 17:51:27 -0300
committerGitHub <noreply@github.com>2018-11-07 17:51:27 -0300
commitdaa168677233e32d4f6125f3ee5e478892d10e73 (patch)
tree596b3f037ece65dd93f46c5a5ca0b999f35defc8
parent8ca90d718e79557408a352335b67bc6219740a34 (diff)
parent6d0f4a4ad70bc20e2653c144d630f19507edb164 (diff)
Merge pull request #21386 from RandomShaper/fix-picking-in-canvas-layers
Fix picking in CanvasLayer
-rw-r--r--scene/2d/canvas_item.cpp9
-rw-r--r--scene/2d/canvas_item.h1
-rw-r--r--scene/2d/collision_object_2d.cpp16
-rw-r--r--scene/main/canvas_layer.cpp5
-rw-r--r--scene/main/viewport.cpp59
-rw-r--r--scene/main/viewport.h6
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp1
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h4
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp37
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h6
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h6
-rw-r--r--servers/physics_2d/space_2d_sw.cpp15
-rw-r--r--servers/physics_2d/space_2d_sw.h3
-rw-r--r--servers/physics_2d_server.cpp26
-rw-r--r--servers/physics_2d_server.h10
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,