diff options
Diffstat (limited to 'scene')
-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-- | scene/resources/shape.cpp | 2 |
7 files changed, 81 insertions, 17 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/scene/resources/shape.cpp b/scene/resources/shape.cpp index 869f4a3a9b..214e2e8edc 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -101,7 +101,7 @@ void Shape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape::set_margin); ClassDB::bind_method(D_METHOD("get_margin"), &Shape::get_margin); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.04,10,0.001"), "set_margin", "get_margin"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin"); } Shape::Shape() : |