diff options
Diffstat (limited to 'scene')
| -rw-r--r-- | scene/2d/joints_2d.cpp | 53 | ||||
| -rw-r--r-- | scene/2d/joints_2d.h | 3 | ||||
| -rw-r--r-- | scene/2d/light_occluder_2d.cpp | 14 | ||||
| -rw-r--r-- | scene/2d/light_occluder_2d.h | 5 | ||||
| -rw-r--r-- | scene/3d/physics_joint_3d.cpp | 55 | ||||
| -rw-r--r-- | scene/3d/physics_joint_3d.h | 3 | ||||
| -rw-r--r-- | scene/gui/aspect_ratio_container.cpp | 167 | ||||
| -rw-r--r-- | scene/gui/aspect_ratio_container.h | 80 | ||||
| -rw-r--r-- | scene/gui/control.h | 2 | ||||
| -rw-r--r-- | scene/main/scene_tree.cpp | 8 | ||||
| -rw-r--r-- | scene/main/viewport.cpp | 42 | ||||
| -rw-r--r-- | scene/main/viewport.h | 26 | ||||
| -rw-r--r-- | scene/register_scene_types.cpp | 2 | ||||
| -rw-r--r-- | scene/resources/visual_shader_nodes.cpp | 15 | ||||
| -rw-r--r-- | scene/resources/visual_shader_nodes.h | 1 |
15 files changed, 458 insertions, 18 deletions
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 0e4b1836da..f5d13fd641 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -47,29 +47,53 @@ void Joint2D::_update_joint(bool p_only_free) { } if (p_only_free || !is_inside_tree()) { + warning = String(); return; } Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr; Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr; - if (!node_a || !node_b) { + PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a); + PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b); + + if (node_a && !body_a && node_b && !body_b) { + warning = TTR("Node A and Node B must be PhysicsBody2Ds"); + update_configuration_warning(); return; } - PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a); - PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b); + if (node_a && !body_a) { + warning = TTR("Node A must be a PhysicsBody2D"); + update_configuration_warning(); + return; + } - if (!body_a || !body_b) { + if (node_b && !body_b) { + warning = TTR("Node B must be a PhysicsBody2D"); + update_configuration_warning(); return; } - joint = _configure_joint(body_a, body_b); + if (!body_a || !body_b) { + warning = TTR("Joint is not connected to two PhysicsBody2Ds"); + update_configuration_warning(); + return; + } - if (!joint.is_valid()) { + if (body_a == body_b) { + warning = TTR("Node A and Node B must be different PhysicsBody2Ds"); + update_configuration_warning(); return; } + warning = String(); + update_configuration_warning(); + + joint = _configure_joint(body_a, body_b); + + ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); + PhysicsServer2D::get_singleton()->get_singleton()->joint_set_param(joint, PhysicsServer2D::JOINT_PARAM_BIAS, bias); ba = body_a->get_rid(); @@ -141,6 +165,19 @@ bool Joint2D::get_exclude_nodes_from_collision() const { return exclude_from_collision; } +String Joint2D::get_configuration_warning() const { + String node_warning = Node2D::get_configuration_warning(); + + if (!warning.empty()) { + if (!node_warning.empty()) { + node_warning += "\n\n"; + } + node_warning += warning; + } + + return node_warning; +} + void Joint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint2D::set_node_a); ClassDB::bind_method(D_METHOD("get_node_a"), &Joint2D::get_node_a); @@ -154,8 +191,8 @@ void Joint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint2D::set_exclude_nodes_from_collision); ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint2D::get_exclude_nodes_from_collision); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_a", "get_node_a"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_b", "get_node_b"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody2D"), "set_node_a", "get_node_a"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody2D"), "set_node_b", "get_node_b"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); } diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h index 60534cae65..759e7de8a0 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joints_2d.h @@ -46,6 +46,7 @@ class Joint2D : public Node2D { real_t bias; bool exclude_from_collision; + String warning; protected: void _update_joint(bool p_only_free = false); @@ -56,6 +57,8 @@ protected: static void _bind_methods(); public: + virtual String get_configuration_warning() const override; + void set_node_a(const NodePath &p_node_a); NodePath get_node_a() const; diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 0531762ed8..6908fbeada 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -265,6 +265,14 @@ String LightOccluder2D::get_configuration_warning() const { return warning; } +void LightOccluder2D::set_as_sdf_collision(bool p_enable) { + sdf_collision = p_enable; + RS::get_singleton()->canvas_light_occluder_set_as_sdf_collision(occluder, sdf_collision); +} +bool LightOccluder2D::is_set_as_sdf_collision() const { + return sdf_collision; +} + void LightOccluder2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_occluder_polygon", "polygon"), &LightOccluder2D::set_occluder_polygon); ClassDB::bind_method(D_METHOD("get_occluder_polygon"), &LightOccluder2D::get_occluder_polygon); @@ -272,14 +280,20 @@ void LightOccluder2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &LightOccluder2D::set_occluder_light_mask); ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &LightOccluder2D::get_occluder_light_mask); + ClassDB::bind_method(D_METHOD("set_as_sdf_collision", "enable"), &LightOccluder2D::set_as_sdf_collision); + ClassDB::bind_method(D_METHOD("is_set_as_sdf_collision"), &LightOccluder2D::is_set_as_sdf_collision); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"), "set_occluder_polygon", "get_occluder_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdf_collision"), "set_as_sdf_collision", "is_set_as_sdf_collision"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask"); } LightOccluder2D::LightOccluder2D() { occluder = RS::get_singleton()->canvas_light_occluder_create(); mask = 1; + set_notify_transform(true); + set_as_sdf_collision(true); } LightOccluder2D::~LightOccluder2D() { diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 694097f985..97574af542 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -84,7 +84,7 @@ class LightOccluder2D : public Node2D { bool enabled; int mask; Ref<OccluderPolygon2D> occluder_polygon; - + bool sdf_collision; void _poly_changed(); protected: @@ -103,6 +103,9 @@ public: void set_occluder_light_mask(int p_mask); int get_occluder_light_mask() const; + void set_as_sdf_collision(bool p_enable); + bool is_set_as_sdf_collision() const; + String get_configuration_warning() const override; LightOccluder2D(); diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index af4d6ae152..ab9cdb9fd8 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -43,6 +43,7 @@ void Joint3D::_update_joint(bool p_only_free) { } if (p_only_free || !is_inside_tree()) { + warning = String(); return; } @@ -52,20 +53,47 @@ void Joint3D::_update_joint(bool p_only_free) { PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a); PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b); - if (!body_a && body_b) { - SWAP(body_a, body_b); + if (node_a && !body_a && node_b && !body_b) { + warning = TTR("Node A and Node B must be PhysicsBody3Ds"); + update_configuration_warning(); + return; } - if (!body_a) { + if (node_a && !body_a) { + warning = TTR("Node A must be a PhysicsBody3D"); + update_configuration_warning(); return; } - joint = _configure_joint(body_a, body_b); + if (node_b && !body_b) { + warning = TTR("Node B must be a PhysicsBody3D"); + update_configuration_warning(); + return; + } - if (!joint.is_valid()) { + if (!body_a && !body_b) { + warning = TTR("Joint is not connected to any PhysicsBody3Ds"); + update_configuration_warning(); return; } + if (body_a == body_b) { + warning = TTR("Node A and Node B must be different PhysicsBody3Ds"); + update_configuration_warning(); + return; + } + + if (!body_a) { + SWAP(body_a, body_b); + } + + warning = String(); + update_configuration_warning(); + + joint = _configure_joint(body_a, body_b); + + ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); + PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority); ba = body_a->get_rid(); @@ -137,6 +165,19 @@ bool Joint3D::get_exclude_nodes_from_collision() const { return exclude_from_collision; } +String Joint3D::get_configuration_warning() const { + String node_warning = Node3D::get_configuration_warning(); + + if (!warning.empty()) { + if (!node_warning.empty()) { + node_warning += "\n\n"; + } + node_warning += warning; + } + + return node_warning; +} + void Joint3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint3D::set_node_a); ClassDB::bind_method(D_METHOD("get_node_a"), &Joint3D::get_node_a); @@ -150,8 +191,8 @@ void Joint3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint3D::set_exclude_nodes_from_collision); ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint3D::get_exclude_nodes_from_collision); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject3D"), "set_node_a", "get_node_a"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject3D"), "set_node_b", "get_node_b"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody3D"), "set_node_a", "get_node_a"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody3D"), "set_node_b", "get_node_b"); ADD_PROPERTY(PropertyInfo(Variant::INT, "solver/priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision/exclude_nodes"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h index d1a375ca5d..a65f6db3bf 100644 --- a/scene/3d/physics_joint_3d.h +++ b/scene/3d/physics_joint_3d.h @@ -46,6 +46,7 @@ class Joint3D : public Node3D { int solver_priority; bool exclude_from_collision; + String warning; protected: void _update_joint(bool p_only_free = false); @@ -57,6 +58,8 @@ protected: static void _bind_methods(); public: + virtual String get_configuration_warning() const override; + void set_node_a(const NodePath &p_node_a); NodePath get_node_a() const; diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp new file mode 100644 index 0000000000..9f60131186 --- /dev/null +++ b/scene/gui/aspect_ratio_container.cpp @@ -0,0 +1,167 @@ +/*************************************************************************/ +/* aspect_ratio_container.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "aspect_ratio_container.h" + +Size2 AspectRatioContainer::get_minimum_size() const { + Size2 ms; + for (int i = 0; i < get_child_count(); i++) { + Control *c = Object::cast_to<Control>(get_child(i)); + if (!c) { + continue; + } + if (c->is_set_as_top_level()) { + continue; + } + if (!c->is_visible()) { + continue; + } + Size2 minsize = c->get_combined_minimum_size(); + ms.width = MAX(ms.width, minsize.width); + ms.height = MAX(ms.height, minsize.height); + } + return ms; +} + +void AspectRatioContainer::set_ratio(float p_ratio) { + ratio = p_ratio; + queue_sort(); +} + +void AspectRatioContainer::set_stretch_mode(StretchMode p_mode) { + stretch_mode = p_mode; + queue_sort(); +} + +void AspectRatioContainer::set_alignment_horizontal(AlignMode p_alignment_horizontal) { + alignment_horizontal = p_alignment_horizontal; + queue_sort(); +} + +void AspectRatioContainer::set_alignment_vertical(AlignMode p_alignment_vertical) { + alignment_vertical = p_alignment_vertical; + queue_sort(); +} + +void AspectRatioContainer::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_SORT_CHILDREN: { + Size2 size = get_size(); + for (int i = 0; i < get_child_count(); i++) { + Control *c = Object::cast_to<Control>(get_child(i)); + if (!c) { + continue; + } + if (c->is_set_as_top_level()) { + continue; + } + Size2 child_minsize = c->get_combined_minimum_size(); + Size2 child_size = Size2(ratio, 1.0); + float scale_factor = 1.0; + + switch (stretch_mode) { + case STRETCH_WIDTH_CONTROLS_HEIGHT: { + scale_factor = size.x / child_size.x; + } break; + case STRETCH_HEIGHT_CONTROLS_WIDTH: { + scale_factor = size.y / child_size.y; + } break; + case STRETCH_FIT: { + scale_factor = MIN(size.x / child_size.x, size.y / child_size.y); + } break; + case STRETCH_COVER: { + scale_factor = MAX(size.x / child_size.x, size.y / child_size.y); + } break; + } + child_size *= scale_factor; + child_size.x = MAX(child_size.x, child_minsize.x); + child_size.y = MAX(child_size.y, child_minsize.y); + + float align_x = 0.5; + switch (alignment_horizontal) { + case ALIGN_BEGIN: { + align_x = 0.0; + } break; + case ALIGN_CENTER: { + align_x = 0.5; + } break; + case ALIGN_END: { + align_x = 1.0; + } break; + } + float align_y = 0.5; + switch (alignment_vertical) { + case ALIGN_BEGIN: { + align_y = 0.0; + } break; + case ALIGN_CENTER: { + align_y = 0.5; + } break; + case ALIGN_END: { + align_y = 1.0; + } break; + } + Vector2 offset = (size - child_size) * Vector2(align_x, align_y); + + fit_child_in_rect(c, Rect2(offset, child_size)); + } + } break; + } +} + +void AspectRatioContainer::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_ratio", "ratio"), &AspectRatioContainer::set_ratio); + ClassDB::bind_method(D_METHOD("get_ratio"), &AspectRatioContainer::get_ratio); + + ClassDB::bind_method(D_METHOD("set_stretch_mode", "stretch_mode"), &AspectRatioContainer::set_stretch_mode); + ClassDB::bind_method(D_METHOD("get_stretch_mode"), &AspectRatioContainer::get_stretch_mode); + + ClassDB::bind_method(D_METHOD("set_alignment_horizontal", "alignment_horizontal"), &AspectRatioContainer::set_alignment_horizontal); + ClassDB::bind_method(D_METHOD("get_alignment_horizontal"), &AspectRatioContainer::get_alignment_horizontal); + + ClassDB::bind_method(D_METHOD("set_alignment_vertical", "alignment_vertical"), &AspectRatioContainer::set_alignment_vertical); + ClassDB::bind_method(D_METHOD("get_alignment_vertical"), &AspectRatioContainer::get_alignment_vertical); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ratio"), "set_ratio", "get_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Width controls height,Height controls width,Fit,Cover"), "set_stretch_mode", "get_stretch_mode"); + + ADD_GROUP("Alignment", "alignment_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment_horizontal", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment_horizontal", "get_alignment_horizontal"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment_vertical", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment_vertical", "get_alignment_vertical"); + + BIND_ENUM_CONSTANT(STRETCH_WIDTH_CONTROLS_HEIGHT); + BIND_ENUM_CONSTANT(STRETCH_HEIGHT_CONTROLS_WIDTH); + BIND_ENUM_CONSTANT(STRETCH_FIT); + BIND_ENUM_CONSTANT(STRETCH_COVER); + + BIND_ENUM_CONSTANT(ALIGN_BEGIN); + BIND_ENUM_CONSTANT(ALIGN_CENTER); + BIND_ENUM_CONSTANT(ALIGN_END); +} diff --git a/scene/gui/aspect_ratio_container.h b/scene/gui/aspect_ratio_container.h new file mode 100644 index 0000000000..8ffc4363c3 --- /dev/null +++ b/scene/gui/aspect_ratio_container.h @@ -0,0 +1,80 @@ +/*************************************************************************/ +/* aspect_ratio_container.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef ASPECT_RATIO_CONTAINER_H +#define ASPECT_RATIO_CONTAINER_H + +#include "scene/gui/container.h" + +class AspectRatioContainer : public Container { + GDCLASS(AspectRatioContainer, Container); + +protected: + void _notification(int p_what); + static void _bind_methods(); + virtual Size2 get_minimum_size() const override; + +public: + enum StretchMode { + STRETCH_WIDTH_CONTROLS_HEIGHT, + STRETCH_HEIGHT_CONTROLS_WIDTH, + STRETCH_FIT, + STRETCH_COVER, + }; + enum AlignMode { + ALIGN_BEGIN, + ALIGN_CENTER, + ALIGN_END, + }; + +private: + float ratio = 1.0; + StretchMode stretch_mode = STRETCH_FIT; + AlignMode alignment_horizontal = ALIGN_CENTER; + AlignMode alignment_vertical = ALIGN_CENTER; + +public: + void set_ratio(float p_ratio); + float get_ratio() const { return ratio; } + + void set_stretch_mode(StretchMode p_mode); + StretchMode get_stretch_mode() const { return stretch_mode; } + + void set_alignment_horizontal(AlignMode p_alignment_horizontal); + AlignMode get_alignment_horizontal() const { return alignment_horizontal; } + + void set_alignment_vertical(AlignMode p_alignment_vertical); + AlignMode get_alignment_vertical() const { return alignment_vertical; } +}; + +VARIANT_ENUM_CAST(AspectRatioContainer::StretchMode); +VARIANT_ENUM_CAST(AspectRatioContainer::AlignMode); + +#endif // ASPECT_RATIO_CONTAINER_H diff --git a/scene/gui/control.h b/scene/gui/control.h index 85b3227884..e4fe0bb25d 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -157,8 +157,6 @@ private: Vector2 scale; Vector2 pivot_offset; - bool pending_resize; - int h_size_flags; int v_size_flags; float expand; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index cc5f4e9598..304e8b9c6d 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1397,6 +1397,14 @@ SceneTree::SceneTree() { bool snap_2d_vertices = GLOBAL_DEF("rendering/quality/2d/snap_2d_vertices_to_pixel", false); root->set_snap_2d_vertices_to_pixel(snap_2d_vertices); + Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/quality/2d_sdf/oversize", 1))); + root->set_sdf_oversize(sdf_oversize); + Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/quality/2d_sdf/scale", 1))); + root->set_sdf_scale(sdf_scale); + + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/2d_sdf/oversize", PropertyInfo(Variant::INT, "rendering/quality/2d_sdf/oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/2d_sdf/scale", PropertyInfo(Variant::INT, "rendering/quality/2d_sdf/scale", PROPERTY_HINT_ENUM, "100%,50%,25%")); + { //load default fallback environment //get possible extensions List<String> exts; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index f4498507f1..5be5c1b266 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3383,6 +3383,24 @@ void Viewport::pass_mouse_focus_to(Viewport *p_viewport, Control *p_control) { } } +void Viewport::set_sdf_oversize(SDFOversize p_sdf_oversize) { + ERR_FAIL_INDEX(p_sdf_oversize, SDF_OVERSIZE_MAX); + sdf_oversize = p_sdf_oversize; + RS::get_singleton()->viewport_set_sdf_oversize_and_scale(viewport, RS::ViewportSDFOversize(sdf_oversize), RS::ViewportSDFScale(sdf_scale)); +} +Viewport::SDFOversize Viewport::get_sdf_oversize() const { + return sdf_oversize; +} + +void Viewport::set_sdf_scale(SDFScale p_sdf_scale) { + ERR_FAIL_INDEX(p_sdf_scale, SDF_SCALE_MAX); + sdf_scale = p_sdf_scale; + RS::get_singleton()->viewport_set_sdf_oversize_and_scale(viewport, RS::ViewportSDFOversize(sdf_oversize), RS::ViewportSDFScale(sdf_scale)); +} +Viewport::SDFScale Viewport::get_sdf_scale() const { + return sdf_scale; +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d); ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d); @@ -3482,6 +3500,12 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat); ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_repeat"), &Viewport::get_default_canvas_item_texture_repeat); + ClassDB::bind_method(D_METHOD("set_sdf_oversize", "oversize"), &Viewport::set_sdf_oversize); + ClassDB::bind_method(D_METHOD("get_sdf_oversize"), &Viewport::get_sdf_oversize); + + 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); + 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"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); @@ -3506,6 +3530,9 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_embed_subwindows"), "set_embed_subwindows_hint", "get_embed_subwindows_hint"); + ADD_GROUP("SDF", "sdf_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%"), "set_sdf_oversize", "get_sdf_oversize"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale"); ADD_GROUP("Shadow Atlas", "shadow_atlas_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0); @@ -3575,6 +3602,17 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX); + + BIND_ENUM_CONSTANT(SDF_OVERSIZE_100_PERCENT); + BIND_ENUM_CONSTANT(SDF_OVERSIZE_120_PERCENT); + BIND_ENUM_CONSTANT(SDF_OVERSIZE_150_PERCENT); + BIND_ENUM_CONSTANT(SDF_OVERSIZE_200_PERCENT); + BIND_ENUM_CONSTANT(SDF_OVERSIZE_MAX); + + BIND_ENUM_CONSTANT(SDF_SCALE_100_PERCENT); + BIND_ENUM_CONSTANT(SDF_SCALE_50_PERCENT); + BIND_ENUM_CONSTANT(SDF_SCALE_25_PERCENT); + BIND_ENUM_CONSTANT(SDF_SCALE_MAX); } Viewport::Viewport() { @@ -3661,6 +3699,10 @@ Viewport::Viewport() { default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; + + sdf_oversize = SDF_OVERSIZE_120_PERCENT; + sdf_scale = SDF_SCALE_50_PERCENT; + set_sdf_oversize(SDF_OVERSIZE_120_PERCENT); //set to server } Viewport::~Viewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 4be66ae79f..7ce202d27c 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -159,6 +159,21 @@ public: DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX, }; + enum SDFOversize { + SDF_OVERSIZE_100_PERCENT, + SDF_OVERSIZE_120_PERCENT, + SDF_OVERSIZE_150_PERCENT, + SDF_OVERSIZE_200_PERCENT, + SDF_OVERSIZE_MAX + }; + + enum SDFScale { + SDF_SCALE_100_PERCENT, + SDF_SCALE_50_PERCENT, + SDF_SCALE_25_PERCENT, + SDF_SCALE_MAX + }; + enum { SUBWINDOW_CANVAS_LAYER = 1024 }; @@ -285,6 +300,9 @@ private: Ref<ViewportTexture> default_texture; Set<ViewportTexture *> viewport_textures; + SDFOversize sdf_oversize; + SDFScale sdf_scale; + enum SubWindowDrag { SUB_WINDOW_DRAG_DISABLED, SUB_WINDOW_DRAG_MOVE, @@ -572,6 +590,12 @@ public: bool gui_is_dragging() const; + void set_sdf_oversize(SDFOversize p_sdf_oversize); + SDFOversize get_sdf_oversize() const; + + void set_sdf_scale(SDFScale p_sdf_scale); + SDFScale get_sdf_scale() const; + void set_default_canvas_item_texture_filter(DefaultCanvasItemTextureFilter p_filter); DefaultCanvasItemTextureFilter get_default_canvas_item_texture_filter() const; @@ -650,6 +674,8 @@ VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA); VARIANT_ENUM_CAST(Viewport::DebugDraw); +VARIANT_ENUM_CAST(Viewport::SDFScale); +VARIANT_ENUM_CAST(Viewport::SDFOversize); VARIANT_ENUM_CAST(SubViewport::ClearMode); VARIANT_ENUM_CAST(Viewport::RenderInfo); VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureFilter); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 7997dc12e1..3ca4e6db3a 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -77,6 +77,7 @@ #include "scene/animation/tween.h" #include "scene/audio/audio_stream_player.h" #include "scene/debugger/scene_debugger.h" +#include "scene/gui/aspect_ratio_container.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/center_container.h" @@ -324,6 +325,7 @@ void register_scene_types() { ClassDB::register_class<ColorRect>(); ClassDB::register_class<NinePatchRect>(); ClassDB::register_class<ReferenceRect>(); + ClassDB::register_class<AspectRatioContainer>(); ClassDB::register_class<TabContainer>(); ClassDB::register_class<Tabs>(); ClassDB::register_virtual_class<Separator>(); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 704d1b2ea8..a3358ea8c7 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -724,6 +724,10 @@ Vector<StringName> VisualShaderNodeTexture::get_editable_properties() const { } String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + if (is_input_port_connected(2) && source != SOURCE_PORT) { + return TTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'."); + } + if (source == SOURCE_TEXTURE) { return String(); // all good } @@ -980,6 +984,10 @@ void VisualShaderNodeSample3D::_bind_methods() { } String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + if (is_input_port_connected(2) && source != SOURCE_PORT) { + return TTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'."); + } + if (source == SOURCE_TEXTURE) { return String(); // all good } @@ -1276,6 +1284,13 @@ Vector<StringName> VisualShaderNodeCubemap::get_editable_properties() const { return props; } +String VisualShaderNodeCubemap::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + if (is_input_port_connected(2) && source != SOURCE_PORT) { + return TTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'."); + } + return String(); +} + void VisualShaderNodeCubemap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubemap::set_source); ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubemap::get_source); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index d4d6540baf..4b39c76388 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -448,6 +448,7 @@ public: TextureType get_texture_type() const; virtual Vector<StringName> get_editable_properties() const override; + virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override; VisualShaderNodeCubemap(); }; |