From b91b8fce43ab9cb9f8c96f8c640acc801774b6b5 Mon Sep 17 00:00:00 2001 From: Rindbee Date: Sun, 14 Aug 2022 19:17:45 +0800 Subject: Improve the UX of ViewportTexture in the editor The associated `ViewportTexture`s will update the `viewport_path` in time when the `Viewport`'s nodepath is changed (caused by renaming the node names or moving in the SceneTree dock). If the target `Viewport` is changed by resetting the `viewport_path`, the `ViewportTexture`s will be re-setup and emit `changed` signal in time. (cherry picked from commit af58f1e8547c8b6a2e6b83b7de9c3ac9bc05d881) --- scene/main/viewport.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++--- scene/main/viewport.h | 2 ++ 2 files changed, 45 insertions(+), 3 deletions(-) (limited to 'scene') diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8bdcd9302f..4aaa2e8f5b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -72,10 +72,9 @@ void ViewportTexture::setup_local_to_scene() { if (vp) { vp->viewport_textures.erase(this); + vp = nullptr; } - vp = nullptr; - if (loc_scene->is_ready()) { _setup_local_to_scene(loc_scene); } else { @@ -91,8 +90,24 @@ void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) { path = p_path; - if (get_local_scene()) { + if (vp) { + vp->viewport_textures.erase(this); + vp = nullptr; + } + + if (proxy_ph.is_valid()) { + RS::get_singleton()->free(proxy_ph); + } + if (proxy.is_valid()) { + RS::get_singleton()->free(proxy); + } + proxy_ph = RID(); + proxy = RID(); + + if (get_local_scene() && !path.is_empty()) { setup_local_to_scene(); + } else { + emit_changed(); } } @@ -171,6 +186,8 @@ void ViewportTexture::_setup_local_to_scene(const Node *p_loc_scene) { proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid); } vp_pending = false; + + emit_changed(); } void ViewportTexture::_bind_methods() { @@ -408,9 +425,28 @@ int Viewport::_sub_window_find(Window *p_window) { return -1; } +void Viewport::_update_viewport_path() { + if (viewport_textures.is_empty()) { + return; + } + + Node *scene_root = get_scene_file_path().is_empty() ? get_owner() : this; + if (!scene_root && is_inside_tree()) { + scene_root = get_tree()->get_edited_scene_root(); + } + if (scene_root && (scene_root == this || scene_root->is_ancestor_of(this))) { + NodePath path_in_scene = scene_root->get_path_to(this); + for (ViewportTexture *E : viewport_textures) { + E->path = path_in_scene; + } + } +} + void Viewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { + _update_viewport_path(); + if (get_parent()) { parent = get_parent()->get_viewport(); RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, parent->get_viewport_rid()); @@ -503,6 +539,10 @@ void Viewport::_notification(int p_what) { RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID()); } break; + case NOTIFICATION_PATH_RENAMED: { + _update_viewport_path(); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (!get_tree()) { return; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index e88e0628dd..de0abec052 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -317,6 +317,8 @@ private: Ref default_texture; HashSet viewport_textures; + void _update_viewport_path(); + SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT; SDFScale sdf_scale = SDF_SCALE_50_PERCENT; -- cgit v1.2.3