diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/canvas_item.cpp | 24 | ||||
-rw-r--r-- | scene/main/canvas_item.h | 8 | ||||
-rw-r--r-- | scene/main/canvas_layer.cpp | 6 | ||||
-rw-r--r-- | scene/main/canvas_layer.h | 4 | ||||
-rw-r--r-- | scene/main/http_request.cpp | 19 | ||||
-rw-r--r-- | scene/main/http_request.h | 7 | ||||
-rw-r--r-- | scene/main/instance_placeholder.cpp | 4 | ||||
-rw-r--r-- | scene/main/instance_placeholder.h | 4 | ||||
-rw-r--r-- | scene/main/node.cpp | 132 | ||||
-rw-r--r-- | scene/main/node.h | 15 | ||||
-rw-r--r-- | scene/main/resource_preloader.cpp | 6 | ||||
-rw-r--r-- | scene/main/resource_preloader.h | 4 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 16 | ||||
-rw-r--r-- | scene/main/scene_tree.h | 4 | ||||
-rw-r--r-- | scene/main/shader_globals_override.cpp | 4 | ||||
-rw-r--r-- | scene/main/shader_globals_override.h | 4 | ||||
-rw-r--r-- | scene/main/timer.cpp | 4 | ||||
-rw-r--r-- | scene/main/timer.h | 4 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 243 | ||||
-rw-r--r-- | scene/main/viewport.h | 45 | ||||
-rw-r--r-- | scene/main/window.cpp | 34 | ||||
-rw-r--r-- | scene/main/window.h | 9 |
22 files changed, 391 insertions, 209 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 5065684839..c80665cf2e 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -274,9 +274,7 @@ void CanvasItem::_exit_canvas() { void CanvasItem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - _update_texture_filter_changed(false); - _update_texture_repeat_changed(false); - + ERR_FAIL_COND(!is_inside_tree()); first_draw = true; Node *parent = get_parent(); if (parent) { @@ -305,6 +303,10 @@ void CanvasItem::_notification(int p_what) { } } _enter_canvas(); + + _update_texture_filter_changed(false); + _update_texture_repeat_changed(false); + if (!block_transform_notify && !xform_change.in_list()) { get_tree()->xform_change_list.add(&xform_change); } @@ -647,16 +649,16 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid); } -void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { +void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_font.is_null()); - p_font->draw_string(canvas_item, p_pos, p_text, p_align, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); + p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); } -void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { +void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_font.is_null()); - p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_align, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); + p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); } real_t CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate) const { @@ -892,8 +894,8 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()), DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>())); ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>())); - ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "align", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); - ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "align", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &CanvasItem::draw_char, DEFVAL(""), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0))); ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture"), &CanvasItem::draw_multimesh); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 04376ad809..3d49d89746 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -235,8 +235,8 @@ public: void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1)); void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture); - void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; - void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const; void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0)); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 26bff4494b..282ab6b497 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -256,7 +256,7 @@ void CanvasLayer::_update_follow_viewport(bool p_force_exit) { void CanvasLayer::_validate_property(PropertyInfo &property) const { if (!follow_viewport && property.name == "follow_viewport_scale") { - property.usage = PROPERTY_USAGE_NOEDITOR; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index 9d8e0c203d..93a0152787 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index a4fcc04e20..34cc4aceb8 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -243,7 +243,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) { } } - if (new_request != "") { + if (!new_request.is_empty()) { // Process redirect client->close(); int new_redirs = redirections + 1; // Because _request() will clear it @@ -363,7 +363,7 @@ bool HTTPRequest::_update_connection() { return true; } - if (download_to_file != String()) { + if (!download_to_file.is_empty()) { file = FileAccess::open(download_to_file, FileAccess::WRITE); if (!file) { call_deferred(SNAME("_request_done"), RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray()); @@ -554,6 +554,14 @@ int HTTPRequest::get_body_size() const { return body_len; } +void HTTPRequest::set_http_proxy(const String &p_host, int p_port) { + client->set_http_proxy(p_host, p_port); +} + +void HTTPRequest::set_https_proxy(const String &p_host, int p_port) { + client->set_https_proxy(p_host, p_port); +} + void HTTPRequest::set_timeout(int p_timeout) { ERR_FAIL_COND(p_timeout < 0); timeout = p_timeout; @@ -602,6 +610,9 @@ void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("set_download_chunk_size", "chunk_size"), &HTTPRequest::set_download_chunk_size); ClassDB::bind_method(D_METHOD("get_download_chunk_size"), &HTTPRequest::get_download_chunk_size); + ClassDB::bind_method(D_METHOD("set_http_proxy", "host", "port"), &HTTPRequest::set_http_proxy); + ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPRequest::set_https_proxy); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file"); ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216"), "set_download_chunk_size", "get_download_chunk_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 673cf3a740..62880fa282 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -154,6 +154,9 @@ public: int get_downloaded_bytes() const; int get_body_size() const; + void set_http_proxy(const String &p_host, int p_port); + void set_https_proxy(const String &p_host, int p_port); + HTTPRequest(); ~HTTPRequest(); }; diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp index b5ba1899ec..6dd83e4636 100644 --- a/scene/main/instance_placeholder.cpp +++ b/scene/main/instance_placeholder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h index fe20fc4760..8f2eb01773 100644 --- a/scene/main/instance_placeholder.h +++ b/scene/main/instance_placeholder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 189aebb47d..bec01762d8 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -114,7 +114,7 @@ void Node::_notification(int p_notification) { get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, false); } } break; - case NOTIFICATION_PATH_CHANGED: { + case NOTIFICATION_PATH_RENAMED: { if (data.path_cache) { memdelete(data.path_cache); data.path_cache = nullptr; @@ -152,12 +152,6 @@ void Node::_notification(int p_notification) { data.in_constructor = false; } break; case NOTIFICATION_PREDELETE: { - set_owner(nullptr); - - while (data.owned.size()) { - data.owned.front()->get()->set_owner(nullptr); - } - if (data.parent) { data.parent->remove_child(this); } @@ -165,10 +159,8 @@ void Node::_notification(int p_notification) { // kill children as cleanly as possible while (data.children.size()) { Node *child = data.children[data.children.size() - 1]; //begin from the end because its faster and more consistent with creation - remove_child(child); memdelete(child); } - } break; } } @@ -237,8 +229,12 @@ void Node::_propagate_enter_tree() { } void Node::_propagate_after_exit_tree() { + if (data.owner) { + data.owner->data.owned.erase(data.OW); + data.owner = nullptr; + } data.blocked++; - for (int i = 0; i < data.children.size(); i++) { + for (int i = data.children.size() - 1; i >= 0; i--) { data.children[i]->_propagate_after_exit_tree(); } data.blocked--; @@ -332,7 +328,7 @@ void Node::_move_child(Node *p_child, int p_pos, bool p_ignore_end) { int motion_from = MIN(p_pos, p_child->data.pos); int motion_to = MAX(p_pos, p_child->data.pos); - data.children.remove(p_child->data.pos); + data.children.remove_at(p_child->data.pos); data.children.insert(p_pos, p_child); if (data.tree) { @@ -892,14 +888,14 @@ void Node::_set_name_nocheck(const StringName &p_name) { void Node::set_name(const String &p_name) { String name = p_name.validate_node_name(); - ERR_FAIL_COND(name == ""); + ERR_FAIL_COND(name.is_empty()); data.name = name; if (data.parent) { - data.parent->_validate_child_name(this); + data.parent->_validate_child_name(this, true); } - propagate_notification(NOTIFICATION_PATH_CHANGED); + propagate_notification(NOTIFICATION_PATH_RENAMED); if (is_inside_tree()) { emit_signal(SNAME("renamed")); @@ -908,17 +904,12 @@ void Node::set_name(const String &p_name) { } } -static bool node_hrcr = false; static SafeRefCount node_hrcr_count; void Node::init_node_hrcr() { node_hrcr_count.init(1); } -void Node::set_human_readable_collision_renaming(bool p_enabled) { - node_hrcr = p_enabled; -} - #ifdef TOOLS_ENABLED String Node::validate_child_name(Node *p_child) { StringName name = p_child->data.name; @@ -930,9 +921,8 @@ String Node::validate_child_name(Node *p_child) { void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { /* Make sure the name is unique */ - if (node_hrcr || p_force_human_readable) { + if (p_force_human_readable) { //this approach to autoset node names is human readable but very slow - //it's turned on while running in the editor StringName name = p_child->data.name; _generate_serial_child_name(p_child, name); @@ -1150,31 +1140,6 @@ void Node::add_sibling(Node *p_sibling, bool p_legible_unique_name) { data.parent->_move_child(p_sibling, get_index() + 1); } -void Node::_propagate_validate_owner() { - if (data.owner) { - bool found = false; - Node *parent = data.parent; - - while (parent) { - if (parent == data.owner) { - found = true; - break; - } - - parent = parent->data.parent; - } - - if (!found) { - data.owner->data.owned.erase(data.OW); - data.owner = nullptr; - } - } - - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_validate_owner(); - } -} - void Node::remove_child(Node *p_child) { ERR_FAIL_NULL(p_child); ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\", child) instead."); @@ -1214,7 +1179,7 @@ void Node::remove_child(Node *p_child) { remove_child_notify(p_child); p_child->notification(NOTIFICATION_UNPARENTED); - data.children.remove(idx); + data.children.remove_at(idx); //update pointer and size child_count = data.children.size(); @@ -1228,9 +1193,6 @@ void Node::remove_child(Node *p_child) { p_child->data.parent = nullptr; p_child->data.pos = -1; - // validate owner - p_child->_propagate_validate_owner(); - if (data.inside_tree) { p_child->_propagate_after_exit_tree(); } @@ -1899,6 +1861,56 @@ Node *Node::get_deepest_editable_node(Node *p_start_node) const { return node; } +#ifdef TOOLS_ENABLED +void Node::set_property_pinned(const String &p_property, bool p_pinned) { + bool current_pinned = false; + bool has_pinned = has_meta("_edit_pinned_properties_"); + Array pinned; + String psa = get_property_store_alias(p_property); + if (has_pinned) { + pinned = get_meta("_edit_pinned_properties_"); + current_pinned = pinned.has(psa); + } + + if (current_pinned != p_pinned) { + if (p_pinned) { + pinned.append(psa); + if (!has_pinned) { + set_meta("_edit_pinned_properties_", pinned); + } + } else { + pinned.erase(psa); + if (pinned.is_empty()) { + remove_meta("_edit_pinned_properties_"); + } + } + } +} + +bool Node::is_property_pinned(const StringName &p_property) const { + if (!has_meta("_edit_pinned_properties_")) { + return false; + } + Array pinned = get_meta("_edit_pinned_properties_"); + String psa = get_property_store_alias(p_property); + return pinned.has(psa); +} + +StringName Node::get_property_store_alias(const StringName &p_property) const { + return p_property; +} +#endif + +void Node::get_storable_properties(Set<StringName> &r_storable_properties) const { + List<PropertyInfo> pi; + get_property_list(&pi); + for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { + if ((E->get().usage & PROPERTY_USAGE_STORAGE)) { + r_storable_properties.insert(E->get().name); + } + } +} + String Node::to_string() { if (get_script_instance()) { bool valid; @@ -1946,7 +1958,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const nip->set_instance_path(ip->get_instance_path()); node = nip; - } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_scene_file_path() != String()) { + } else if ((p_flags & DUPLICATE_USE_INSTANCING) && !get_scene_file_path().is_empty()) { Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path()); ERR_FAIL_COND_V(res.is_null(), nullptr); PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED; @@ -1970,7 +1982,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const ERR_FAIL_COND_V(!node, nullptr); } - if (get_scene_file_path() != "") { //an instance + if (!get_scene_file_path().is_empty()) { //an instance node->set_scene_file_path(get_scene_file_path()); node->data.editable_instance = data.editable_instance; } @@ -2002,7 +2014,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const node_tree.push_back(descendant); - if (descendant->get_scene_file_path() != "" && instance_roots.has(descendant->get_owner())) { + if (!descendant->get_scene_file_path().is_empty() && instance_roots.has(descendant->get_owner())) { instance_roots.push_back(descendant); } } @@ -2750,7 +2762,11 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path); ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path"); +#ifdef TOOLS_ENABLED + ClassDB::bind_method(D_METHOD("_set_property_pinned", "property", "pinned"), &Node::set_property_pinned); +#endif + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path"); { MethodInfo mi; @@ -2781,7 +2797,7 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_INSTANCED); BIND_CONSTANT(NOTIFICATION_DRAG_BEGIN); BIND_CONSTANT(NOTIFICATION_DRAG_END); - BIND_CONSTANT(NOTIFICATION_PATH_CHANGED); + BIND_CONSTANT(NOTIFICATION_PATH_RENAMED); BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS); BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS); BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE); @@ -2841,7 +2857,7 @@ void Node::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority"); ADD_GROUP("Editor Description", "editor_"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "set_editor_description", "get_editor_description"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT), "set_editor_description", "get_editor_description"); GDVIRTUAL_BIND(_process, "delta"); GDVIRTUAL_BIND(_physics_process, "delta"); diff --git a/scene/main/node.h b/scene/main/node.h index e59a7a390a..a1fc672a15 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -172,7 +172,6 @@ private: void _propagate_ready(); void _propagate_exit_tree(); void _propagate_after_exit_tree(); - void _propagate_validate_owner(); void _print_stray_nodes(); void _propagate_process_owner(Node *p_owner, int p_pause_notification, int p_enabled_notification); Array _get_node_and_resource(const NodePath &p_path); @@ -256,7 +255,7 @@ public: NOTIFICATION_INSTANCED = 20, NOTIFICATION_DRAG_BEGIN = 21, NOTIFICATION_DRAG_END = 22, - NOTIFICATION_PATH_CHANGED = 23, + NOTIFICATION_PATH_RENAMED = 23, //NOTIFICATION_TRANSLATION_CHANGED = 24, moved below NOTIFICATION_INTERNAL_PROCESS = 25, NOTIFICATION_INTERNAL_PHYSICS_PROCESS = 26, @@ -363,6 +362,13 @@ public: bool is_editable_instance(const Node *p_node) const; Node *get_deepest_editable_node(Node *p_start_node) const; +#ifdef TOOLS_ENABLED + void set_property_pinned(const String &p_property, bool p_pinned); + bool is_property_pinned(const StringName &p_property) const; + virtual StringName get_property_store_alias(const StringName &p_property) const; +#endif + void get_storable_properties(Set<StringName> &r_storable_properties) const; + virtual String to_string() override; /* NOTIFICATIONS */ @@ -437,7 +443,6 @@ public: void queue_delete(); //hacks for speed - static void set_human_readable_collision_renaming(bool p_enabled); static void init_node_hrcr(); void force_parent_owned() { data.parent_owned = true; } //hack to avoid duplicate nodes diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp index f4c90ee668..49010095ff 100644 --- a/scene/main/resource_preloader.cpp +++ b/scene/main/resource_preloader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -147,7 +147,7 @@ void ResourcePreloader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_resource", "name"), &ResourcePreloader::get_resource); ClassDB::bind_method(D_METHOD("get_resource_list"), &ResourcePreloader::_get_resource_list); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "resources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_resources", "_get_resources"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "resources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_resources", "_get_resources"); } ResourcePreloader::ResourcePreloader() { diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h index 1b7ea3fb9f..aabb109d56 100644 --- a/scene/main/resource_preloader.h +++ b/scene/main/resource_preloader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index a122241cd0..9e4908a23d 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -510,7 +510,7 @@ bool SceneTree::process(double p_time) { cpath = fallback->get_path(); } if (cpath != env_path) { - if (env_path != String()) { + if (!env_path.is_empty()) { fallback = ResourceLoader::load(env_path); if (fallback.is_null()) { //could not load fallback, set as empty @@ -1290,7 +1290,7 @@ void SceneTree::get_argument_options(const StringName &p_function, int p_idx, Li dir_access->list_dir_begin(); String filename = dir_access->get_next(); - while (filename != "") { + while (!filename.is_empty()) { if (filename == "." || filename == "..") { filename = dir_access->get_next(); continue; @@ -1355,9 +1355,9 @@ SceneTree::SceneTree() { const bool use_occlusion_culling = GLOBAL_DEF("rendering/occlusion_culling/use_occlusion_culling", false); root->set_use_occlusion_culling(use_occlusion_culling); - float lod_threshold = GLOBAL_DEF("rendering/mesh_lod/lod_change/threshold_pixels", 1.0); + float mesh_lod_threshold = GLOBAL_DEF("rendering/mesh_lod/lod_change/threshold_pixels", 1.0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/mesh_lod/lod_change/threshold_pixels", PropertyInfo(Variant::FLOAT, "rendering/mesh_lod/lod_change/threshold_pixels", PROPERTY_HINT_RANGE, "0,1024,0.1")); - root->set_lod_threshold(lod_threshold); + root->set_mesh_lod_threshold(mesh_lod_threshold); bool snap_2d_transforms = GLOBAL_DEF("rendering/2d/snap/snap_2d_transforms_to_pixel", false); root->set_snap_2d_transforms_to_pixel(snap_2d_transforms); @@ -1400,7 +1400,7 @@ SceneTree::SceneTree() { ResourceLoader::get_recognized_extensions_for_type("Environment", &exts); String ext_hint; for (const String &E : exts) { - if (ext_hint != String()) { + if (!ext_hint.is_empty()) { ext_hint += ","; } ext_hint += "*." + E; @@ -1410,7 +1410,7 @@ SceneTree::SceneTree() { // Setup property. ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/defaults/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint)); env_path = env_path.strip_edges(); - if (env_path != String()) { + if (!env_path.is_empty()) { Ref<Environment> env = ResourceLoader::load(env_path); if (env.is_valid()) { root->get_world_3d()->set_fallback_environment(env); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 7a4f9f9c52..1dff1dab4f 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 9477e300d1..240e662efb 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h index ab4b9de727..af99bf9aa7 100644 --- a/scene/main/shader_globals_override.h +++ b/scene/main/shader_globals_override.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 154e4cf683..babe62f453 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/timer.h b/scene/main/timer.h index e2f34042dd..8785d31a8a 100644 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 6388b375d9..0a9f98bb2f 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,6 +55,7 @@ #include "scene/resources/world_2d.h" #include "scene/scene_string_names.h" #include "servers/audio_server.h" +#include "servers/rendering/rendering_server_globals.h" void ViewportTexture::setup_local_to_scene() { Node *local_scene = get_local_scene(); @@ -290,7 +291,7 @@ void Viewport::_sub_window_grab_focus(Window *p_window) { if (p_window->get_flag(Window::FLAG_NO_FOCUS)) { // Can only move to foreground, but no focus granted. SubWindow sw = gui.sub_windows[index]; - gui.sub_windows.remove(index); + gui.sub_windows.remove_at(index); gui.sub_windows.push_back(sw); index = gui.sub_windows.size() - 1; _sub_window_update_order(); @@ -318,7 +319,7 @@ void Viewport::_sub_window_grab_focus(Window *p_window) { { // Move to foreground. SubWindow sw = gui.sub_windows[index]; - gui.sub_windows.remove(index); + gui.sub_windows.remove_at(index); gui.sub_windows.push_back(sw); index = gui.sub_windows.size() - 1; _sub_window_update_order(); @@ -335,7 +336,7 @@ void Viewport::_sub_window_remove(Window *p_window) { for (int i = 0; i < gui.sub_windows.size(); i++) { if (gui.sub_windows[i].window == p_window) { RS::get_singleton()->free(gui.sub_windows[i].canvas_item); - gui.sub_windows.remove(i); + gui.sub_windows.remove_at(i); break; } } @@ -395,14 +396,15 @@ void Viewport::_notification(int p_what) { #ifndef _3D_DISABLED PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count()); contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create(); - RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true); + RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, false); RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0); RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid()); contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create(); RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh); RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario()); - //RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true); + RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); #endif // _3D_DISABLED + set_physics_process_internal(true); } } break; @@ -460,6 +462,10 @@ void Viewport::_notification(int p_what) { RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID()); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (!get_tree()) { + return; + } + if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) { RenderingServer::get_singleton()->canvas_item_clear(contact_2d_debug); RenderingServer::get_singleton()->canvas_item_set_draw_index(contact_2d_debug, 0xFFFFF); //very high index @@ -584,9 +590,9 @@ void Viewport::_process_picking() { physics_last_mouse_state.meta = mb->is_meta_pressed(); if (mb->is_pressed()) { - physics_last_mouse_state.mouse_mask |= (MouseButton)(1 << (mb->get_button_index() - 1)); + physics_last_mouse_state.mouse_mask |= mouse_button_to_mask(mb->get_button_index()); } else { - physics_last_mouse_state.mouse_mask &= (MouseButton) ~(1 << (mb->get_button_index() - 1)); + physics_last_mouse_state.mouse_mask &= ~mouse_button_to_mask(mb->get_button_index()); // If touch mouse raised, assume we don't know last mouse pos until new events come if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) { @@ -638,7 +644,13 @@ void Viewport::_process_picking() { 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); + PhysicsDirectSpaceState2D::PointParameters point_params; + point_params.position = point; + point_params.canvas_instance_id = canvas_layer_id; + point_params.collide_with_areas = true; + point_params.pick_point = true; + + int rc = ss2d->intersect_point(point_params, res, 64); for (int i = 0; i < rc; i++) { if (res[i].collider_id.is_valid() && res[i].collider) { CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); @@ -690,7 +702,7 @@ void Viewport::_process_picking() { if (co && camera_3d) { _collision_object_3d_input_event(co, camera_3d, ev, Vector3(), Vector3(), 0); captured = true; - if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { physics_object_capture = ObjectID(); } @@ -706,7 +718,7 @@ void Viewport::_process_picking() { if (ObjectDB::get_instance(last_id) && last_object) { // Good, exists. _collision_object_3d_input_event(last_object, camera_3d, ev, result.position, result.normal, result.shape); - if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { + if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { physics_object_capture = last_id; } } @@ -715,10 +727,17 @@ void Viewport::_process_picking() { if (camera_3d) { Vector3 from = camera_3d->project_ray_origin(pos); Vector3 dir = camera_3d->project_ray_normal(pos); + real_t far = camera_3d->far; PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space()); if (space) { - bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); + PhysicsDirectSpaceState3D::RayParameters ray_params; + ray_params.from = from; + ray_params.to = from + dir * far; + ray_params.collide_with_areas = true; + ray_params.pick_ray = true; + + bool col = space->intersect_ray(ray_params, result); ObjectID new_collider; if (col) { CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); @@ -727,7 +746,7 @@ void Viewport::_process_picking() { last_object = co; last_id = result.collider_id; new_collider = last_id; - if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { + if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { physics_object_capture = last_id; } } @@ -1246,10 +1265,10 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu Ref<InputEventMouseButton> mb = p_input; bool cant_stop_me_now = (mb.is_valid() && - (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN || - mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP || - mb->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT || - mb->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT)); + (mb->get_button_index() == MouseButton::WHEEL_DOWN || + mb->get_button_index() == MouseButton::WHEEL_UP || + mb->get_button_index() == MouseButton::WHEEL_LEFT || + mb->get_button_index() == MouseButton::WHEEL_RIGHT)); Ref<InputEventPanGesture> pn = p_input; cant_stop_me_now = pn.is_valid() || cant_stop_me_now; @@ -1432,21 +1451,21 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.last_mouse_pos = mpos; if (mb->is_pressed()) { Size2 pos = mpos; - if (gui.mouse_focus_mask) { + if (gui.mouse_focus_mask != MouseButton::NONE) { // Do not steal mouse focus and stuff while a focus mask exists. - gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); // Add the button to the mask. + gui.mouse_focus_mask |= mouse_button_to_mask(mb->get_button_index()); } else { gui.mouse_focus = gui_find_control(pos); gui.last_mouse_focus = gui.mouse_focus; if (!gui.mouse_focus) { - gui.mouse_focus_mask = 0; + gui.mouse_focus_mask = MouseButton::NONE; return; } - gui.mouse_focus_mask = 1 << (mb->get_button_index() - 1); + gui.mouse_focus_mask = mouse_button_to_mask(mb->get_button_index()); - if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (mb->get_button_index() == MouseButton::LEFT) { gui.drag_accum = Vector2(); gui.drag_attempted = false; } @@ -1469,7 +1488,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } #endif - if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { // Assign focus. + if (mb->get_button_index() == MouseButton::LEFT) { // Assign focus. CanvasItem *ci = gui.mouse_focus; while (ci) { Control *control = Object::cast_to<Control>(ci); @@ -1500,10 +1519,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { set_input_as_handled(); - if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) { // Alternate drop use (when using force_drag(), as proposed by #5342). + gui.drag_successful = false; if (gui.mouse_focus) { - _gui_drop(gui.mouse_focus, pos, false); + gui.drag_successful = _gui_drop(gui.mouse_focus, pos, false); } gui.drag_data = Variant(); @@ -1520,9 +1540,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { _gui_cancel_tooltip(); } else { - if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) { + gui.drag_successful = false; if (gui.drag_mouse_over) { - _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false); + gui.drag_successful = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false); } Control *drag_preview = _gui_get_drag_preview(); @@ -1538,7 +1559,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { // Change mouse accordingly. } - gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); // Remove from mask. + gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask. if (!gui.mouse_focus) { // Release event is only sent if a mouse focus (previously pressed button) exists. @@ -1557,7 +1578,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { // Disable mouse focus if needed before calling input, // this makes popups on mouse press event work better, // as the release will never be received otherwise. - if (gui.mouse_focus_mask == 0) { + if (gui.mouse_focus_mask == MouseButton::NONE) { gui.mouse_focus = nullptr; gui.forced_mouse_focus = false; } @@ -1577,7 +1598,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { over = gui_find_control(mpos); } - if (gui.mouse_focus_mask == 0 && over != gui.mouse_over) { + if (gui.mouse_focus_mask == MouseButton::NONE && over != gui.mouse_over) { if (gui.mouse_over) { _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); } @@ -1605,7 +1626,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Control *over = nullptr; // Drag & drop. - if (!gui.drag_attempted && gui.mouse_focus && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { + if (!gui.drag_attempted && gui.mouse_focus && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { gui.drag_accum += mm->get_relative(); float len = gui.drag_accum.length(); if (len > 10) { @@ -1619,7 +1640,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.drag_data.get_type() != Variant::NIL) { gui.mouse_focus = nullptr; gui.forced_mouse_focus = false; - gui.mouse_focus_mask = 0; + gui.mouse_focus_mask = MouseButton::NONE; break; } else { Control *drag_preview = _gui_get_drag_preview(); @@ -1688,15 +1709,13 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { mm->set_speed(speed); mm->set_relative(rel); - if (mm->get_button_mask() == 0) { + if (mm->get_button_mask() == MouseButton::NONE) { // Nothing pressed. - bool can_tooltip = true; - bool is_tooltip_shown = false; if (gui.tooltip_popup) { - if (can_tooltip && gui.tooltip_control) { + if (gui.tooltip_control) { String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform().xform_inv(mpos)); if (tooltip.length() == 0) { @@ -1721,7 +1740,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } - if (can_tooltip && !is_tooltip_shown) { + if (!is_tooltip_shown && over->can_process()) { if (gui.tooltip_timer.is_valid()) { gui.tooltip_timer->release_connections(); gui.tooltip_timer = Ref<SceneTreeTimer>(); @@ -1741,7 +1760,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Control *c = over; Vector2 cpos = pos; while (c) { - if (gui.mouse_focus_mask != 0 || c->has_point(cpos)) { + if (gui.mouse_focus_mask != MouseButton::NONE || c->has_point(cpos)) { cursor_shape = c->get_cursor_shape(cpos); } else { cursor_shape = Control::CURSOR_ARROW; @@ -1854,14 +1873,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse(); gui.drag_mouse_over_pos = localizer.xform(viewport_pos); - if (mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { - bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true); + bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true); - if (!can_drop) { - ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN; - } else { - ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP; - } + if (!can_drop) { + ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN; + } else { + ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP; } } @@ -2029,6 +2046,7 @@ void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control * if (p_control) { _gui_set_drag_preview(p_base, p_control); } + _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN); } void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) { @@ -2095,7 +2113,7 @@ void Viewport::_gui_remove_control(Control *p_control) { if (gui.mouse_focus == p_control) { gui.mouse_focus = nullptr; gui.forced_mouse_focus = false; - gui.mouse_focus_mask = 0; + gui.mouse_focus_mask = MouseButton::NONE; } if (gui.last_mouse_focus == p_control) { gui.last_mouse_focus = nullptr; @@ -2165,13 +2183,13 @@ void Viewport::_gui_accept_event() { void Viewport::_drop_mouse_focus() { Control *c = gui.mouse_focus; - int mask = gui.mouse_focus_mask; + MouseButton mask = gui.mouse_focus_mask; gui.mouse_focus = nullptr; gui.forced_mouse_focus = false; - gui.mouse_focus_mask = 0; + gui.mouse_focus_mask = MouseButton::NONE; for (int i = 0; i < 3; i++) { - if (mask & (1 << i)) { + if ((int)mask & (1 << i)) { Ref<InputEventMouseButton> mb; mb.instantiate(); mb->set_position(c->get_local_mouse_position()); @@ -2280,11 +2298,11 @@ void Viewport::_post_gui_grab_click_focus() { return; } - int mask = gui.mouse_focus_mask; + MouseButton mask = gui.mouse_focus_mask; Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); for (int i = 0; i < 3; i++) { - if (mask & (1 << i)) { + if ((int)mask & (1 << i)) { Ref<InputEventMouseButton> mb; mb.instantiate(); @@ -2302,7 +2320,7 @@ void Viewport::_post_gui_grab_click_focus() { click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); for (int i = 0; i < 3; i++) { - if (mask & (1 << i)) { + if ((int)mask & (1 << i)) { Ref<InputEventMouseButton> mb; mb.instantiate(); @@ -2399,7 +2417,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND_V(gui.subwindow_focused == nullptr, false); Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) { if (gui.subwindow_drag_close_rect.has_point(mb->get_position())) { // Close window. @@ -2524,7 +2542,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; // If the event is a mouse button, we need to check whether another window was clicked. - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { bool click_on_window = false; for (int i = gui.sub_windows.size() - 1; i >= 0; i--) { SubWindow &sw = gui.sub_windows.write[i]; @@ -2815,13 +2833,13 @@ bool Viewport::is_using_debanding() const { return use_debanding; } -void Viewport::set_lod_threshold(float p_pixels) { - lod_threshold = p_pixels; - RS::get_singleton()->viewport_set_lod_threshold(viewport, lod_threshold); +void Viewport::set_mesh_lod_threshold(float p_pixels) { + mesh_lod_threshold = p_pixels; + RS::get_singleton()->viewport_set_mesh_lod_threshold(viewport, mesh_lod_threshold); } -float Viewport::get_lod_threshold() const { - return lod_threshold; +float Viewport::get_mesh_lod_threshold() const { + return mesh_lod_threshold; } void Viewport::set_use_occlusion_culling(bool p_use_occlusion_culling) { @@ -2882,6 +2900,10 @@ bool Viewport::gui_is_dragging() const { return gui.dragging; } +bool Viewport::gui_is_drag_successful() const { + return gui.drag_successful; +} + void Viewport::set_input_as_handled() { _drop_physics_mouseover(); @@ -3028,7 +3050,7 @@ void Viewport::pass_mouse_focus_to(Viewport *p_viewport, Control *p_control) { gui.mouse_focus = nullptr; gui.forced_mouse_focus = false; - gui.mouse_focus_mask = 0; + gui.mouse_focus_mask = MouseButton::NONE; } } @@ -3454,17 +3476,60 @@ bool Viewport::is_using_xr() { return use_xr; } -void Viewport::set_scale_3d(float p_scale_3d) { +void Viewport::set_scaling_3d_mode(Scaling3DMode p_scaling_3d_mode) { + if (scaling_3d_mode == p_scaling_3d_mode) { + return; + } + + scaling_3d_mode = p_scaling_3d_mode; + RS::get_singleton()->viewport_set_scaling_3d_mode(viewport, (RS::ViewportScaling3DMode)(int)p_scaling_3d_mode); +} + +Viewport::Scaling3DMode Viewport::get_scaling_3d_mode() const { + return scaling_3d_mode; +} + +void Viewport::set_scaling_3d_scale(float p_scaling_3d_scale) { // Clamp to reasonable values that are actually useful. // Values above 2.0 don't serve a practical purpose since the viewport // isn't displayed with mipmaps. - scale_3d = CLAMP(p_scale_3d, 0.1, 2.0); + scaling_3d_scale = CLAMP(p_scaling_3d_scale, 0.1, 2.0); - RS::get_singleton()->viewport_set_scale_3d(viewport, scale_3d); + RS::get_singleton()->viewport_set_scaling_3d_scale(viewport, scaling_3d_scale); } -float Viewport::get_scale_3d() const { - return scale_3d; +float Viewport::get_scaling_3d_scale() const { + return scaling_3d_scale; +} + +void Viewport::set_fsr_sharpness(float p_fsr_sharpness) { + if (fsr_sharpness == p_fsr_sharpness) { + return; + } + + if (p_fsr_sharpness < 0.0f) { + p_fsr_sharpness = 0.0f; + } + + fsr_sharpness = p_fsr_sharpness; + RS::get_singleton()->viewport_set_fsr_sharpness(viewport, p_fsr_sharpness); +} + +float Viewport::get_fsr_sharpness() const { + return fsr_sharpness; +} + +void Viewport::set_fsr_mipmap_bias(float p_fsr_mipmap_bias) { + if (fsr_mipmap_bias == p_fsr_mipmap_bias) { + return; + } + + fsr_mipmap_bias = p_fsr_mipmap_bias; + RS::get_singleton()->viewport_set_fsr_mipmap_bias(viewport, p_fsr_mipmap_bias); +} + +float Viewport::get_fsr_mipmap_bias() const { + return fsr_mipmap_bias; } #endif // _3D_DISABLED @@ -3521,6 +3586,7 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("gui_get_drag_data"), &Viewport::gui_get_drag_data); ClassDB::bind_method(D_METHOD("gui_is_dragging"), &Viewport::gui_is_dragging); + ClassDB::bind_method(D_METHOD("gui_is_drag_successful"), &Viewport::gui_is_drag_successful); ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input); ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled); @@ -3568,8 +3634,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sdf_scale", "scale"), &Viewport::set_sdf_scale); ClassDB::bind_method(D_METHOD("get_sdf_scale"), &Viewport::get_sdf_scale); - ClassDB::bind_method(D_METHOD("set_lod_threshold", "pixels"), &Viewport::set_lod_threshold); - ClassDB::bind_method(D_METHOD("get_lod_threshold"), &Viewport::get_lod_threshold); + ClassDB::bind_method(D_METHOD("set_mesh_lod_threshold", "pixels"), &Viewport::set_mesh_lod_threshold); + ClassDB::bind_method(D_METHOD("get_mesh_lod_threshold"), &Viewport::get_mesh_lod_threshold); ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking); @@ -3591,12 +3657,20 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &Viewport::set_use_xr); ClassDB::bind_method(D_METHOD("is_using_xr"), &Viewport::is_using_xr); - ClassDB::bind_method(D_METHOD("set_scale_3d", "scale"), &Viewport::set_scale_3d); - ClassDB::bind_method(D_METHOD("get_scale_3d"), &Viewport::get_scale_3d); + ClassDB::bind_method(D_METHOD("set_scaling_3d_mode", "scaling_3d_mode"), &Viewport::set_scaling_3d_mode); + ClassDB::bind_method(D_METHOD("get_scaling_3d_mode"), &Viewport::get_scaling_3d_mode); + + ClassDB::bind_method(D_METHOD("set_scaling_3d_scale", "scale"), &Viewport::set_scaling_3d_scale); + ClassDB::bind_method(D_METHOD("get_scaling_3d_scale"), &Viewport::get_scaling_3d_scale); + + ClassDB::bind_method(D_METHOD("set_fsr_sharpness", "fsr_sharpness"), &Viewport::set_fsr_sharpness); + ClassDB::bind_method(D_METHOD("get_fsr_sharpness"), &Viewport::get_fsr_sharpness); + + ClassDB::bind_method(D_METHOD("set_fsr_mipmap_bias", "fsr_mipmap_bias"), &Viewport::set_fsr_mipmap_bias); + ClassDB::bind_method(D_METHOD("get_fsr_mipmap_bias"), &Viewport::get_fsr_mipmap_bias); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scale_3d", PROPERTY_HINT_RANGE, "0.25,2.0,0.01"), "set_scale_3d", "get_scale_3d"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d"); @@ -3611,8 +3685,15 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mesh_lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_mesh_lod_threshold", "get_mesh_lod_threshold"); ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); +#ifndef _3D_DISABLED + ADD_GROUP("Scaling 3D", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Disabled (Slowest),Bilinear (Fastest),FSR (Fast)"), "set_scaling_3d_mode", "get_scaling_3d_mode"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scaling_3d_scale", PROPERTY_HINT_RANGE, "0.25,2.0,0.01"), "set_scaling_3d_scale", "get_scaling_3d_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.1"), "set_fsr_mipmap_bias", "get_fsr_mipmap_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1"), "set_fsr_sharpness", "get_fsr_sharpness"); +#endif ADD_GROUP("Canvas Items", "canvas_item_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Linear Mipmap,Nearest Mipmap"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirror"), "set_default_canvas_item_texture_repeat", "get_default_canvas_item_texture_repeat"); @@ -3649,6 +3730,10 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); + BIND_ENUM_CONSTANT(SCALING_3D_MODE_BILINEAR); + BIND_ENUM_CONSTANT(SCALING_3D_MODE_FSR); + BIND_ENUM_CONSTANT(SCALING_3D_MODE_MAX); + BIND_ENUM_CONSTANT(MSAA_DISABLED); BIND_ENUM_CONSTANT(MSAA_2X); BIND_ENUM_CONSTANT(MSAA_4X); @@ -3681,6 +3766,7 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS); BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE); BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO); + BIND_ENUM_CONSTANT(DEBUG_DRAW_SSIL); BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS); BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS); BIND_ENUM_CONSTANT(DEBUG_DRAW_SDFGI); @@ -3739,7 +3825,7 @@ Viewport::Viewport() { set_shadow_atlas_quadrant_subdiv(2, SHADOW_ATLAS_QUADRANT_SUBDIV_16); set_shadow_atlas_quadrant_subdiv(3, SHADOW_ATLAS_QUADRANT_SUBDIV_64); - set_lod_threshold(lod_threshold); + set_mesh_lod_threshold(mesh_lod_threshold); String id = itos(get_instance_id()); input_group = "_vp_input" + id; @@ -3752,7 +3838,16 @@ Viewport::Viewport() { ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers #ifndef _3D_DISABLED - set_scale_3d(GLOBAL_GET("rendering/3d/viewport/scale")); + Viewport::Scaling3DMode scaling_3d_mode = (Viewport::Scaling3DMode)(int)GLOBAL_GET("rendering/scaling_3d/mode"); + set_scaling_3d_mode(scaling_3d_mode); + + set_scaling_3d_scale(GLOBAL_GET("rendering/scaling_3d/scale")); + + float fsr_sharpness = GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"); + set_fsr_sharpness(fsr_sharpness); + + float fsr_mipmap_bias = GLOBAL_GET("rendering/scaling_3d/fsr_mipmap_bias"); + set_fsr_mipmap_bias(fsr_mipmap_bias); #endif // _3D_DISABLED set_sdf_oversize(sdf_oversize); // Set to server. diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 1f19ff04c9..57e1100521 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -89,6 +89,12 @@ class Viewport : public Node { GDCLASS(Viewport, Node); public: + enum Scaling3DMode { + SCALING_3D_MODE_BILINEAR, + SCALING_3D_MODE_FSR, + SCALING_3D_MODE_MAX + }; + enum ShadowAtlasQuadrantSubdiv { SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED, SHADOW_ATLAS_QUADRANT_SUBDIV_1, @@ -142,6 +148,7 @@ public: DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, DEBUG_DRAW_SCENE_LUMINANCE, DEBUG_DRAW_SSAO, + DEBUG_DRAW_SSIL, DEBUG_DRAW_PSSM_SPLITS, DEBUG_DRAW_DECAL_ATLAS, DEBUG_DRAW_SDFGI, @@ -244,7 +251,7 @@ private: bool control = false; bool shift = false; bool meta = false; - int mouse_mask = 0; + MouseButton mouse_mask = MouseButton::NONE; } physics_last_mouse_state; @@ -284,8 +291,13 @@ private: MSAA msaa = MSAA_DISABLED; ScreenSpaceAA screen_space_aa = SCREEN_SPACE_AA_DISABLED; + + Scaling3DMode scaling_3d_mode = SCALING_3D_MODE_BILINEAR; + float scaling_3d_scale = 1.0; + float fsr_sharpness = 0.2f; + float fsr_mipmap_bias = 0.0f; bool use_debanding = false; - float lod_threshold = 1.0; + float mesh_lod_threshold = 1.0; bool use_occlusion_culling = false; Ref<ViewportTexture> default_texture; @@ -327,7 +339,7 @@ private: Control *mouse_focus = nullptr; Control *last_mouse_focus = nullptr; Control *mouse_click_grabber = nullptr; - int mouse_focus_mask = 0; + MouseButton mouse_focus_mask = MouseButton::NONE; Control *key_focus = nullptr; Control *mouse_over = nullptr; Control *drag_mouse_over = nullptr; @@ -348,6 +360,7 @@ private: List<Control *> roots; int canvas_sort_index = 0; //for sorting items with canvas as root bool dragging = false; + bool drag_successful = false; bool embed_subwindows_hint = false; bool embedding_subwindows = false; @@ -503,11 +516,23 @@ public: void set_screen_space_aa(ScreenSpaceAA p_screen_space_aa); ScreenSpaceAA get_screen_space_aa() const; + void set_scaling_3d_mode(Scaling3DMode p_scaling_3d_mode); + Scaling3DMode get_scaling_3d_mode() const; + + void set_scaling_3d_scale(float p_scaling_3d_scale); + float get_scaling_3d_scale() const; + + void set_fsr_sharpness(float p_fsr_sharpness); + float get_fsr_sharpness() const; + + void set_fsr_mipmap_bias(float p_fsr_mipmap_bias); + float get_fsr_mipmap_bias() const; + void set_use_debanding(bool p_use_debanding); bool is_using_debanding() const; - void set_lod_threshold(float p_pixels); - float get_lod_threshold() const; + void set_mesh_lod_threshold(float p_pixels); + float get_mesh_lod_threshold() const; void set_use_occlusion_culling(bool p_us_occlusion_culling); bool is_using_occlusion_culling() const; @@ -556,6 +581,7 @@ public: bool is_handling_input_locally() const; bool gui_is_dragging() const; + bool gui_is_drag_successful() const; Control *gui_find_control(const Point2 &p_global); @@ -584,7 +610,6 @@ public: #ifndef _3D_DISABLED bool use_xr = false; - float scale_3d = 1.0; friend class AudioListener3D; AudioListener3D *audio_listener_3d = nullptr; Set<AudioListener3D *> audio_listener_3d_set; @@ -655,9 +680,6 @@ public: void set_use_xr(bool p_use_xr); bool is_using_xr(); - - void set_scale_3d(float p_scale_3d); - float get_scale_3d() const; #endif // _3D_DISABLED Viewport(); @@ -712,6 +734,7 @@ public: SubViewport(); ~SubViewport(); }; +VARIANT_ENUM_CAST(Viewport::Scaling3DMode); VARIANT_ENUM_CAST(SubViewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index a0f62c853f..43de4187d4 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -88,6 +88,10 @@ Size2i Window::get_size() const { return size; } +void Window::reset_size() { + set_size(Size2i()); +} + Size2i Window::get_real_size() const { if (window_id != DisplayServer::INVALID_WINDOW_ID) { return DisplayServer::get_singleton()->window_get_real_size(window_id); @@ -556,9 +560,12 @@ void Window::_update_viewport_size() { float font_oversampling = 1.0; if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) { - stretch_transform = Transform2D(); + font_oversampling = content_scale_factor; final_size = size; + final_size_override = Size2(size) / content_scale_factor; + stretch_transform = Transform2D(); + stretch_transform.scale(Size2(content_scale_factor, content_scale_factor)); } else { //actual screen video mode Size2 video_mode = size; @@ -630,9 +637,9 @@ void Window::_update_viewport_size() { } break; case CONTENT_SCALE_MODE_CANVAS_ITEMS: { final_size = screen_size; - final_size_override = viewport_size; + final_size_override = viewport_size / content_scale_factor; attach_to_screen_rect = Rect2(margin, screen_size); - font_oversampling = screen_size.x / viewport_size.x; + font_oversampling = (screen_size.x / viewport_size.x) * content_scale_factor; Size2 scale = Vector2(screen_size) / Vector2(final_size_override); stretch_transform.scale(scale); @@ -821,6 +828,16 @@ Window::ContentScaleAspect Window::get_content_scale_aspect() const { return content_scale_aspect; } +void Window::set_content_scale_factor(real_t p_factor) { + ERR_FAIL_COND(p_factor <= 0); + content_scale_factor = p_factor; + _update_viewport_size(); +} + +real_t Window::get_content_scale_factor() const { + return content_scale_factor; +} + void Window::set_use_font_oversampling(bool p_oversampling) { if (is_inside_tree() && window_id != DisplayServer::MAIN_WINDOW_ID) { ERR_FAIL_MSG("Only the root window can set and use font oversampling."); @@ -895,7 +912,7 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) { if (EngineDebugger::is_active()) { //quit from game window using F8 Ref<InputEventKey> k = p_ev; - if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == KEY_F8) { + if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::F8) { EngineDebugger::get_singleton()->send_message("request_quit", Array()); } } @@ -1410,6 +1427,7 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_size", "size"), &Window::set_size); ClassDB::bind_method(D_METHOD("get_size"), &Window::get_size); + ClassDB::bind_method(D_METHOD("reset_size"), &Window::reset_size); ClassDB::bind_method(D_METHOD("get_real_size"), &Window::get_real_size); @@ -1463,6 +1481,9 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_content_scale_aspect", "aspect"), &Window::set_content_scale_aspect); ClassDB::bind_method(D_METHOD("get_content_scale_aspect"), &Window::get_content_scale_aspect); + ClassDB::bind_method(D_METHOD("set_content_scale_factor", "factor"), &Window::set_content_scale_factor); + ClassDB::bind_method(D_METHOD("get_content_scale_factor"), &Window::get_content_scale_factor); + ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &Window::set_use_font_oversampling); ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &Window::is_using_font_oversampling); @@ -1534,6 +1555,7 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Canvas Items,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor"), "set_content_scale_factor", "get_content_scale_factor"); ADD_GROUP("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); diff --git a/scene/main/window.h b/scene/main/window.h index def6eab7b8..2dd1dd6601 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -112,6 +112,7 @@ private: Size2i content_scale_size; ContentScaleMode content_scale_mode = CONTENT_SCALE_MODE_DISABLED; ContentScaleAspect content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE; + real_t content_scale_factor = 1.0; void _make_window(); void _clear_window(); @@ -178,6 +179,7 @@ public: void set_size(const Size2i &p_size); Size2i get_size() const; + void reset_size(); Size2i get_real_size() const; @@ -229,6 +231,9 @@ public: void set_content_scale_aspect(ContentScaleAspect p_aspect); ContentScaleAspect get_content_scale_aspect() const; + void set_content_scale_factor(real_t p_factor); + real_t get_content_scale_factor() const; + void set_use_font_oversampling(bool p_oversampling); bool is_using_font_oversampling() const; |