From 30076b891a17cb4da94580f1eb6f9a7cc79d5cc0 Mon Sep 17 00:00:00 2001 From: Chase Warrington Date: Fri, 17 Sep 2021 00:06:24 -0400 Subject: [PATCH] Propogate previously unused NOTIFICATION_WORLD_2D_CHANGED, make CanvasItem/Camera2D/CollisionObject2D use it to fix godot/godotengine#52423 --- scene/2d/camera_2d.cpp | 12 ++++++++++++ scene/2d/canvas_item.cpp | 8 ++++++++ scene/2d/collision_object_2d.cpp | 21 +++++++++++++++++++++ scene/main/viewport.cpp | 27 +++++++++++++++++++++++++++ scene/main/viewport.h | 1 + scene/scene_string_names.cpp | 1 + scene/scene_string_names.h | 1 + 7 files changed, 71 insertions(+) diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index c87ebbcc736d..f62a2ce54074 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -272,6 +272,18 @@ void Camera2D::_notification(int p_what) { viewport = nullptr; } break; + case NOTIFICATION_WORLD_2D_CHANGED: { + if (is_current()) { + if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { + viewport->set_canvas_transform(Transform2D()); + } + } + remove_from_group(group_name); + remove_from_group(canvas_group_name); + + _setup_viewport(); + _update_scroll(); + } break; #ifdef TOOLS_ENABLED case NOTIFICATION_DRAW: { if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint()) { diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 7e97872469af..28d53d670baf 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -596,6 +596,13 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { emit_signal(SceneStringNames::get_singleton()->visibility_changed); } break; + case NOTIFICATION_WORLD_2D_CHANGED: { + _exit_canvas(); + _enter_canvas(); + if (get_script_instance()) { + get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_world_2d_changed, nullptr, 0); + } + } break; } } @@ -1199,6 +1206,7 @@ void CanvasItem::_bind_methods() { BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); BIND_CONSTANT(NOTIFICATION_ENTER_CANVAS); BIND_CONSTANT(NOTIFICATION_EXIT_CANVAS); + BIND_CONSTANT(NOTIFICATION_WORLD_2D_CHANGED); } Transform2D CanvasItem::get_canvas_transform() const { diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index fa926404bcdb..e1f436b9247d 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -97,6 +97,27 @@ void CollisionObject2D::_notification(int p_what) { Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, 0); } } break; + + case NOTIFICATION_WORLD_2D_CHANGED: { + Transform2D global_transform = get_global_transform(); + + if (area) { + Physics2DServer::get_singleton()->area_set_transform(rid, global_transform); + } else { + Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform); + } + + RID space = get_world_2d()->get_space(); + if (area) { + Physics2DServer::get_singleton()->area_set_space(rid, space); + } else { + Physics2DServer::get_singleton()->body_set_space(rid, space); + } + + _update_pickable(); + + //get space + } break; } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 01a2ba963475..5ba82f0a22d4 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1017,6 +1017,10 @@ void Viewport::set_world_2d(const Ref &p_world_2d) { _update_listener_2d(); + if (is_inside_tree()) { + _propagate_world_2d_changed(this); + } + if (is_inside_tree()) { current_canvas = find_world_2d()->get_canvas(); VisualServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); @@ -1057,6 +1061,29 @@ void Viewport::_propagate_enter_world(Node *p_node) { } } +void Viewport::_propagate_world_2d_changed(Node *p_node) { + if (p_node != this) { + if (!p_node->is_inside_tree()) { //may not have entered scene yet + return; + } + + if (Object::cast_to(p_node)) { + p_node->notification(CanvasItem::NOTIFICATION_WORLD_2D_CHANGED); + } else { + Viewport *v = Object::cast_to(p_node); + if (v) { + if (v->world_2d.is_valid()) { + return; + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _propagate_world_2d_changed(p_node->get_child(i)); + } +} + void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) { p_node->notification(p_what); for (int i = 0; i < p_node->get_child_count(); i++) { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 360f75860452..300f17c33401 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -260,6 +260,7 @@ class Viewport : public Node { void _propagate_enter_world(Node *p_node); void _propagate_exit_world(Node *p_node); + void _propagate_world_2d_changed(Node *p_node); void _propagate_viewport_notification(Node *p_node, int p_what); void _update_stretch_transform(); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index aecdd425f692..4df0c354821f 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -96,6 +96,7 @@ SceneStringNames::SceneStringNames() { _exit_tree = StaticCString::create("_exit_tree"); _enter_world = StaticCString::create("_enter_world"); _exit_world = StaticCString::create("_exit_world"); + _world_2d_changed = StaticCString::create("_world_2d_changed"); _ready = StaticCString::create("_ready"); _update_scroll = StaticCString::create("_update_scroll"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 338b2fd5c2b6..bf9877b3b81a 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -112,6 +112,7 @@ class SceneStringNames { StringName _process; StringName _enter_world; StringName _exit_world; + StringName _world_2d_changed; StringName _enter_tree; StringName _exit_tree; StringName _draw;