Fix picking in CanvasLayer

New APIs in 2D physics allow intersection queries filtered by CanvasLayer object instance id. Viewport keep an inventory of its descendant CanvasLayers and takes advantage of all that to test picking with the mouse/touch position correctly transformed for each CanvasLayer.
This commit is contained in:
Pedro J. Estébanez 2018-08-25 00:03:26 +02:00
parent 62233423c7
commit 6d0f4a4ad7
15 changed files with 182 additions and 18 deletions

View file

@ -861,6 +861,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);

View file

@ -326,6 +326,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);

View file

@ -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);
}
}
}

View file

@ -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();
@ -179,6 +182,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();
}
@ -198,6 +202,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);

View file

@ -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++) {
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;
}
if (res[i].collider_id && res[i].collider) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
if (co) {
Vector2 point = canvas_transform.affine_inverse().xform(pos);
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;
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);
}
}
}
@ -874,6 +890,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;
@ -2921,6 +2947,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;

View file

@ -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();

View file

@ -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;

View file

@ -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; }

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -323,7 +323,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++)
@ -332,7 +332,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();
@ -351,6 +356,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) {
Vector<Vector2> ret;
@ -391,6 +406,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);
@ -572,6 +588,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);
@ -603,6 +622,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);

View file

@ -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;
@ -402,6 +407,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,