summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRindbee <idleman@yeah.net>2022-08-14 19:17:45 +0800
committerRĂ©mi Verschelde <rverschelde@gmail.com>2023-05-12 12:31:22 +0200
commitb91b8fce43ab9cb9f8c96f8c640acc801774b6b5 (patch)
tree3c3eb5511ddef46a86c6b5a305264630c47febfa
parent1146172b302a68393e4f97b47e6460d78db75518 (diff)
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)
-rw-r--r--doc/classes/ViewportTexture.xml1
-rw-r--r--editor/editor_properties.cpp1
-rw-r--r--scene/main/viewport.cpp46
-rw-r--r--scene/main/viewport.h2
4 files changed, 46 insertions, 4 deletions
diff --git a/doc/classes/ViewportTexture.xml b/doc/classes/ViewportTexture.xml
index 8ecda45bd6..36390863cf 100644
--- a/doc/classes/ViewportTexture.xml
+++ b/doc/classes/ViewportTexture.xml
@@ -17,6 +17,7 @@
<members>
<member name="viewport_path" type="NodePath" setter="set_viewport_path_in_scene" getter="get_viewport_path_in_scene" default="NodePath(&quot;&quot;)">
The path to the [Viewport] node to display. This is relative to the scene root, not to the node which uses the texture.
+ [b]Note:[/b] In the editor, it is automatically updated when the target viewport's node path changes due to renaming or moving the viewport or its ancestors. At runtime, it may not be able to automatically update due to the inability to determine the scene root.
</member>
</members>
</class>
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 01a574def6..348e1ead4a 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -3998,7 +3998,6 @@ void EditorPropertyResource::_viewport_selected(const NodePath &p_path) {
Ref<ViewportTexture> vt;
vt.instantiate();
vt->set_viewport_path_in_scene(get_tree()->get_edited_scene_root()->get_path_to(to_node));
- vt->setup_local_to_scene();
emit_changed(get_edited_property(), vt);
update_property();
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<ViewportTexture> default_texture;
HashSet<ViewportTexture *> viewport_textures;
+ void _update_viewport_path();
+
SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT;
SDFScale sdf_scale = SDF_SCALE_50_PERCENT;