diff options
Diffstat (limited to 'scene/main/viewport.cpp')
-rw-r--r-- | scene/main/viewport.cpp | 113 |
1 files changed, 89 insertions, 24 deletions
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index c8d2d71c2a..26128a08ab 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -54,7 +54,6 @@ #include "scene/resources/mesh.h" #include "scene/resources/text_line.h" #include "scene/resources/world_2d.h" -#include "scene/scene_string_names.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_globals.h" @@ -81,7 +80,7 @@ void ViewportTexture::setup_local_to_scene() { if (loc_scene->is_ready()) { _setup_local_to_scene(loc_scene); } else { - loc_scene->connect(SNAME("ready"), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT); + loc_scene->connect(SceneStringName(ready), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT); vp_pending = true; } } @@ -688,6 +687,18 @@ void Viewport::_process_picking() { physics_picking_events.clear(); return; } +#ifndef _3D_DISABLED + if (use_xr) { + if (XRServer::get_singleton() != nullptr) { + Ref<XRInterface> xr_interface = XRServer::get_singleton()->get_primary_interface(); + if (xr_interface.is_valid() && xr_interface->is_initialized() && xr_interface->get_view_count() > 1) { + WARN_PRINT_ONCE("Object picking can't be used when stereo rendering, this will be turned off!"); + physics_object_picking = false; // don't try again. + return; + } + } + } +#endif _drop_physics_mouseover(true); @@ -856,9 +867,10 @@ void Viewport::_process_picking() { if (send_event) { co->_input_event_call(this, ev, res[i].shape); - if (physics_object_picking_first_only) { - break; - } + } + + if (physics_object_picking_first_only) { + break; } } } @@ -970,7 +982,7 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override, stretch_transform_new.scale(scale); } - Size2i new_size = p_size.max(Size2i(2, 2)); + Size2i new_size = p_size.maxi(2); if (size == new_size && size_allocated == p_allocated && stretch_transform == stretch_transform_new && p_size_2d_override == size_2d_override) { return; } @@ -1452,7 +1464,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_label->set_theme_type_variation(SNAME("TooltipLabel")); gui.tooltip_label->set_text(gui.tooltip_text); base_tooltip = gui.tooltip_label; - panel->connect("mouse_entered", callable_mp(this, &Viewport::_gui_cancel_tooltip)); + panel->connect(SceneStringName(mouse_entered), callable_mp(this, &Viewport::_gui_cancel_tooltip)); } base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); @@ -1461,6 +1473,8 @@ void Viewport::_gui_show_tooltip() { panel->set_flag(Window::FLAG_NO_FOCUS, true); panel->set_flag(Window::FLAG_POPUP, false); panel->set_flag(Window::FLAG_MOUSE_PASSTHROUGH, true); + // A non-embedded tooltip window will only be transparent if per_pixel_transparency is allowed in the main Viewport. + panel->set_flag(Window::FLAG_TRANSPARENT, true); panel->set_wrap_controls(true); panel->add_child(base_tooltip); panel->gui_parent = this; @@ -1469,17 +1483,25 @@ void Viewport::_gui_show_tooltip() { tooltip_owner->add_child(gui.tooltip_popup); + Window *window = Object::cast_to<Window>(gui.tooltip_popup->get_embedder()); + if (!window) { // Not embedded. + window = gui.tooltip_popup->get_parent_visible_window(); + } + float win_scale = window->content_scale_factor; Point2 tooltip_offset = GLOBAL_GET("display/mouse_cursor/tooltip_position_offset"); + if (!gui.tooltip_popup->is_embedded()) { + tooltip_offset *= win_scale; + } Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size()); - r.size = r.size.min(panel->get_max_size()); - - Window *window = gui.tooltip_popup->get_parent_visible_window(); Rect2i vr; if (gui.tooltip_popup->is_embedded()) { vr = gui.tooltip_popup->get_embedder()->get_visible_rect(); } else { + panel->content_scale_factor = win_scale; + r.size *= win_scale; vr = window->get_usable_parent_rect(); } + r.size = r.size.min(panel->get_max_size()); if (r.size.x + r.position.x > vr.size.x + vr.position.x) { // Place it in the opposite direction. If it fails, just hug the border. @@ -1705,12 +1727,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Point2 mpos = mb->get_position(); if (mb->is_pressed()) { - if (!gui.mouse_focus_mask.is_empty()) { - // Do not steal mouse focus and stuff while a focus mask exists. - gui.mouse_focus_mask.set_flag(mouse_button_to_mask(mb->get_button_index())); + MouseButtonMask button_mask = mouse_button_to_mask(mb->get_button_index()); + if (!gui.mouse_focus_mask.is_empty() && !gui.mouse_focus_mask.has_flag(button_mask)) { + // Do not steal mouse focus and stuff while a focus mask without the current mouse button exists. + gui.mouse_focus_mask.set_flag(button_mask); } else { gui.mouse_focus = gui_find_control(mpos); - gui.last_mouse_focus = gui.mouse_focus; if (!gui.mouse_focus) { return; @@ -2295,6 +2317,7 @@ void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control * gui.dragging = true; gui.drag_data = p_data; gui.mouse_focus = nullptr; + gui.mouse_focus_mask.clear(); if (p_control) { _gui_set_drag_preview(p_base, p_control); @@ -2350,7 +2373,7 @@ void Viewport::_gui_hide_control(Control *p_control) { if (gui.key_focus == p_control) { gui_release_focus(); } - if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.find(p_control) >= 0) { + if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.has(p_control)) { _drop_mouse_over(p_control->get_parent_control()); } if (gui.drag_mouse_over == p_control) { @@ -2367,13 +2390,10 @@ void Viewport::_gui_remove_control(Control *p_control) { gui.forced_mouse_focus = false; gui.mouse_focus_mask.clear(); } - if (gui.last_mouse_focus == p_control) { - gui.last_mouse_focus = nullptr; - } if (gui.key_focus == p_control) { gui.key_focus = nullptr; } - if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.find(p_control) >= 0) { + if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.has(p_control)) { _drop_mouse_over(p_control->get_parent_control()); } if (gui.drag_mouse_over == p_control) { @@ -2747,8 +2767,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { Size2i min_size = gui.currently_dragged_subwindow->get_min_size(); Size2i min_size_clamped = gui.currently_dragged_subwindow->get_clamped_minimum_size(); - min_size_clamped.x = MAX(min_size_clamped.x, 1); - min_size_clamped.y = MAX(min_size_clamped.y, 1); + min_size_clamped = min_size_clamped.maxi(1); Rect2i r = gui.subwindow_resize_from_rect; @@ -2809,8 +2828,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { Size2i max_size = gui.currently_dragged_subwindow->get_max_size(); if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) { - max_size.x = MAX(max_size.x, 1); - max_size.y = MAX(max_size.y, 1); + max_size = max_size.maxi(1); if (r.size.x > max_size.x) { r.size.x = max_size.x; @@ -3569,6 +3587,13 @@ bool Viewport::gui_is_drag_successful() const { return gui.drag_successful; } +void Viewport::gui_cancel_drag() { + ERR_MAIN_THREAD_GUARD; + if (gui_is_dragging()) { + _perform_drop(); + } +} + void Viewport::set_input_as_handled() { ERR_MAIN_THREAD_GUARD; if (!handle_input_locally) { @@ -3709,6 +3734,28 @@ Viewport::VRSMode Viewport::get_vrs_mode() const { return vrs_mode; } +void Viewport::set_vrs_update_mode(VRSUpdateMode p_vrs_update_mode) { + ERR_MAIN_THREAD_GUARD; + + vrs_update_mode = p_vrs_update_mode; + switch (p_vrs_update_mode) { + case VRS_UPDATE_ONCE: { + RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_ONCE); + } break; + case VRS_UPDATE_ALWAYS: { + RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_ALWAYS); + } break; + default: { + RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_DISABLED); + } break; + } +} + +Viewport::VRSUpdateMode Viewport::get_vrs_update_mode() const { + ERR_READ_THREAD_GUARD_V(VRS_UPDATE_DISABLED); + return vrs_update_mode; +} + void Viewport::set_vrs_texture(Ref<Texture2D> p_texture) { ERR_MAIN_THREAD_GUARD; vrs_texture = p_texture; @@ -4488,6 +4535,10 @@ void Viewport::set_use_xr(bool p_use_xr) { } else { RS::get_singleton()->viewport_set_size(viewport, 0, 0); } + + // Reset render target override textures. + RID rt = RS::get_singleton()->viewport_get_render_target(viewport); + RSG::texture_storage->render_target_set_override(rt, RID(), RID(), RID()); } } } @@ -4745,6 +4796,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_vrs_mode", "mode"), &Viewport::set_vrs_mode); ClassDB::bind_method(D_METHOD("get_vrs_mode"), &Viewport::get_vrs_mode); + ClassDB::bind_method(D_METHOD("set_vrs_update_mode", "mode"), &Viewport::set_vrs_update_mode); + ClassDB::bind_method(D_METHOD("get_vrs_update_mode"), &Viewport::get_vrs_update_mode); + ClassDB::bind_method(D_METHOD("set_vrs_texture", "texture"), &Viewport::set_vrs_texture); ClassDB::bind_method(D_METHOD("get_vrs_texture"), &Viewport::get_vrs_texture); @@ -4777,6 +4831,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1"), "set_fsr_sharpness", "get_fsr_sharpness"); ADD_GROUP("Variable Rate Shading", "vrs_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "vrs_mode", PROPERTY_HINT_ENUM, "Disabled,Texture,Depth buffer,XR"), "set_vrs_mode", "get_vrs_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "vrs_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,Always"), "set_vrs_update_mode", "get_vrs_update_mode"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "vrs_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_vrs_texture", "get_vrs_texture"); #endif ADD_GROUP("Canvas Items", "canvas_item_"); @@ -4843,6 +4898,7 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_VISIBLE); BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_SHADOW); + BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_CANVAS); BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_MAX); BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED); @@ -4899,12 +4955,21 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(VRS_TEXTURE); BIND_ENUM_CONSTANT(VRS_XR); BIND_ENUM_CONSTANT(VRS_MAX); + + BIND_ENUM_CONSTANT(VRS_UPDATE_DISABLED); + BIND_ENUM_CONSTANT(VRS_UPDATE_ONCE); + BIND_ENUM_CONSTANT(VRS_UPDATE_ALWAYS); + BIND_ENUM_CONSTANT(VRS_UPDATE_MAX); } void Viewport::_validate_property(PropertyInfo &p_property) const { if (vrs_mode != VRS_TEXTURE && (p_property.name == "vrs_texture")) { p_property.usage = PROPERTY_USAGE_NO_EDITOR; } + + if (vrs_mode == VRS_DISABLED && (p_property.name == "vrs_update_mode")) { + p_property.usage = PROPERTY_USAGE_NO_EDITOR; + } } Viewport::Viewport() { @@ -4940,7 +5005,7 @@ Viewport::Viewport() { unhandled_key_input_group = "_vp_unhandled_key_input" + id; // Window tooltip. - gui.tooltip_delay = GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"), 0.5); + gui.tooltip_delay = GLOBAL_GET("gui/timers/tooltip_delay_sec"); #ifndef _3D_DISABLED set_scaling_3d_mode((Viewport::Scaling3DMode)(int)GLOBAL_GET("rendering/scaling_3d/mode")); |