diff options
98 files changed, 1091 insertions, 368 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 92c2e3c516..eeca57a22e 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -122,13 +122,13 @@ jobs: ${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$' - # Download, unzip and setup SwiftShader library [4466040] + # Download, unzip and setup SwiftShader library + # See https://github.com/godotengine/regression-test-project/releases/tag/_ci-deps for details - name: Download SwiftShader if: ${{ matrix.tests }} run: | - wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/swiftshader2.zip - unzip swiftshader2.zip - rm swiftshader2.zip + wget https://github.com/godotengine/regression-test-project/releases/download/_ci-deps/swiftshader-ubuntu20.04-20211002.zip + unzip swiftshader-ubuntu20.04-20211002.zip curr="$(pwd)/libvk_swiftshader.so" sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json @@ -136,9 +136,9 @@ jobs: - name: Download test project if: ${{ matrix.proj-test }} run: | - wget https://github.com/qarmin/RegressionTestProject/archive/4.0.zip + wget https://github.com/godotengine/regression-test-project/archive/4.0.zip unzip 4.0.zip - mv "RegressionTestProject-4.0" "test_project" + mv "regression-test-project-4.0" "test_project" # Editor is quite complicated piece of software, so it is easy to introduce bug here - name: Open and close editor diff --git a/SConstruct b/SConstruct index 9dcc6c554f..bdf4937cd7 100644 --- a/SConstruct +++ b/SConstruct @@ -300,13 +300,6 @@ opts.Update(env_base) env_base["platform"] = selected_platform # Must always be re-set after calling opts.Update(). Help(opts.GenerateHelpText(env_base)) -# Detect and print a warning listing unknown SCons variables to ease troubleshooting. -unknown = opts.UnknownVariables() -if unknown: - print("WARNING: Unknown SCons variables were passed and will be ignored:") - for item in unknown.items(): - print(" " + item[0] + "=" + item[1]) - # add default include paths env_base.Prepend(CPPPATH=["#"]) diff --git a/core/core_constants.cpp b/core/core_constants.cpp index cd56233c58..6f26288eb7 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -669,15 +669,15 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_SIGNAL", Variant::SIGNAL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_ARRAY", Variant::ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RAW_ARRAY", Variant::PACKED_BYTE_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT32_ARRAY", Variant::PACKED_INT32_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT64_ARRAY", Variant::PACKED_INT64_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_ARRAY", Variant::PACKED_STRING_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_BYTE_ARRAY", Variant::PACKED_BYTE_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_INT32_ARRAY", Variant::PACKED_INT32_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_INT64_ARRAY", Variant::PACKED_INT64_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_STRING_ARRAY", Variant::PACKED_STRING_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_MAX", Variant::VARIANT_MAX); //comparison diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 715468f71d..526952b14f 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -312,10 +312,10 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con } else { read_block--; at_end = true; - if (i < p_length - 1) { + if (i + 1 < p_length) { read_eof = true; } - return i; + return i + 1; } } } diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index d90a0c9110..6347862775 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -189,7 +189,7 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, uint6 f.package = pkg_num; unzGetFilePos(zfile, &f.file_pos); - String fname = String("res://") + filename_inzip; + String fname = String("res://") + String::utf8(filename_inzip); files[fname] = f; uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 311d71638b..66d5c54b53 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -520,8 +520,8 @@ void ResourceCache::dump(const char *p_file, bool p_short) { FileAccess *f = nullptr; if (p_file) { - f = FileAccess::open(p_file, FileAccess::WRITE); - ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String(p_file) + "'."); + f = FileAccess::open(String::utf8(p_file), FileAccess::WRITE); + ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String::utf8(p_file) + "'."); } const String *K = nullptr; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 65eb27ef4e..200d5fafde 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -53,9 +53,9 @@ enum { VARIANT_PLANE = 13, VARIANT_QUATERNION = 14, VARIANT_AABB = 15, - VARIANT_MATRIX3 = 16, - VARIANT_TRANSFORM = 17, - VARIANT_MATRIX32 = 18, + VARIANT_BASIS = 16, + VARIANT_TRANSFORM3D = 17, + VARIANT_TRANSFORM2D = 18, VARIANT_COLOR = 20, VARIANT_NODE_PATH = 22, VARIANT_RID = 23, @@ -63,13 +63,13 @@ enum { VARIANT_INPUT_EVENT = 25, VARIANT_DICTIONARY = 26, VARIANT_ARRAY = 30, - VARIANT_RAW_ARRAY = 31, - VARIANT_INT32_ARRAY = 32, - VARIANT_FLOAT32_ARRAY = 33, - VARIANT_STRING_ARRAY = 34, - VARIANT_VECTOR3_ARRAY = 35, - VARIANT_COLOR_ARRAY = 36, - VARIANT_VECTOR2_ARRAY = 37, + VARIANT_PACKED_BYTE_ARRAY = 31, + VARIANT_PACKED_INT32_ARRAY = 32, + VARIANT_PACKED_FLOAT32_ARRAY = 33, + VARIANT_PACKED_STRING_ARRAY = 34, + VARIANT_PACKED_VECTOR3_ARRAY = 35, + VARIANT_PACKED_COLOR_ARRAY = 36, + VARIANT_PACKED_VECTOR2_ARRAY = 37, VARIANT_INT64 = 40, VARIANT_DOUBLE = 41, VARIANT_CALLABLE = 42, @@ -78,8 +78,8 @@ enum { VARIANT_VECTOR2I = 45, VARIANT_RECT2I = 46, VARIANT_VECTOR3I = 47, - VARIANT_INT64_ARRAY = 48, - VARIANT_FLOAT64_ARRAY = 49, + VARIANT_PACKED_INT64_ARRAY = 48, + VARIANT_PACKED_FLOAT64_ARRAY = 49, OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, @@ -220,7 +220,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_MATRIX32: { + case VARIANT_TRANSFORM2D: { Transform2D v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); @@ -231,7 +231,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_MATRIX3: { + case VARIANT_BASIS: { Basis v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); @@ -245,7 +245,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_TRANSFORM: { + case VARIANT_TRANSFORM3D: { Transform3D v; v.basis.elements[0].x = f->get_real(); v.basis.elements[0].y = f->get_real(); @@ -422,7 +422,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = a; } break; - case VARIANT_RAW_ARRAY: { + case VARIANT_PACKED_BYTE_ARRAY: { uint32_t len = f->get_32(); Vector<uint8_t> array; @@ -434,7 +434,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_INT32_ARRAY: { + case VARIANT_PACKED_INT32_ARRAY: { uint32_t len = f->get_32(); Vector<int32_t> array; @@ -453,7 +453,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_INT64_ARRAY: { + case VARIANT_PACKED_INT64_ARRAY: { uint32_t len = f->get_32(); Vector<int64_t> array; @@ -472,7 +472,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_FLOAT32_ARRAY: { + case VARIANT_PACKED_FLOAT32_ARRAY: { uint32_t len = f->get_32(); Vector<float> array; @@ -491,7 +491,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_FLOAT64_ARRAY: { + case VARIANT_PACKED_FLOAT64_ARRAY: { uint32_t len = f->get_32(); Vector<double> array; @@ -510,7 +510,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_STRING_ARRAY: { + case VARIANT_PACKED_STRING_ARRAY: { uint32_t len = f->get_32(); Vector<String> array; array.resize(len); @@ -522,7 +522,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_VECTOR2_ARRAY: { + case VARIANT_PACKED_VECTOR2_ARRAY: { uint32_t len = f->get_32(); Vector<Vector2> array; @@ -547,7 +547,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_VECTOR3_ARRAY: { + case VARIANT_PACKED_VECTOR3_ARRAY: { uint32_t len = f->get_32(); Vector<Vector3> array; @@ -572,7 +572,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_COLOR_ARRAY: { + case VARIANT_PACKED_COLOR_ARRAY: { uint32_t len = f->get_32(); Vector<Color> array; @@ -1476,7 +1476,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::TRANSFORM2D: { - f->store_32(VARIANT_MATRIX32); + f->store_32(VARIANT_TRANSFORM2D); Transform2D val = p_property; f->store_real(val.elements[0].x); f->store_real(val.elements[0].y); @@ -1487,7 +1487,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::BASIS: { - f->store_32(VARIANT_MATRIX3); + f->store_32(VARIANT_BASIS); Basis val = p_property; f->store_real(val.elements[0].x); f->store_real(val.elements[0].y); @@ -1501,7 +1501,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::TRANSFORM3D: { - f->store_32(VARIANT_TRANSFORM); + f->store_32(VARIANT_TRANSFORM3D); Transform3D val = p_property; f->store_real(val.basis.elements[0].x); f->store_real(val.basis.elements[0].y); @@ -1625,7 +1625,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_BYTE_ARRAY: { - f->store_32(VARIANT_RAW_ARRAY); + f->store_32(VARIANT_PACKED_BYTE_ARRAY); Vector<uint8_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1635,7 +1635,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_INT32_ARRAY: { - f->store_32(VARIANT_INT32_ARRAY); + f->store_32(VARIANT_PACKED_INT32_ARRAY); Vector<int32_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1646,7 +1646,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_INT64_ARRAY: { - f->store_32(VARIANT_INT64_ARRAY); + f->store_32(VARIANT_PACKED_INT64_ARRAY); Vector<int64_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1657,7 +1657,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_FLOAT32_ARRAY: { - f->store_32(VARIANT_FLOAT32_ARRAY); + f->store_32(VARIANT_PACKED_FLOAT32_ARRAY); Vector<float> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1668,7 +1668,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_FLOAT64_ARRAY: { - f->store_32(VARIANT_FLOAT64_ARRAY); + f->store_32(VARIANT_PACKED_FLOAT64_ARRAY); Vector<double> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1679,7 +1679,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_STRING_ARRAY: { - f->store_32(VARIANT_STRING_ARRAY); + f->store_32(VARIANT_PACKED_STRING_ARRAY); Vector<String> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1690,7 +1690,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_VECTOR3_ARRAY: { - f->store_32(VARIANT_VECTOR3_ARRAY); + f->store_32(VARIANT_PACKED_VECTOR3_ARRAY); Vector<Vector3> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1703,7 +1703,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_VECTOR2_ARRAY: { - f->store_32(VARIANT_VECTOR2_ARRAY); + f->store_32(VARIANT_PACKED_VECTOR2_ARRAY); Vector<Vector2> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1715,7 +1715,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_COLOR_ARRAY: { - f->store_32(VARIANT_COLOR_ARRAY); + f->store_32(VARIANT_PACKED_COLOR_ARRAY); Vector<Color> arr = p_property; int len = arr.size(); f->store_32(len); diff --git a/core/math/octree.h b/core/math/octree.h index 7861c35e07..23ba4c1aa3 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -103,7 +103,7 @@ private: Octant *parent = nullptr; Octant *children[8] = { nullptr }; - int children_count = 0; // cache for amount of childrens (fast check for removal) + int children_count = 0; // cache for amount of children (fast check for removal) int parent_index = -1; // cache for parent index (fast check for removal) List<Element *, AL> pairable_elements; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 38dad893f5..676a0004ea 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -210,6 +210,14 @@ Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { CLAMP(y, p_min.y, p_max.y)); } +int64_t Vector2i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y; +} + +double Vector2i::length() const { + return Math::sqrt((double)length_squared()); +} + Vector2i Vector2i::operator+(const Vector2i &p_v) const { return Vector2i(x + p_v.x, y + p_v.y); } diff --git a/core/math/vector2.h b/core/math/vector2.h index 493e0af27d..a340036ac7 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -261,11 +261,16 @@ Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const { } Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_normalized(), Vector2(), "The start Vector2 must be normalized."); -#endif - real_t theta = angle_to(p_to); - return rotated(theta * p_weight); + real_t start_length_sq = length_squared(); + real_t end_length_sq = p_to.length_squared(); + if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) { + // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. + return lerp(p_to, p_weight); + } + real_t start_length = Math::sqrt(start_length_sq); + real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); + real_t angle = angle_to(p_to); + return rotated(angle * p_weight) * (result_length / start_length); } Vector2 Vector2::direction_to(const Vector2 &p_to) const { @@ -344,6 +349,9 @@ struct Vector2i { bool operator==(const Vector2i &p_vec2) const; bool operator!=(const Vector2i &p_vec2) const; + int64_t length_squared() const; + double length() const; + real_t aspect() const { return width / (real_t)height; } Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); } Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); } diff --git a/core/math/vector3.h b/core/math/vector3.h index 1861627718..d7a72b05a8 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -240,8 +240,16 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const { } Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const { - real_t theta = angle_to(p_to); - return rotated(cross(p_to).normalized(), theta * p_weight); + real_t start_length_sq = length_squared(); + real_t end_length_sq = p_to.length_squared(); + if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) { + // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. + return lerp(p_to, p_weight); + } + real_t start_length = Math::sqrt(start_length_sq); + real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); + real_t angle = angle_to(p_to); + return rotated(cross(p_to).normalized(), angle * p_weight) * (result_length / start_length); } real_t Vector3::distance_to(const Vector3 &p_to) const { diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 0f9caa349b..1416c98057 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -31,6 +31,7 @@ #ifndef VECTOR3I_H #define VECTOR3I_H +#include "core/math/math_funcs.h" #include "core/string/ustring.h" #include "core/typedefs.h" @@ -65,6 +66,9 @@ struct Vector3i { Vector3i::Axis min_axis_index() const; Vector3i::Axis max_axis_index() const; + _FORCE_INLINE_ int64_t length_squared() const; + _FORCE_INLINE_ double length() const; + _FORCE_INLINE_ void zero(); _FORCE_INLINE_ Vector3i abs() const; @@ -110,6 +114,14 @@ struct Vector3i { } }; +int64_t Vector3i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y + z * (int64_t)z; +} + +double Vector3i::length() const { + return Math::sqrt((double)length_squared()); +} + Vector3i Vector3i::abs() const { return Vector3i(ABS(x), ABS(y), ABS(z)); } diff --git a/core/object/script_language.h b/core/object/script_language.h index 23c8667afd..4b18d9a5e8 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -227,6 +227,7 @@ struct ScriptCodeCompletionOption { Color font_color; RES icon; Variant default_value; + Vector<Pair<int, int>> matches; ScriptCodeCompletionOption() {} diff --git a/core/os/os.cpp b/core/os/os.cpp index 506e968bf6..0032e8e4bc 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -346,7 +346,7 @@ String OS::get_model_name() const { } void OS::set_cmdline(const char *p_execpath, const List<String> &p_args) { - _execpath = p_execpath; + _execpath = String::utf8(p_execpath); _cmdline = p_args; } diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 1a19f29f3b..f4e0748c27 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -36,6 +36,8 @@ #include "core/templates/sort_array.h" #include "core/templates/vector.h" +#include <initializer_list> + template <class T, class U = uint32_t, bool force_trivial = false> class LocalVector { private: @@ -228,6 +230,12 @@ public: } _FORCE_INLINE_ LocalVector() {} + _FORCE_INLINE_ LocalVector(std::initializer_list<T> p_init) { + reserve(p_init.size()); + for (const T &element : p_init) { + push_back(element); + } + } _FORCE_INLINE_ LocalVector(const LocalVector &p_from) { resize(p_from.size()); for (U i = 0; i < p_from.count; i++) { diff --git a/core/templates/vector.h b/core/templates/vector.h index 18b731c458..4ada3b597a 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -43,6 +43,8 @@ #include "core/templates/search_array.h" #include "core/templates/sort_array.h" +#include <initializer_list> + template <class T> class VectorWriteProxy { public: @@ -258,6 +260,15 @@ public: } _FORCE_INLINE_ Vector() {} + _FORCE_INLINE_ Vector(std::initializer_list<T> p_init) { + Error err = _cowdata.resize(p_init.size()); + ERR_FAIL_COND(err); + + int i = 0; + for (const T &element : p_init) { + _cowdata.set(i++, element); + } + } _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); } _FORCE_INLINE_ ~Vector() {} diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 64522a9908..ecf5009fb6 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1513,6 +1513,8 @@ static void _register_variant_builtin_methods() { bind_method(Vector2i, aspect, sarray(), varray()); bind_method(Vector2i, max_axis_index, sarray(), varray()); bind_method(Vector2i, min_axis_index, sarray(), varray()); + bind_method(Vector2i, length, sarray(), varray()); + bind_method(Vector2i, length_squared, sarray(), varray()); bind_method(Vector2i, sign, sarray(), varray()); bind_method(Vector2i, abs, sarray(), varray()); bind_method(Vector2i, clamp, sarray("min", "max"), varray()); @@ -1594,6 +1596,8 @@ static void _register_variant_builtin_methods() { bind_method(Vector3i, min_axis_index, sarray(), varray()); bind_method(Vector3i, max_axis_index, sarray(), varray()); + bind_method(Vector3i, length, sarray(), varray()); + bind_method(Vector3i, length_squared, sarray(), varray()); bind_method(Vector3i, sign, sarray(), varray()); bind_method(Vector3i, abs, sarray(), varray()); bind_method(Vector3i, clamp, sarray("min", "max"), varray()); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 7f794fef6e..20a371c3d0 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2699,31 +2699,31 @@ <constant name="TYPE_ARRAY" value="25" enum="Variant.Type"> Variable is of type [Array]. </constant> - <constant name="TYPE_RAW_ARRAY" value="26" enum="Variant.Type"> + <constant name="TYPE_PACKED_BYTE_ARRAY" value="26" enum="Variant.Type"> Variable is of type [PackedByteArray]. </constant> - <constant name="TYPE_INT32_ARRAY" value="27" enum="Variant.Type"> + <constant name="TYPE_PACKED_INT32_ARRAY" value="27" enum="Variant.Type"> Variable is of type [PackedInt32Array]. </constant> - <constant name="TYPE_INT64_ARRAY" value="28" enum="Variant.Type"> + <constant name="TYPE_PACKED_INT64_ARRAY" value="28" enum="Variant.Type"> Variable is of type [PackedInt64Array]. </constant> - <constant name="TYPE_FLOAT32_ARRAY" value="29" enum="Variant.Type"> + <constant name="TYPE_PACKED_FLOAT32_ARRAY" value="29" enum="Variant.Type"> Variable is of type [PackedFloat32Array]. </constant> - <constant name="TYPE_FLOAT64_ARRAY" value="30" enum="Variant.Type"> + <constant name="TYPE_PACKED_FLOAT64_ARRAY" value="30" enum="Variant.Type"> Variable is of type [PackedFloat64Array]. </constant> - <constant name="TYPE_STRING_ARRAY" value="31" enum="Variant.Type"> + <constant name="TYPE_PACKED_STRING_ARRAY" value="31" enum="Variant.Type"> Variable is of type [PackedStringArray]. </constant> - <constant name="TYPE_VECTOR2_ARRAY" value="32" enum="Variant.Type"> + <constant name="TYPE_PACKED_VECTOR2_ARRAY" value="32" enum="Variant.Type"> Variable is of type [PackedVector2Array]. </constant> - <constant name="TYPE_VECTOR3_ARRAY" value="33" enum="Variant.Type"> + <constant name="TYPE_PACKED_VECTOR3_ARRAY" value="33" enum="Variant.Type"> Variable is of type [PackedVector3Array]. </constant> - <constant name="TYPE_COLOR_ARRAY" value="34" enum="Variant.Type"> + <constant name="TYPE_PACKED_COLOR_ARRAY" value="34" enum="Variant.Type"> Variable is of type [PackedColorArray]. </constant> <constant name="TYPE_MAX" value="35" enum="Variant.Type"> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 768006ebe4..7a2120379f 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -53,7 +53,6 @@ <argument index="1" name="texture" type="Texture2D" /> <description> Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots. - [b]Note:[/b] When setting a roughness or metallic texture on a material that has no texture assigned to those slots, [member roughness] or [member metallic] will automatically be set to [code]1.0[/code] to ensure correct appearance. </description> </method> </methods> @@ -233,7 +232,6 @@ </member> <member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0"> A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness]. - [b]Note:[/b] [member metallic] is automatically set to [code]1.0[/code] when assigning a metallic texture using [method set_texture]. </member> <member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5"> Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources. @@ -306,7 +304,6 @@ </member> <member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0"> Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic]. - [b]Note:[/b] [member roughness] is automatically set to [code]1.0[/code] when assigning a roughness texture using [method set_texture]. </member> <member name="roughness_texture" type="Texture2D" setter="set_texture" getter="get_texture"> Texture used to control the roughness per-pixel. Multiplied by [member roughness]. diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index c432410d3b..be6d9e07c3 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -109,6 +109,14 @@ Removes the connection between the [code]from_port[/code] slot of the [code]from[/code] GraphNode and the [code]to_port[/code] slot of the [code]to[/code] GraphNode. If the connection does not exist, no connection is removed. </description> </method> + <method name="force_connection_drag_end"> + <return type="void" /> + <description> + Ends the creation of the current connection. In other words, if you are dragging a connection you can use this method to abort the process and remove the line that followed your cursor. + This is best used together with [signal connection_drag_begun] and [signal connection_drag_ended] to add custom behavior like node addition through shortcuts. + [b]Note:[/b] This method suppresses any other connection request signals apart from [signal connection_drag_ended]. + </description> + </method> <method name="get_connection_line"> <return type="PackedVector2Array" /> <argument index="0" name="from" type="Vector2" /> @@ -241,6 +249,19 @@ Emitted at the beginning of a GraphNode movement. </description> </signal> + <signal name="connection_drag_begun"> + <argument index="0" name="from" type="String" /> + <argument index="1" name="slot" type="String" /> + <argument index="2" name="is_output" type="bool" /> + <description> + Emitted at the beginning of a connection drag. + </description> + </signal> + <signal name="connection_drag_ended"> + <description> + Emitted at the end of a connection drag. + </description> + </signal> <signal name="connection_from_empty"> <argument index="0" name="to" type="StringName" /> <argument index="1" name="to_slot" type="int" /> diff --git a/doc/classes/HMACContext.xml b/doc/classes/HMACContext.xml index b29f821da5..0b2d65d339 100644 --- a/doc/classes/HMACContext.xml +++ b/doc/classes/HMACContext.xml @@ -15,7 +15,7 @@ var err = ctx.start(HashingContext.HASH_SHA256, key) assert(err == OK) var msg1 = "this is ".to_utf8() - var msg2 = "vewy vewy secret".to_utf8() + var msg2 = "super duper secret".to_utf8() err = ctx.update(msg1) assert(err == OK) err = ctx.update(msg2) @@ -38,7 +38,7 @@ Error err = ctx.Start(HashingContext.HASH_SHA256, key); GD.Assert(err == OK); PackedByteArray msg1 = String("this is ").to_utf8(); - PackedByteArray msg2 = String("vewy vew secret").to_utf8(); + PackedByteArray msg2 = String("super duper secret").to_utf8(); err = ctx.Update(msg1); GD.Assert(err == OK); err = ctx.Update(msg2); diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index 1036c1fbcf..6b5a627575 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -134,6 +134,20 @@ Resets this node's transformations (like scale, skew and taper) preserving its rotation and translation by performing Gram-Schmidt orthonormalization on this node's [Transform3D]. </description> </method> + <method name="property_can_revert"> + <return type="bool" /> + <argument index="0" name="name" type="String" /> + <description> + Returns [code]true[/code] if the property identified by [code]name[/code] can be reverted to a default value. + </description> + </method> + <method name="property_get_revert"> + <return type="Variant" /> + <argument index="0" name="name" type="String" /> + <description> + Returns the default value of the Node3D property with given [code]name[/code]. + </description> + </method> <method name="rotate"> <return type="void" /> <argument index="0" name="axis" type="Vector3" /> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index b16d45b8ca..686854ffe8 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -363,7 +363,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the size of the array. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index 13d7440bb9..d875549319 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -126,7 +126,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the size of the array. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index 151014192f..6c77c4bee2 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -127,7 +127,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the size of the array. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index 963a02ace8..a8282c099a 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -127,7 +127,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the size of the array. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index cef113dee9..da26e93b96 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -127,7 +127,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the array size. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 072df519c6..9ddf43a837 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -127,7 +127,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the array size. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 0bded150a3..439d59dde7 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -127,7 +127,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the size of the array. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index 8e993c41ab..8c4f052016 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -127,7 +127,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the size of the array. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index df69e3cd4a..8229af984d 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -126,7 +126,7 @@ <method name="size" qualifiers="const"> <return type="int" /> <description> - Returns the size of the array. + Returns the number of elements in the array. </description> </method> <method name="slice" qualifiers="const"> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 00f072b306..a249786388 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1692,6 +1692,8 @@ <member name="rendering/gles2/compatibility/enable_high_float.Android" type="bool" setter="" getter="" default="false"> </member> <member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false"> + If [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting. + [b]Note:[/b] This property is only read when the project starts. To set half-resolution GI at run-time, call [method RenderingServer.gi_set_use_half_resolution] instead. </member> <member name="rendering/global_illumination/sdfgi/frames_to_converge" type="int" setter="" getter="" default="4"> </member> diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml index 8abd3f84b1..8a8d6e73f0 100644 --- a/doc/classes/RayCast3D.xml +++ b/doc/classes/RayCast3D.xml @@ -38,8 +38,7 @@ <method name="force_raycast_update"> <return type="void" /> <description> - Updates the collision information for the ray. - Use this method to update the collision information immediately instead of waiting for the next [code]_physics_process[/code] call, for example if the ray or its parent has changed state. + Updates the collision information for the ray. Use this method to update the collision information immediately instead of waiting for the next [code]_physics_process[/code] call, for example if the ray or its parent has changed state. [b]Note:[/b] [member enabled] does not need to be [code]true[/code] for this to work. </description> </method> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index f17f6293bc..009e9d3df4 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1068,7 +1068,7 @@ <argument index="8" name="light_affect" type="float" /> <argument index="9" name="ao_channel_affect" type="float" /> <description> - Sets the variables to be used with the "screen space ambient occlusion" post-process effect. See [Environment] for more details. + Sets the variables to be used with the screen-space ambient occlusion (SSAO) post-process effect. See [Environment] for more details. </description> </method> <method name="environment_set_ssao_quality"> @@ -1080,6 +1080,19 @@ <argument index="4" name="fadeout_from" type="float" /> <argument index="5" name="fadeout_to" type="float" /> <description> + Sets the quality level of the screen-space ambient occlusion (SSAO) post-process effect. See [Environment] for more details. + </description> + </method> + <method name="environment_set_ssil_quality"> + <return type="void" /> + <argument index="0" name="quality" type="int" enum="RenderingServer.EnvironmentSSILQuality" /> + <argument index="1" name="half_size" type="bool" /> + <argument index="2" name="adaptive_target" type="float" /> + <argument index="3" name="blur_passes" type="int" /> + <argument index="4" name="fadeout_from" type="float" /> + <argument index="5" name="fadeout_to" type="float" /> + <description> + Sets the quality level of the screen-space indirect lighting (SSIL) post-process effect. See [Environment] for more details. </description> </method> <method name="environment_set_ssr"> @@ -1252,6 +1265,13 @@ Returns the id of a white texture. Creates one if none exists. </description> </method> + <method name="gi_set_use_half_resolution"> + <return type="void" /> + <argument index="0" name="half_resolution" type="bool" /> + <description> + If [code]half_resolution[/code] is [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting. See also [member ProjectSettings.rendering/global_illumination/gi/use_half_resolution]. + </description> + </method> <method name="global_variable_add"> <return type="void" /> <argument index="0" name="name" type="StringName" /> @@ -4131,19 +4151,34 @@ <constant name="ENV_SSR_ROUGNESS_QUALITY_HIGH" value="3" enum="EnvironmentSSRRoughnessQuality"> </constant> <constant name="ENV_SSAO_QUALITY_VERY_LOW" value="0" enum="EnvironmentSSAOQuality"> - Lowest quality of screen space ambient occlusion. + Lowest quality of screen-space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_LOW" value="1" enum="EnvironmentSSAOQuality"> - Low quality screen space ambient occlusion. + Low quality screen-space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_MEDIUM" value="2" enum="EnvironmentSSAOQuality"> - Medium quality screen space ambient occlusion. + Medium quality screen-space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_HIGH" value="3" enum="EnvironmentSSAOQuality"> - High quality screen space ambient occlusion. + High quality screen-space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_ULTRA" value="4" enum="EnvironmentSSAOQuality"> - Highest quality screen space ambient occlusion. Uses the adaptive setting which can be dynamically adjusted to smoothly balance performance and visual quality. + Highest quality screen-space ambient occlusion. Uses the adaptive target setting which can be dynamically adjusted to smoothly balance performance and visual quality. + </constant> + <constant name="ENV_SSIL_QUALITY_VERY_LOW" value="0" enum="EnvironmentSSILQuality"> + Lowest quality of screen-space indirect lighting. + </constant> + <constant name="ENV_SSIL_QUALITY_LOW" value="1" enum="EnvironmentSSILQuality"> + Low quality screen-space indirect lighting. + </constant> + <constant name="ENV_SSIL_QUALITY_MEDIUM" value="2" enum="EnvironmentSSILQuality"> + High quality screen-space indirect lighting. + </constant> + <constant name="ENV_SSIL_QUALITY_HIGH" value="3" enum="EnvironmentSSILQuality"> + High quality screen-space indirect lighting. + </constant> + <constant name="ENV_SSIL_QUALITY_ULTRA" value="4" enum="EnvironmentSSILQuality"> + Highest quality screen-space indirect lighting. Uses the adaptive target setting which can be dynamically adjusted to smoothly balance performance and visual quality. </constant> <constant name="ENV_SDFGI_CASCADES_4" value="0" enum="EnvironmentSDFGICascades"> </constant> diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml index 805f056289..69d224ed24 100644 --- a/doc/classes/StreamPeer.xml +++ b/doc/classes/StreamPeer.xml @@ -70,7 +70,7 @@ <return type="String" /> <argument index="0" name="bytes" type="int" default="-1" /> <description> - Gets a string with byte-length [code]bytes[/code] from the stream. If [code]bytes[/code] is negative (default) the length will be read from the stream using the reverse process of [method put_string]. + Gets an ASCII string with byte-length [code]bytes[/code] from the stream. If [code]bytes[/code] is negative (default) the length will be read from the stream using the reverse process of [method put_string]. </description> </method> <method name="get_u16"> diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml index f97b3e08d1..d0976be4b5 100644 --- a/doc/classes/TabBar.xml +++ b/doc/classes/TabBar.xml @@ -49,19 +49,6 @@ Returns [code]true[/code] if select with right mouse button is enabled. </description> </method> - <method name="get_tab_count" qualifiers="const"> - <return type="int" /> - <description> - Returns the number of tabs. - </description> - </method> - <method name="get_tab_disabled" qualifiers="const"> - <return type="bool" /> - <argument index="0" name="tab_idx" type="int" /> - <description> - Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is disabled. - </description> - </method> <method name="get_tab_icon" qualifiers="const"> <return type="Texture2D" /> <argument index="0" name="tab_idx" type="int" /> @@ -117,6 +104,13 @@ Returns the [TabBar]'s rearrange group ID. </description> </method> + <method name="is_tab_disabled" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="tab_idx" type="int" /> + <description> + Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is disabled. + </description> + </method> <method name="move_tab"> <return type="void" /> <argument index="0" name="from" type="int" /> @@ -214,6 +208,9 @@ <member name="tab_close_display_policy" type="int" setter="set_tab_close_display_policy" getter="get_tab_close_display_policy" enum="TabBar.CloseButtonDisplayPolicy" default="0"> Sets when the close button will appear on the tabs. See [enum CloseButtonDisplayPolicy] for details. </member> + <member name="tab_count" type="int" setter="set_tab_count" getter="get_tab_count" default="0"> + The number of tabs currently in the bar. + </member> </members> <signals> <signal name="active_tab_rearranged"> diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml index e62cb9216e..e679a8cfeb 100644 --- a/doc/classes/Transform3D.xml +++ b/doc/classes/Transform3D.xml @@ -60,13 +60,13 @@ <argument index="0" name="xform" type="Transform3D" /> <argument index="1" name="weight" type="float" /> <description> - Interpolates the transform to other Transform3D by weight amount (on the range of 0.0 to 1.0). + Returns a transform interpolated between this transform and another by a given [code]weight[/code] (on the range of 0.0 to 1.0). </description> </method> <method name="inverse" qualifiers="const"> <return type="Transform3D" /> <description> - Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use affine_inverse for transforms with scaling). + Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use [method affine_inverse] for transforms with scaling). </description> </method> <method name="is_equal_approx" qualifiers="const"> @@ -88,7 +88,7 @@ <method name="orthonormalized" qualifiers="const"> <return type="Transform3D" /> <description> - Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors. + Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors (scale of 1 or -1). </description> </method> <method name="rotated" qualifiers="const"> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index 7e773a0249..64256f33fd 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -95,7 +95,7 @@ <method name="ceil" qualifiers="const"> <return type="Vector2" /> <description> - Returns the vector with all components rounded up (towards positive infinity). + Returns a new vector with all components rounded up (towards positive infinity). </description> </method> <method name="clamp" qualifiers="const"> @@ -158,7 +158,7 @@ <method name="floor" qualifiers="const"> <return type="Vector2" /> <description> - Returns the vector with all components rounded down (towards negative infinity). + Returns a new vector with all components rounded down (towards negative infinity). </description> </method> <method name="from_angle" qualifiers="static"> @@ -231,7 +231,7 @@ <argument index="0" name="to" type="Vector2" /> <argument index="1" name="delta" type="float" /> <description> - Moves the vector toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value. + Returns a new vector moved toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value. </description> </method> <method name="normalized" qualifiers="const"> @@ -264,7 +264,7 @@ <return type="Vector2" /> <argument index="0" name="b" type="Vector2" /> <description> - Returns the vector projected onto the vector [code]b[/code]. + Returns this vector projected onto the vector [code]b[/code]. </description> </method> <method name="reflect" qualifiers="const"> @@ -284,13 +284,13 @@ <method name="round" qualifiers="const"> <return type="Vector2" /> <description> - Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. + Returns a new vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. </description> </method> <method name="sign" qualifiers="const"> <return type="Vector2" /> <description> - Returns the vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. + Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. </description> </method> <method name="slerp" qualifiers="const"> @@ -299,7 +299,7 @@ <argument index="1" name="weight" type="float" /> <description> Returns the result of spherical linear interpolation between this vector and [code]to[/code], by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation. - [b]Note:[/b] Both vectors must be normalized. + This method also handles interpolating the lengths if the input vectors have different lengths. For the special case of one or both input vectors having zero length, this method behaves like [method lerp]. </description> </method> <method name="slide" qualifiers="const"> diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml index a9334d924f..721c73d603 100644 --- a/doc/classes/Vector2i.xml +++ b/doc/classes/Vector2i.xml @@ -53,7 +53,7 @@ <method name="aspect" qualifiers="const"> <return type="float" /> <description> - Returns the ratio of [member x] to [member y]. + Returns the aspect ratio of this vector, the ratio of [member x] to [member y]. </description> </method> <method name="clamp" qualifiers="const"> @@ -64,6 +64,19 @@ Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. </description> </method> + <method name="length" qualifiers="const"> + <return type="float" /> + <description> + Returns the length (magnitude) of this vector. + </description> + </method> + <method name="length_squared" qualifiers="const"> + <return type="int" /> + <description> + Returns the squared length (squared magnitude) of this vector. + This method runs faster than [method length], so prefer it if you need to compare vectors or need the squared distance for some formula. + </description> + </method> <method name="max_axis_index" qualifiers="const"> <return type="int" /> <description> @@ -79,7 +92,7 @@ <method name="sign" qualifiers="const"> <return type="Vector2i" /> <description> - Returns the vector with each component set to one or negative one, depending on the signs of the components. + Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. </description> </method> </methods> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index da5e4f4f43..ead08d86df 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -96,7 +96,7 @@ <argument index="2" name="post_b" type="Vector3" /> <argument index="3" name="weight" type="float" /> <description> - Performs a cubic interpolation between vectors [code]pre_a[/code], [code]a[/code], [code]b[/code], [code]post_b[/code] ([code]a[/code] is current), by the given amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation. + Performs a cubic interpolation between this vector and [code]b[/code] using [code]pre_a[/code] and [code]post_b[/code] as handles, and returns the result at position [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation. </description> </method> <method name="direction_to" qualifiers="const"> @@ -201,7 +201,7 @@ <argument index="0" name="to" type="Vector3" /> <argument index="1" name="delta" type="float" /> <description> - Moves this vector toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value. + Returns a new vector moved toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value. </description> </method> <method name="normalized" qualifiers="const"> @@ -246,7 +246,7 @@ <return type="Vector3" /> <argument index="0" name="b" type="Vector3" /> <description> - Returns this vector projected onto another vector [code]b[/code]. + Returns this vector projected onto the vector [code]b[/code]. </description> </method> <method name="reflect" qualifiers="const"> @@ -267,13 +267,13 @@ <method name="round" qualifiers="const"> <return type="Vector3" /> <description> - Returns this vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. + Returns a new vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. </description> </method> <method name="sign" qualifiers="const"> <return type="Vector3" /> <description> - Returns a vector with each component set to one or negative one, depending on the signs of this vector's components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. + Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. </description> </method> <method name="signed_angle_to" qualifiers="const"> @@ -290,7 +290,7 @@ <argument index="1" name="weight" type="float" /> <description> Returns the result of spherical linear interpolation between this vector and [code]to[/code], by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation. - [b]Note:[/b] Both vectors must be normalized. + This method also handles interpolating the lengths if the input vectors have different lengths. For the special case of one or both input vectors having zero length, this method behaves like [method lerp]. </description> </method> <method name="slide" qualifiers="const"> diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml index 9b952292b6..da729e1ec2 100644 --- a/doc/classes/Vector3i.xml +++ b/doc/classes/Vector3i.xml @@ -58,6 +58,19 @@ Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. </description> </method> + <method name="length" qualifiers="const"> + <return type="float" /> + <description> + Returns the length (magnitude) of this vector. + </description> + </method> + <method name="length_squared" qualifiers="const"> + <return type="int" /> + <description> + Returns the squared length (squared magnitude) of this vector. + This method runs faster than [method length], so prefer it if you need to compare vectors or need the squared distance for some formula. + </description> + </method> <method name="max_axis_index" qualifiers="const"> <return type="int" /> <description> diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml index 995f2796dd..b9ff711f44 100644 --- a/doc/classes/VisualShaderNodeCustom.xml +++ b/doc/classes/VisualShaderNodeCustom.xml @@ -25,7 +25,7 @@ </method> <method name="_get_code" qualifiers="virtual const"> <return type="String" /> - <argument index="0" name="input_vars" type="PackedStringArray" /> + <argument index="0" name="input_vars" type="String[]" /> <argument index="1" name="output_vars" type="String[]" /> <argument index="2" name="mode" type="int" enum="Shader.Mode" /> <argument index="3" name="type" type="int" enum="VisualShader.Type" /> diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index 4cb9de6d58..9e18866ca3 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -19,10 +19,11 @@ GODOT_DOCS_PATTERN = re.compile(r"^\$DOCS_URL/(.*)\.html(#.*)?$") MARKUP_ALLOWED_PRECEDENT = " -:/'\"<([{" MARKUP_ALLOWED_SUBSEQUENT = " -.,:;!?\\/'\")]}>" -# Used to translate the section headings when required with --lang argument. -# The HEADINGS list should be synced with what we actually write with `make_heading`, -# and also hardcoded in `doc/translations/extract.py`. -HEADINGS = [ +# Used to translate section headings and other hardcoded strings when required with +# the --lang argument. The BASE_STRINGS list should be synced with what we actually +# write in this script (check `translate()` uses), and also hardcoded in +# `doc/translations/extract.py` to include them in the source POT file. +BASE_STRINGS = [ "Description", "Tutorials", "Properties", @@ -38,8 +39,21 @@ HEADINGS = [ "Method Descriptions", "Operator Descriptions", "Theme Property Descriptions", + "Inherits:", + "Inherited By:", + "(overrides %s)", + "Default", + "Setter", + "value", + "Getter", + "This method should typically be overridden by the user to have any effect.", + "This method has no side effects. It doesn't modify any of the instance's member variables.", + "This method accepts any number of arguments after the ones described here.", + "This method is used to construct a type.", + "This method doesn't need an instance to be called, so it can be called directly using the class name.", + "This method describes a valid operator to use with this type as left-hand operand.", ] -headings_l10n = {} +strings_l10n = {} def print_error(error, state): # type: (str, State) -> None @@ -408,13 +422,13 @@ def main(): # type: () -> None try: import polib except ImportError: - print("Section heading localization requires `polib`.") + print("Base template strings localization requires `polib`.") exit(1) pofile = polib.pofile(lang_file) for entry in pofile.translated_entries(): - if entry.msgid in HEADINGS: - headings_l10n[entry.msgid] = entry.msgstr + if entry.msgid in BASE_STRINGS: + strings_l10n[entry.msgid] = entry.msgstr else: print("No PO file at '{}' for language '{}'.".format(lang_file, args.lang)) @@ -494,6 +508,14 @@ def main(): # type: () -> None exit(1) +def translate(string): # type: (str) -> str + """Translate a string based on translations sourced from `doc/translations/*.po` + for a language if defined via the --lang command line argument. + Returns the original string if no translation exists. + """ + return strings_l10n.get(string, string) + + def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, State, bool, str) -> None class_name = class_def.name @@ -515,7 +537,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S # Ascendants if class_def.inherits: inh = class_def.inherits.strip() - f.write("**Inherits:** ") + f.write("**" + translate("Inherits:") + "** ") first = True while inh in state.classes: if not first: @@ -538,7 +560,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S inherited.append(c.name) if len(inherited): - f.write("**Inherited By:** ") + f.write("**" + translate("Inherited By:") + "** ") for i, child in enumerate(inherited): if i > 0: f.write(", ") @@ -569,7 +591,8 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S default = property_def.default_value if default is not None and property_def.overrides: ref = ":ref:`{1}<class_{1}_property_{0}>`".format(property_def.name, property_def.overrides) - ml.append((type_rst, property_def.name, default + " (overrides " + ref + ")")) + # Not using translate() for now as it breaks table formatting. + ml.append((type_rst, property_def.name, default + " " + "(overrides %s)" % ref)) else: ref = ":ref:`{0}<class_{1}_property_{0}>`".format(property_def.name, class_name) ml.append((type_rst, ref, default)) @@ -687,12 +710,13 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S f.write("- {} **{}**\n\n".format(property_def.type_name.to_rst(state), property_def.name)) info = [] + # Not using translate() for now as it breaks table formatting. if property_def.default_value is not None: - info.append(("*Default*", property_def.default_value)) + info.append(("*" + "Default" + "*", property_def.default_value)) if property_def.setter is not None and not property_def.setter.startswith("_"): - info.append(("*Setter*", property_def.setter + "(value)")) + info.append(("*" + "Setter" + "*", property_def.setter + "(" + "value" + ")")) if property_def.getter is not None and not property_def.getter.startswith("_"): - info.append(("*Getter*", property_def.getter + "()")) + info.append(("*" + "Getter" + "*", property_def.getter + "()")) if len(info) > 0: format_table(f, info) @@ -781,7 +805,8 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S info = [] if theme_item_def.default_value is not None: - info.append(("*Default*", theme_item_def.default_value)) + # Not using translate() for now as it breaks table formatting. + info.append(("*" + "Default" + "*", theme_item_def.default_value)) if len(info) > 0: format_table(f, info) @@ -1306,8 +1331,9 @@ def make_method_signature( def make_heading(title, underline, l10n=True): # type: (str, str, bool) -> str if l10n: - if title in headings_l10n: - title = headings_l10n.get(title) + new_title = translate(title) + if new_title != title: + title = new_title underline *= 2 # Double length to handle wide chars. return title + "\n" + (underline * len(title)) + "\n\n" @@ -1317,12 +1343,12 @@ def make_footer(): # type: () -> str # This way, we avoid bloating the generated rST with duplicate abbreviations. # fmt: off return ( - ".. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`\n" - ".. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`\n" - ".. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`\n" - ".. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`\n" - ".. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`\n" - ".. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`\n" + ".. |virtual| replace:: :abbr:`virtual (" + translate("This method should typically be overridden by the user to have any effect.") + ")`\n" + ".. |const| replace:: :abbr:`const (" + translate("This method has no side effects. It doesn't modify any of the instance's member variables.") + ")`\n" + ".. |vararg| replace:: :abbr:`vararg (" + translate("This method accepts any number of arguments after the ones described here.") + ")`\n" + ".. |constructor| replace:: :abbr:`constructor (" + translate("This method is used to construct a type.") + ")`\n" + ".. |static| replace:: :abbr:`static (" + translate("This method doesn't need an instance to be called, so it can be called directly using the class name.") + ")`\n" + ".. |operator| replace:: :abbr:`operator (" + translate("This method describes a valid operator to use with this type as left-hand operand.") + ")`\n" ) # fmt: on diff --git a/doc/translations/extract.py b/doc/translations/extract.py index 45e747d5dd..f8223701d5 100644 --- a/doc/translations/extract.py +++ b/doc/translations/extract.py @@ -26,7 +26,7 @@ msgstr "" """ # Some strings used by make_rst.py are normally part of the editor translations, # so we need to include them manually here for the online docs. -HEADINGS = [ +BASE_STRINGS = [ "Description", "Tutorials", "Properties", @@ -42,6 +42,19 @@ HEADINGS = [ "Method Descriptions", "Operator Descriptions", "Theme Property Descriptions", + "Inherits:", + "Inherited By:", + "(overrides %s)", + "Default", + "Setter", + "value", + "Getter", + "This method should typically be overridden by the user to have any effect.", + "This method has no side effects. It doesn't modify any of the instance's member variables.", + "This method accepts any number of arguments after the ones described here.", + "This method is used to construct a type.", + "This method doesn't need an instance to be called, so it can be called directly using the class name.", + "This method describes a valid operator to use with this type as left-hand operand.", ] ## <xml-line-number-hack from="https://stackoverflow.com/a/36430270/10846399"> @@ -229,12 +242,12 @@ def _make_translation_catalog(classes): def _generate_translation_catalog_file(unique_msgs, output, location_line=False): with open(output, "w", encoding="utf8") as f: f.write(HEADER) - for msg in HEADINGS: + for msg in BASE_STRINGS: f.write("#: doc/tools/make_rst.py\n") f.write('msgid "{}"\n'.format(msg)) f.write('msgstr ""\n\n') for msg in unique_msgs: - if len(msg) == 0 or msg in HEADINGS: + if len(msg) == 0 or msg in BASE_STRINGS: continue f.write("#:") diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 9cf2b7a7eb..7884269103 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -283,9 +283,9 @@ Array AudioDriverALSA::get_device_list() { if (name != nullptr && !strncmp(name, "plughw", 6)) { if (desc) { - list.push_back(String(name) + ";" + String(desc)); + list.push_back(String::utf8(name) + ";" + String::utf8(desc)); } else { - list.push_back(String(name)); + list.push_back(String::utf8(name)); } } diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 7364dbe2e7..e37a53fede 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -540,7 +540,7 @@ Array AudioDriverCoreAudio::_get_device_list(bool capture) { ERR_FAIL_NULL_V_MSG(buffer, list, "Out of memory."); if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) { // Append the ID to the name in case we have devices with duplicate name - list.push_back(String(buffer) + " (" + itos(audioDevices[i]) + ")"); + list.push_back(String::utf8(buffer) + " (" + itos(audioDevices[i]) + ")"); } memfree(buffer); @@ -597,7 +597,7 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) { char *buffer = (char *)memalloc(maxSize); ERR_FAIL_NULL_MSG(buffer, "Out of memory."); if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) { - String name = String(buffer) + " (" + itos(audioDevices[i]) + ")"; + String name = String::utf8(buffer) + " (" + itos(audioDevices[i]) + ")"; if (name == device) { deviceId = audioDevices[i]; found = true; diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 69af0f6578..807789586b 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -1325,7 +1325,7 @@ public: struct Frame { RenderTarget *current_rt; - // these 2 may have been superceded by the equivalents in the render target. + // these 2 may have been superseded by the equivalents in the render target. // these may be able to be removed. bool clear_request; Color clear_request_color; diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 102787f0bf..75a3ab26ea 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -33,6 +33,7 @@ #include "core/config/engine.h" #include "core/config/project_settings.h" #include "core/string/ustring.h" +#include "core/templates/local_vector.h" #include "core/version.h" #include "servers/rendering/rendering_device.h" @@ -41,7 +42,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <vector> #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #define APP_SHORT_NAME "GodotEngine" @@ -212,7 +212,7 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char *const *c } Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const char *const **names) { - static const std::vector<std::vector<const char *>> instance_validation_layers_alt{ + static const LocalVector<LocalVector<const char *>> instance_validation_layers_alt{ // Preferred set of validation layers { "VK_LAYER_KHRONOS_validation" }, @@ -249,10 +249,10 @@ Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const cha } for (uint32_t i = 0; i < instance_validation_layers_alt.size(); i++) { - if (_check_layers(instance_validation_layers_alt[i].size(), instance_validation_layers_alt[i].data(), instance_layer_count, instance_layers)) { + if (_check_layers(instance_validation_layers_alt[i].size(), instance_validation_layers_alt[i].ptr(), instance_layer_count, instance_layers)) { *count = instance_validation_layers_alt[i].size(); if (names != nullptr) { - *names = instance_validation_layers_alt[i].data(); + *names = instance_validation_layers_alt[i].ptr(); } break; } diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index a1704e37a7..4669e56e20 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1548,7 +1548,9 @@ void CodeTextEditor::set_error_pos(int p_line, int p_column) { void CodeTextEditor::goto_error() { if (!error->get_text().is_empty()) { - text_editor->unfold_line(error_line); + if (text_editor->get_line_count() != error_line) { + text_editor->unfold_line(error_line); + } text_editor->set_caret_line(error_line); text_editor->set_caret_column(error_column); text_editor->center_viewport_to_caret(); diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 827eb76db5..d556255a8f 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -273,8 +273,8 @@ void editor_register_fonts(Ref<Theme> p_theme) { // Default font MAKE_DEFAULT_FONT(df, String()); - p_theme->set_default_theme_font(df); // Default theme font - p_theme->set_default_theme_font_size(default_font_size); + p_theme->set_default_font(df); // Default theme font + p_theme->set_default_font_size(default_font_size); p_theme->set_font_size("main_size", "EditorFonts", default_font_size); p_theme->set_font("main", "EditorFonts", df); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 7b60c4a384..a8a1dc37ab 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -294,7 +294,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<Theme> theme = Ref<Theme>(memnew(Theme)); // Controls may rely on the scale for their internal drawing logic. - theme->set_default_theme_base_scale(EDSCALE); + theme->set_default_base_scale(EDSCALE); // Theme settings Color accent_color = EDITOR_GET("interface/theme/accent_color"); diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index ab1be7f41b..10654cfe43 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -297,6 +297,8 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { _set_dirty(false); import_as->set_disabled(false); preset->set_disabled(false); + content->show(); + select_a_resource->hide(); imported->set_text(vformat(TTR("%d Files"), p_paths.size())); diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp index be17fc238a..2126ca1bc9 100644 --- a/editor/plugins/lightmap_gi_editor_plugin.cpp +++ b/editor/plugins/lightmap_gi_editor_plugin.cpp @@ -33,13 +33,14 @@ void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) { if (lightmap) { LightmapGI::BakeError err; + const uint64_t time_started = OS::get_singleton()->get_ticks_msec(); if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == lightmap) { err = lightmap->bake(lightmap, p_file, bake_func_step); } else { err = lightmap->bake(lightmap->get_parent(), p_file, bake_func_step); } - bake_func_end(); + bake_func_end(time_started); switch (err) { case LightmapGI::BAKE_ERROR_NO_SAVE_PATH: { @@ -104,11 +105,18 @@ bool LightmapGIEditorPlugin::bake_func_step(float p_progress, const String &p_de return tmp_progress->step(p_description, p_progress * 1000, p_refresh); } -void LightmapGIEditorPlugin::bake_func_end() { +void LightmapGIEditorPlugin::bake_func_end(uint64_t p_time_started) { if (tmp_progress != nullptr) { memdelete(tmp_progress); tmp_progress = nullptr; } + + const int time_taken = (OS::get_singleton()->get_ticks_msec() - p_time_started) * 0.001; + print_line(vformat("Done baking lightmaps in %02d:%02d:%02d.", time_taken / 3600, (time_taken % 3600) / 60, time_taken % 60)); + // Request attention in case the user was doing something else. + // Baking lightmaps is likely the editor task that can take the most time, + // so only request the attention for baking lightmaps. + DisplayServer::get_singleton()->window_request_attention(); } void LightmapGIEditorPlugin::_bind_methods() { diff --git a/editor/plugins/lightmap_gi_editor_plugin.h b/editor/plugins/lightmap_gi_editor_plugin.h index d0edf9f324..5eec972228 100644 --- a/editor/plugins/lightmap_gi_editor_plugin.h +++ b/editor/plugins/lightmap_gi_editor_plugin.h @@ -47,7 +47,7 @@ class LightmapGIEditorPlugin : public EditorPlugin { EditorFileDialog *file_dialog; static EditorProgress *tmp_progress; static bool bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh); - static void bake_func_end(); + static void bake_func_end(uint64_t p_time_started); void _bake_select_file(const String &p_file); void _bake(); diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 576e91e544..9d45c365a8 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -254,6 +254,43 @@ void EditorInspectorPluginMaterial::parse_begin(Object *p_object) { add_custom_control(editor); } +void EditorInspectorPluginMaterial::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) { + UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo); + if (!undo_redo) { + return; + } + + // For BaseMaterial3D, if a roughness or metallic textures is being assigned to an empty slot, + // set the respective metallic or roughness factor to 1.0 as a convenience feature + BaseMaterial3D *base_material = Object::cast_to<StandardMaterial3D>(p_edited); + if (base_material) { + Texture2D *texture = Object::cast_to<Texture2D>(p_new_value); + if (texture) { + if (p_property == "roughness_texture") { + if (base_material->get_texture(StandardMaterial3D::TEXTURE_ROUGHNESS).is_null() && texture) { + undo_redo->add_do_property(p_edited, "roughness", 1.0); + + bool valid = false; + Variant value = p_edited->get("roughness", &valid); + if (valid) { + undo_redo->add_undo_property(p_edited, "roughness", value); + } + } + } else if (p_property == "metallic_texture") { + if (base_material->get_texture(StandardMaterial3D::TEXTURE_METALLIC).is_null() && texture) { + undo_redo->add_do_property(p_edited, "metallic", 1.0); + + bool valid = false; + Variant value = p_edited->get("metallic", &valid); + if (valid) { + undo_redo->add_undo_property(p_edited, "metallic", value); + } + } + } + } + } +} + EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() { env.instantiate(); Ref<Sky> sky = memnew(Sky()); @@ -261,6 +298,8 @@ EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() { env->set_background(Environment::BG_COLOR); env->set_ambient_source(Environment::AMBIENT_SOURCE_SKY); env->set_reflection_source(Environment::REFLECTION_SOURCE_SKY); + + EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &EditorInspectorPluginMaterial::_undo_redo_inspector_callback)); } MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) { diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 36c2df191d..53f4513396 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -92,6 +92,8 @@ public: virtual bool can_handle(Object *p_object) override; virtual void parse_begin(Object *p_object) override; + void _undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value); + EditorInspectorPluginMaterial(); }; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 8d4e7b444b..7e72777da1 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -726,7 +726,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { dup->set_name(parent->validate_child_name(dup)); - editor_data->get_undo_redo().add_do_method(add_below_node, "add_sibling", dup); + editor_data->get_undo_redo().add_do_method(add_below_node, "add_sibling", dup, true); for (Node *F : owned) { if (!duplimap.has(F)) { @@ -942,6 +942,18 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; } + if (tocopy->get_owner() != scene) { + accept->set_text(TTR("Can't save a branch which is a child of an already instantiated scene.\nTo save this branch into its own scene, open the original scene, right click on this branch, and select \"Save Branch as Scene\".")); + accept->popup_centered(); + break; + } + + if (scene->get_scene_inherited_state().is_valid() && scene->get_scene_inherited_state()->find_node_by_path(scene->get_path_to(tocopy)) >= 0) { + accept->set_text(TTR("Can't save a branch which is part of an inherited scene.\nTo save this branch into its own scene, open the original scene, right click on this branch, and select \"Save Branch as Scene\".")); + accept->popup_centered(); + break; + } + new_scene_from_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); List<String> extensions; diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 20c6aafc7f..2098fa2c85 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -353,15 +353,15 @@ void ScriptCreateDialog::_load_exist() { } Vector<String> ScriptCreateDialog::get_hierarchy(String p_object) const { - Vector<String> hierachy; - hierachy.append(p_object); + Vector<String> hierarchy; + hierarchy.append(p_object); String parent_class = ClassDB::get_parent_class(p_object); while (parent_class.is_valid_identifier()) { - hierachy.append(parent_class); + hierarchy.append(parent_class); parent_class = ClassDB::get_parent_class(parent_class); } - return hierachy; + return hierarchy; } void ScriptCreateDialog::_language_changed(int l) { @@ -544,7 +544,7 @@ void ScriptCreateDialog::_update_template_menu() { template_list.clear(); if (is_language_using_templates) { - // Get the lastest templates used for each type of node from project settings then global settings. + // Get the latest templates used for each type of node from project settings then global settings. Dictionary last_local_templates = EditorSettings::get_singleton()->get_project_metadata("script_setup", "templates_dictionary", Dictionary()); Dictionary last_global_templates; if (EditorSettings::get_singleton()->has_meta("script_setup/templates_dictionary")) { diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh index b241f3da70..e66bc88bc0 100755 --- a/misc/scripts/file_format.sh +++ b/misc/scripts/file_format.sh @@ -20,6 +20,8 @@ while IFS= read -rd '' f; do continue elif [[ "$f" == *"sln" ]]; then continue + elif [[ "$f" == *".bat" ]]; then + continue elif [[ "$f" == *".out" ]]; then # GDScript integration testing files. continue diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm index 626cc3f285..391006bfc2 100644 --- a/modules/camera/camera_osx.mm +++ b/modules/camera/camera_osx.mm @@ -231,7 +231,7 @@ void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { // get some info NSString *device_name = p_device.localizedName; - name = device_name.UTF8String; + name = String::utf8(device_name.UTF8String); position = CameraFeed::FEED_UNSPECIFIED; if ([p_device position] == AVCaptureDevicePositionBack) { position = CameraFeed::FEED_BACK; diff --git a/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd new file mode 100644 index 0000000000..27383b878d --- /dev/null +++ b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd @@ -0,0 +1,41 @@ +# meta-description: Visual shader's node plugin template + +@tool +extends _BASE_ +class_name VisualShaderNode_CLASS_ + +func _get_name() -> String: + return "_CLASS_" + +func _get_category() -> String: + return "" + +func _get_description() -> String: + return "" + +func _get_return_icon_type() -> int: + return PORT_TYPE_SCALAR + +func _get_input_port_count() -> int: + return 0 + +func _get_input_port_name(port: int) -> String: + return "" + +func _get_input_port_type(port: int) -> int: + return PORT_TYPE_SCALAR + +func _get_output_port_count() -> int: + return 1 + +func _get_output_port_name(port: int) -> String: + return "result" + +func _get_output_port_type(port: int) -> int: + return PORT_TYPE_SCALAR + +func _get_global_code(mode: Shader.Mode) -> String: + return "" + +func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String: + return output_vars[0] + " = 0.0;" diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 81aaef09dc..9db76861ff 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1164,6 +1164,10 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, const GDScriptParser::ExpressionNode *p_expression, GDScriptCompletionIdentifier &r_type) { bool found = false; + if (p_expression == nullptr) { + return false; + } + if (p_expression->is_constant) { // Already has a value, so just use that. r_type = _type_from_variant(p_expression->reduced_value); diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index 5845f84605..47772b8039 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -362,16 +362,16 @@ void GDScriptTest::error_handler(void *p_this, const char *p_function, const cha } builder.append("\n>> on function: "); - builder.append(p_function); + builder.append(String::utf8(p_function)); builder.append("()\n>> "); - builder.append(String(p_file).trim_prefix(self->base_dir)); + builder.append(String::utf8(p_file).trim_prefix(self->base_dir)); builder.append("\n>> "); builder.append(itos(p_line)); builder.append("\n>> "); - builder.append(p_error); + builder.append(String::utf8(p_error)); if (strlen(p_explanation) > 0) { builder.append("\n>> "); - builder.append(p_explanation); + builder.append(String::utf8(p_explanation)); } builder.append("\n"); diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 833bcb00e6..0d41ff025e 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -6851,7 +6851,7 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) { _process_mesh_instances(state, root); if (state->animations.size()) { AnimationPlayer *ap = memnew(AnimationPlayer); - root->add_child(ap); + root->add_child(ap, true); ap->set_owner(root); for (int i = 0; i < state->animations.size(); i++) { _import_animation(state, ap, i, p_bake_fps); diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 73315350ff..885817caf1 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -181,6 +181,9 @@ <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1"> The navigation layers the GridMap generates its navigable regions in. </member> + <member name="physics_material" type="PhysicsMaterial" setter="set_physics_material" getter="get_physics_material"> + Overrides the default friction and bounce physics properties for the whole [GridMap]. + </member> </members> <signals> <signal name="cell_size_changed"> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 3383daefea..a861efcbf4 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -34,6 +34,7 @@ #include "core/object/message_queue.h" #include "scene/3d/light_3d.h" #include "scene/resources/mesh_library.h" +#include "scene/resources/physics_material.h" #include "scene/resources/surface_tool.h" #include "scene/scene_string_names.h" #include "servers/navigation_server_3d.h" @@ -181,6 +182,15 @@ void GridMap::set_collision_mask_value(int p_layer_number, bool p_value) { set_collision_mask(mask); } +void GridMap::set_physics_material(Ref<PhysicsMaterial> p_material) { + physics_material = p_material; + _recreate_octant_data(); +} + +Ref<PhysicsMaterial> GridMap::get_physics_material() const { + return physics_material; +} + bool GridMap::get_collision_mask_value(int p_layer_number) const { ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); @@ -316,6 +326,10 @@ void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) { PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id()); PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer); PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask); + if (physics_material.is_valid()) { + PhysicsServer3D::get_singleton()->body_set_param(g->static_body, PhysicsServer3D::BODY_PARAM_FRICTION, physics_material->get_friction()); + PhysicsServer3D::get_singleton()->body_set_param(g->static_body, PhysicsServer3D::BODY_PARAM_BOUNCE, physics_material->get_bounce()); + } SceneTree *st = SceneTree::get_singleton(); if (st && st->is_debugging_collisions_hint()) { @@ -801,6 +815,9 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &GridMap::set_collision_layer_value); ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &GridMap::get_collision_layer_value); + ClassDB::bind_method(D_METHOD("set_physics_material", "material"), &GridMap::set_physics_material); + ClassDB::bind_method(D_METHOD("get_physics_material"), &GridMap::get_physics_material); + ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation); ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation); @@ -850,6 +867,7 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("make_baked_meshes", "gen_lightmap_uv", "lightmap_uv_texel_size"), &GridMap::make_baked_meshes, DEFVAL(false), DEFVAL(0.1)); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh_library", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"), "set_mesh_library", "get_mesh_library"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material", "get_physics_material"); ADD_GROUP("Cell", "cell_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cell_size"), "set_cell_size", "get_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_octant_size", "get_octant_size"); diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index db3395b6fe..546b530148 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -38,6 +38,8 @@ //heh heh, godotsphir!! this shares no code and the design is completely different with previous projects i've done.. //should scale better with hardware that supports instancing +class PhysicsMaterial; + class GridMap : public Node3D { GDCLASS(GridMap, Node3D); @@ -134,6 +136,7 @@ class GridMap : public Node3D { uint32_t collision_layer = 1; uint32_t collision_mask = 1; + Ref<PhysicsMaterial> physics_material; bool bake_navigation = false; uint32_t navigation_layers = 1; @@ -223,6 +226,9 @@ public: void set_collision_mask_value(int p_layer_number, bool p_value); bool get_collision_mask_value(int p_layer_number) const; + void set_physics_material(Ref<PhysicsMaterial> p_material); + Ref<PhysicsMaterial> get_physics_material() const; + void set_bake_navigation(bool p_bake_navigation); bool is_baking_navigation(); diff --git a/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs new file mode 100644 index 0000000000..00fdc9968e --- /dev/null +++ b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs @@ -0,0 +1,67 @@ +// meta-description: Visual shader's node plugin template + +using _BINDINGS_NAMESPACE_; +using System; + +public partial class VisualShaderNode_CLASS_ : _BASE_ +{ + public override string _GetName() + { + return "_CLASS_"; + } + + public override string _GetCategory() + { + return ""; + } + + public override string _GetDescription() + { + return ""; + } + + public override int _GetReturnIconType() + { + return 0; + } + + public override int _GetInputPortCount() + { + return 0; + } + + public override string _GetInputPortName(int port) + { + return ""; + } + + public override int _GetInputPortType(int port) + { + return 0; + } + + public override int _GetOutputPortCount() + { + return 1; + } + + public override string _GetOutputPortName(int port) + { + return "result"; + } + + public override int _GetOutputPortType(int port) + { + return 0; + } + + public override string _GetGlobalCode(Shader.Mode mode) + { + return ""; + } + + public override string _GetCode(Godot.Collections.Array inputVars, Godot.Collections.Array outputVars, Shader.Mode mode, VisualShader.Type type) + { + return ""; + } +} diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm index 91a2e6c228..da21ad0ace 100644 --- a/platform/iphone/ios.mm +++ b/platform/iphone/ios.mm @@ -65,7 +65,7 @@ String iOS::get_model() const { NSString *platform = [NSString stringWithCString:model encoding:NSUTF8StringEncoding]; free(model); const char *str = [platform UTF8String]; - return String(str != nullptr ? str : ""); + return String::utf8(str != nullptr ? str : ""); } String iOS::get_rate_url(int p_app_id) const { diff --git a/platform/iphone/joypad_iphone.mm b/platform/iphone/joypad_iphone.mm index 8c6e546515..2630b42da0 100644 --- a/platform/iphone/joypad_iphone.mm +++ b/platform/iphone/joypad_iphone.mm @@ -159,7 +159,7 @@ void JoypadIPhone::start_processing() { }; // tell Godot about our new controller - Input::get_singleton()->joy_connection_changed(joy_id, true, [controller.vendorName UTF8String]); + Input::get_singleton()->joy_connection_changed(joy_id, true, String::utf8([controller.vendorName UTF8String])); // add it to our dictionary, this will retain our controllers [self.connectedJoypads setObject:controller forKey:[NSNumber numberWithInt:joy_id]]; diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index f0b06d841e..5d960ef80c 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -500,7 +500,7 @@ void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_c return; } // Call input_text - Variant event = String(p_text); + Variant event = String::utf8(p_text); Variant *eventp = &event; Variant ret; Callable::CallError ce; @@ -590,7 +590,7 @@ Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() { // Clipboard void DisplayServerJavaScript::update_clipboard_callback(const char *p_text) { - get_singleton()->clipboard = p_text; + get_singleton()->clipboard = String::utf8(p_text); } void DisplayServerJavaScript::clipboard_set(const String &p_text) { diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index fe891e1c6a..b5f127bb16 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -431,7 +431,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { if (trash_path.is_empty()) { char *dhome = getenv("XDG_DATA_HOME"); if (dhome) { - trash_path = String(dhome) + "/Trash"; + trash_path = String::utf8(dhome) + "/Trash"; } } @@ -439,7 +439,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { if (trash_path.is_empty()) { char *home = getenv("HOME"); if (home) { - trash_path = String(home) + "/.local/share/Trash"; + trash_path = String::utf8(home) + "/.local/share/Trash"; } } diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index e57b503ddc..7d07b0076b 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -586,7 +586,7 @@ void OS_OSX::run() { quit = true; } } @catch (NSException *exception) { - ERR_PRINT("NSException: " + String([exception reason].UTF8String)); + ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String)); } }; @@ -602,7 +602,7 @@ Error OS_OSX::move_to_trash(const String &p_path) { NSError *err; if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) { - ERR_PRINT("trashItemAtURL error: " + String(err.localizedDescription.UTF8String)); + ERR_PRINT("trashItemAtURL error: " + String::utf8(err.localizedDescription.UTF8String)); return FAILED; } diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 728f9a1616..57603c6655 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -443,7 +443,7 @@ String OS_UWP::get_name() const { OS::Date OS_UWP::get_date(bool p_utc) const { SYSTEMTIME systemtime; - if (utc) { + if (p_utc) { GetSystemTime(&systemtime); } else { GetLocalTime(&systemtime); @@ -460,10 +460,11 @@ OS::Date OS_UWP::get_date(bool p_utc) const { OS::Time OS_UWP::get_time(bool p_utc) const { SYSTEMTIME systemtime; - if (utc) + if (p_utc) { GetSystemTime(&systemtime); - else + } else { GetLocalTime(&systemtime); + } Time time; time.hour = systemtime.wHour; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 4426a646f4..a992d2aaf2 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -33,6 +33,7 @@ #include "core/object/message_queue.h" #include "scene/3d/visual_instance_3d.h" #include "scene/main/viewport.h" +#include "scene/property_utils.h" #include "scene/scene_string_names.h" /* @@ -837,6 +838,64 @@ void Node3D::_validate_property(PropertyInfo &property) const { } } +bool Node3D::property_can_revert(const String &p_name) { + if (p_name == "basis") { + return true; + } else if (p_name == "scale") { + return true; + } else if (p_name == "quaternion") { + return true; + } else if (p_name == "rotation") { + return true; + } else if (p_name == "position") { + return true; + } + return false; +} + +Variant Node3D::property_get_revert(const String &p_name) { + Variant r_ret; + bool valid = false; + + if (p_name == "basis") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Transform3D(variant).get_basis(); + } else { + r_ret = Basis(); + } + } else if (p_name == "scale") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Transform3D(variant).get_basis().get_scale(); + } else { + return Vector3(1.0, 1.0, 1.0); + } + } else if (p_name == "quaternion") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Quaternion(Transform3D(variant).get_basis()); + } else { + return Quaternion(); + } + } else if (p_name == "rotation") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Transform3D(variant).get_basis().get_euler_normalized(data.rotation_order); + } else { + return Vector3(); + } + } else if (p_name == "position") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid) { + r_ret = Transform3D(variant).get_origin(); + } else { + return Vector3(); + } + } + return r_ret; +} + void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform); ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform); @@ -908,6 +967,9 @@ void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node3D::to_local); ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node3D::to_global); + ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &Node3D::property_can_revert); + ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &Node3D::property_get_revert); + BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED); BIND_CONSTANT(NOTIFICATION_ENTER_WORLD); BIND_CONSTANT(NOTIFICATION_EXIT_WORLD); @@ -926,6 +988,7 @@ void Node3D::_bind_methods() { //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ; ADD_GROUP("Transform", ""); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0,or_greater,or_lesser,noslider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation"); @@ -935,7 +998,6 @@ void Node3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_edit_mode", PROPERTY_HINT_ENUM, "Euler,Quaternion,Basis"), "set_rotation_edit_mode", "get_rotation_edit_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_order", PROPERTY_HINT_ENUM, "XYZ,XZY,YXZ,YZX,ZXY,ZYX"), "set_rotation_order", "get_rotation_order"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform"); ADD_GROUP("Visibility", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent"); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index ec62291d41..4abda66187 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -137,6 +137,9 @@ protected: virtual void _validate_property(PropertyInfo &property) const override; + bool property_can_revert(const String &p_name); + Variant property_get_revert(const String &p_name); + public: enum { NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED, diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index a942fc90aa..128c6cae8b 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -625,7 +625,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double pa->object->set_indexed(pa->subpath, value, &valid); //you are not speshul #ifdef DEBUG_ENABLED if (!valid) { - ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'."); + ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if the property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'."); } #endif @@ -1070,8 +1070,24 @@ void AnimationPlayer::_animation_update_transforms() { bool valid; pa->object->set_indexed(pa->subpath, pa->value_accum, &valid); //you are not speshul #ifdef DEBUG_ENABLED + if (!valid) { - ERR_PRINT("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property"); + // Get subpath as string for printing the error + // Cannot use `String::join(Vector<String>)` because this is a vector of StringName + String key_debug; + if (pa->subpath.size() > 0) { + key_debug = pa->subpath[0]; + for (int subpath_index = 1; subpath_index < pa->subpath.size(); ++subpath_index) { + key_debug += "."; + key_debug += pa->subpath[subpath_index]; + } + } + ERR_PRINT("Failed setting key '" + key_debug + + "' at time " + rtos(playback.current.pos) + + " in Animation '" + get_current_animation() + + "' at Node '" + get_path() + + "', Track '" + String(pa->owner->path) + + "'. Check if the property exists or the type of key is right for the property."); } #endif diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index eb3dafa2b1..398b909195 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -143,7 +143,6 @@ void CodeEdit::_notification(int p_what) { code_completion_line_ofs = CLAMP(code_completion_current_selected - lines / 2, 0, code_completion_options_count - lines); RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, code_completion_rect.position.y + (code_completion_current_selected - code_completion_line_ofs) * row_height), Size2(code_completion_rect.size.width, row_height)), code_completion_selected_color); - draw_rect(Rect2(code_completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(code_completion_base_width, code_completion_rect.size.width - (icon_area_size.x + icon_hsep)), code_completion_rect.size.height)), code_completion_existing_color); for (int i = 0; i < lines; i++) { int l = code_completion_line_ofs + i; @@ -177,6 +176,17 @@ void CodeEdit::_notification(int p_what) { } tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); } + + Point2 match_pos = Point2(code_completion_rect.position.x + icon_area_size.x + icon_hsep, code_completion_rect.position.y + i * row_height); + + for (int j = 0; j < code_completion_options[l].matches.size(); j++) { + Pair<int, int> match = code_completion_options[l].matches[j]; + int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), font_size).width; + int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), font_size).width; + + draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), code_completion_existing_color); + } + tl->draw(ci, title_pos, code_completion_options[l].font_color); } @@ -2808,6 +2818,8 @@ void CodeEdit::_filter_code_completion_candidates_impl() { code_completion_base = string_to_complete; Vector<ScriptCodeCompletionOption> completion_options_casei; + Vector<ScriptCodeCompletionOption> completion_options_substr; + Vector<ScriptCodeCompletionOption> completion_options_substr_casei; Vector<ScriptCodeCompletionOption> completion_options_subseq; Vector<ScriptCodeCompletionOption> completion_options_subseq_casei; @@ -2862,35 +2874,100 @@ void CodeEdit::_filter_code_completion_candidates_impl() { const char32_t *tgt = &option.display[0]; const char32_t *tgt_lower = &display_lower[0]; - const char32_t *ssq_last_tgt = nullptr; - const char32_t *ssq_lower_last_tgt = nullptr; + const char32_t *sst = &string_to_complete[0]; + const char32_t *sst_lower = &display_lower[0]; + + Vector<Pair<int, int>> ssq_matches; + int ssq_match_start = 0; + int ssq_match_len = 0; + + Vector<Pair<int, int>> ssq_lower_matches; + int ssq_lower_match_start = 0; + int ssq_lower_match_len = 0; + + int sst_start = -1; + int sst_lower_start = -1; + + for (int i = 0; *tgt; tgt++, tgt_lower++, i++) { + // Check substring. + if (*sst == *tgt) { + sst++; + if (sst_start == -1) { + sst_start = i; + } + } else if (sst_start != -1 && *sst) { + sst = &string_to_complete[0]; + sst_start = -1; + } - for (; *tgt; tgt++, tgt_lower++) { + // Check subsequence. if (*ssq == *tgt) { ssq++; - ssq_last_tgt = tgt; + if (ssq_match_len == 0) { + ssq_match_start = i; + } + ssq_match_len++; + } else if (ssq_match_len > 0) { + ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len)); + ssq_match_len = 0; } + + // Check lower substring. + if (*sst_lower == *tgt) { + sst_lower++; + if (sst_lower_start == -1) { + sst_lower_start = i; + } + } else if (sst_lower_start != -1 && *sst_lower) { + sst_lower = &string_to_complete[0]; + sst_lower_start = -1; + } + + // Check lower subsequence. if (*ssq_lower == *tgt_lower) { ssq_lower++; - ssq_lower_last_tgt = tgt; + if (ssq_lower_match_len == 0) { + ssq_lower_match_start = i; + } + ssq_lower_match_len++; + } else if (ssq_lower_match_len > 0) { + ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len)); + ssq_lower_match_len = 0; } } /* Matched the whole subsequence in s. */ - if (!*ssq) { - /* Finished matching in the first s.length() characters. */ - if (ssq_last_tgt == &option.display[string_to_complete.length() - 1]) { + if (!*ssq) { // Matched the whole subsequence in s. + option.matches.clear(); + + if (sst_start == 0) { // Matched substring in beginning of s. + option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length())); code_completion_options.push_back(option); + } else if (sst_start > 0) { // Matched substring in s. + option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length())); + completion_options_substr.push_back(option); } else { + if (ssq_match_len > 0) { + ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len)); + } + option.matches.append_array(ssq_matches); completion_options_subseq.push_back(option); } max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); - /* Matched the whole subsequence in s_lower. */ - } else if (!*ssq_lower) { - /* Finished matching in the first s.length() characters. */ - if (ssq_lower_last_tgt == &option.display[string_to_complete.length() - 1]) { + } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower. + option.matches.clear(); + + if (sst_lower_start == 0) { // Matched substring in beginning of s_lower. + option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length())); completion_options_casei.push_back(option); + } else if (sst_lower_start > 0) { // Matched substring in s_lower. + option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length())); + completion_options_substr_casei.push_back(option); } else { + if (ssq_lower_match_len > 0) { + ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len)); + } + option.matches.append_array(ssq_lower_matches); completion_options_subseq_casei.push_back(option); } max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index e4a5b265e3..69e6d74292 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1149,12 +1149,12 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_ Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_theme_base_scale()) { - return theme_owner->data.theme->get_default_theme_base_scale(); + if (theme_owner && theme_owner->data.theme->has_default_base_scale()) { + return theme_owner->data.theme->get_default_base_scale(); } - if (theme_owner_window && theme_owner_window->theme->has_default_theme_base_scale()) { - return theme_owner_window->theme->get_default_theme_base_scale(); + if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) { + return theme_owner_window->theme->get_default_base_scale(); } Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); @@ -1176,13 +1176,16 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_ // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_theme_base_scale()) { - return Theme::get_project_default()->get_default_theme_base_scale(); + if (Theme::get_project_default()->has_default_base_scale()) { + return Theme::get_project_default()->get_default_base_scale(); } } // Lastly, fall back on the default Theme. - return Theme::get_default()->get_default_theme_base_scale(); + if (Theme::get_default()->has_default_base_scale()) { + return Theme::get_default()->get_default_base_scale(); + } + return Theme::get_fallback_base_scale(); } float Control::get_theme_default_base_scale() const { @@ -1197,12 +1200,12 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_theme_font()) { - return theme_owner->data.theme->get_default_theme_font(); + if (theme_owner && theme_owner->data.theme->has_default_font()) { + return theme_owner->data.theme->get_default_font(); } - if (theme_owner_window && theme_owner_window->theme->has_default_theme_font()) { - return theme_owner_window->theme->get_default_theme_font(); + if (theme_owner_window && theme_owner_window->theme->has_default_font()) { + return theme_owner_window->theme->get_default_font(); } Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); @@ -1224,13 +1227,16 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_theme_font()) { - return Theme::get_project_default()->get_default_theme_font(); + if (Theme::get_project_default()->has_default_font()) { + return Theme::get_project_default()->get_default_font(); } } // Lastly, fall back on the default Theme. - return Theme::get_default()->get_default_theme_font(); + if (Theme::get_default()->has_default_font()) { + return Theme::get_default()->get_default_font(); + } + return Theme::get_fallback_font(); } Ref<Font> Control::get_theme_default_font() const { @@ -1245,12 +1251,12 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_theme_font_size()) { - return theme_owner->data.theme->get_default_theme_font_size(); + if (theme_owner && theme_owner->data.theme->has_default_font_size()) { + return theme_owner->data.theme->get_default_font_size(); } - if (theme_owner_window && theme_owner_window->theme->has_default_theme_font_size()) { - return theme_owner_window->theme->get_default_theme_font_size(); + if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) { + return theme_owner_window->theme->get_default_font_size(); } Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); @@ -1272,13 +1278,16 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_theme_font_size()) { - return Theme::get_project_default()->get_default_theme_font_size(); + if (Theme::get_project_default()->has_default_font_size()) { + return Theme::get_project_default()->get_default_font_size(); } } // Lastly, fall back on the default Theme. - return Theme::get_default()->get_default_theme_font_size(); + if (Theme::get_default()->has_default_font_size()) { + return Theme::get_default()->get_default_font_size(); + } + return Theme::get_fallback_font_size(); } int Control::get_theme_default_font_size() const { diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 1ddec4f587..92c770429b 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -600,6 +600,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { to = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(to)) { connecting = true; + emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, false); } return; } @@ -616,6 +617,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; connecting_to = pos; just_disconnected = false; + emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, true); return; } } @@ -642,6 +644,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { fr = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(fr)) { connecting = true; + emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, true); } return; } @@ -658,7 +661,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; connecting_to = pos; just_disconnected = false; - + emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, false); return; } } @@ -740,11 +743,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { } } - connecting = false; - top_layer->update(); - minimap->update(); - update(); - connections_layer->update(); + if (connecting) { + force_connection_drag_end(); + } } } @@ -1162,9 +1163,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { minimap->update(); } else { if (connecting) { - connecting = false; - top_layer->update(); - minimap->update(); + force_connection_drag_end(); } else { emit_signal(SNAME("popup_request"), get_screen_position() + b->get_position()); } @@ -1394,6 +1393,17 @@ void GraphEdit::clear_connections() { connections_layer->update(); } +void GraphEdit::force_connection_drag_end() { + ERR_FAIL_COND_MSG(!connecting, "Drag end requested without active drag!"); + connecting = false; + connecting_valid = false; + top_layer->update(); + minimap->update(); + update(); + connections_layer->update(); + emit_signal(SNAME("connection_drag_ended")); +} + void GraphEdit::set_zoom(float p_zoom) { set_zoom_custom(p_zoom, get_size() / 2); } @@ -2165,6 +2175,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_connection_activity", "from", "from_port", "to", "to_port", "amount"), &GraphEdit::set_connection_activity); ClassDB::bind_method(D_METHOD("get_connection_list"), &GraphEdit::_get_connection_list); ClassDB::bind_method(D_METHOD("clear_connections"), &GraphEdit::clear_connections); + ClassDB::bind_method(D_METHOD("force_connection_drag_end"), &GraphEdit::force_connection_drag_end); ClassDB::bind_method(D_METHOD("get_scroll_ofs"), &GraphEdit::get_scroll_ofs); ClassDB::bind_method(D_METHOD("set_scroll_ofs", "ofs"), &GraphEdit::set_scroll_ofs); @@ -2262,6 +2273,8 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("begin_node_move")); ADD_SIGNAL(MethodInfo("end_node_move")); ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "ofs"))); + ADD_SIGNAL(MethodInfo("connection_drag_begun", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::STRING, "slot"), PropertyInfo(Variant::BOOL, "is_output"))); + ADD_SIGNAL(MethodInfo("connection_drag_ended")); } GraphEdit::GraphEdit() { diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 7cbd0d179d..f1c4e95e38 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -267,6 +267,7 @@ public: bool is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); void disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); void clear_connections(); + void force_connection_drag_end(); void set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity); diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index 6cc64e7ada..760144591e 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -54,6 +54,7 @@ Size2 SubViewportContainer::get_minimum_size() const { void SubViewportContainer::set_stretch(bool p_enable) { stretch = p_enable; + update_minimum_size(); queue_sort(); update(); } diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index f4a0a2fa56..f7ae101690 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -510,6 +510,13 @@ void TabBar::_notification(int p_what) { } } +void TabBar::set_tab_count(int p_count) { + ERR_FAIL_COND(p_count < 0); + tabs.resize(p_count); + update(); + notify_property_list_changed(); +} + int TabBar::get_tab_count() const { return tabs.size(); } @@ -635,7 +642,7 @@ void TabBar::set_tab_disabled(int p_tab, bool p_disabled) { update(); } -bool TabBar::get_tab_disabled(int p_tab) const { +bool TabBar::is_tab_disabled(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), false); return tabs[p_tab].disabled; } @@ -765,13 +772,9 @@ void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { Tab t; t.text = p_str; t.xl_text = atr(p_str); - t.text_buf.instantiate(); t.text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); t.text_buf->add_string(t.xl_text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), Dictionary(), TranslationServer::get_singleton()->get_tool_locale()); t.icon = p_icon; - t.disabled = false; - t.ofs_cache = 0; - t.size_cache = 0; tabs.push_back(t); _update_cache(); @@ -786,6 +789,7 @@ void TabBar::clear_tabs() { previous = 0; call_deferred(SNAME("_update_hover")); update(); + notify_property_list_changed(); } void TabBar::remove_tab(int p_idx) { @@ -808,6 +812,7 @@ void TabBar::remove_tab(int p_idx) { } _ensure_no_over_offset(); + notify_property_list_changed(); } Variant TabBar::get_drag_data(const Point2 &p_point) { @@ -966,6 +971,7 @@ void TabBar::move_tab(int from, int to) { _update_cache(); update(); + notify_property_list_changed(); } int TabBar::get_tab_width(int p_idx) const { @@ -1128,8 +1134,61 @@ bool TabBar::get_select_with_rmb() const { return select_with_rmb; } +bool TabBar::_set(const StringName &p_name, const Variant &p_value) { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) { + int tab_index = components[0].trim_prefix("tab_").to_int(); + String property = components[1]; + if (property == "title") { + set_tab_title(tab_index, p_value); + return true; + } else if (property == "icon") { + set_tab_icon(tab_index, p_value); + return true; + } else if (components[1] == "disabled") { + set_tab_disabled(tab_index, p_value); + return true; + } + } + return false; +} + +bool TabBar::_get(const StringName &p_name, Variant &r_ret) const { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) { + int tab_index = components[0].trim_prefix("tab_").to_int(); + String property = components[1]; + if (property == "title") { + r_ret = get_tab_title(tab_index); + return true; + } else if (property == "icon") { + r_ret = get_tab_icon(tab_index); + return true; + } else if (components[1] == "disabled") { + r_ret = is_tab_disabled(tab_index); + return true; + } + } + return false; +} + +void TabBar::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < tabs.size(); i++) { + p_list->push_back(PropertyInfo(Variant::STRING, vformat("tab_%d/title", i))); + + PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("tab_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); + pi.usage &= ~(get_tab_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + + pi = PropertyInfo(Variant::BOOL, vformat("tab_%d/disabled", i)); + pi.usage &= ~(!is_tab_disabled(i) ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + } +} + void TabBar::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_hover"), &TabBar::_update_hover); + ClassDB::bind_method(D_METHOD("set_tab_count"), &TabBar::set_tab_count); ClassDB::bind_method(D_METHOD("get_tab_count"), &TabBar::get_tab_count); ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &TabBar::set_current_tab); ClassDB::bind_method(D_METHOD("get_current_tab"), &TabBar::get_current_tab); @@ -1146,7 +1205,7 @@ void TabBar::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabBar::set_tab_icon); ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &TabBar::get_tab_icon); ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabBar::set_tab_disabled); - ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &TabBar::get_tab_disabled); + ClassDB::bind_method(D_METHOD("is_tab_disabled", "tab_idx"), &TabBar::is_tab_disabled); ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &TabBar::remove_tab); ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &TabBar::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>())); ClassDB::bind_method(D_METHOD("set_tab_alignment", "alignment"), &TabBar::set_tab_alignment); @@ -1184,6 +1243,8 @@ void TabBar::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled"); + ADD_ARRAY_COUNT("Tabs", "tab_count", "set_tab_count", "get_tab_count", "tab_"); + BIND_ENUM_CONSTANT(ALIGNMENT_LEFT); BIND_ENUM_CONSTANT(ALIGNMENT_CENTER); BIND_ENUM_CONSTANT(ALIGNMENT_RIGHT); diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h index d9f9cca305..1741481b40 100644 --- a/scene/gui/tab_bar.h +++ b/scene/gui/tab_bar.h @@ -73,6 +73,10 @@ private: Ref<Texture2D> right_button; Rect2 rb_rect; Rect2 cb_rect; + + Tab() { + text_buf.instantiate(); + } }; int offset = 0; @@ -112,6 +116,9 @@ private: protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; void _notification(int p_what); static void _bind_methods(); @@ -140,7 +147,7 @@ public: Ref<Texture2D> get_tab_icon(int p_tab) const; void set_tab_disabled(int p_tab, bool p_disabled); - bool get_tab_disabled(int p_tab) const; + bool is_tab_disabled(int p_tab) const; void set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button); Ref<Texture2D> get_tab_right_button(int p_tab) const; @@ -156,7 +163,9 @@ public: void set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy); CloseButtonDisplayPolicy get_tab_close_display_policy() const; + void set_tab_count(int p_count); int get_tab_count() const; + void set_current_tab(int p_current); int get_current_tab() const; int get_previous_tab() const; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 0a9f98bb2f..3e63ba7869 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -48,6 +48,7 @@ #include "scene/gui/label.h" #include "scene/gui/popup.h" #include "scene/gui/popup_menu.h" +#include "scene/gui/subviewport_container.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" #include "scene/resources/mesh.h" @@ -3865,6 +3866,11 @@ Viewport::~Viewport() { void SubViewport::set_size(const Size2i &p_size) { _set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true); + + SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent()); + if (c) { + c->update_minimum_size(); + } } Size2i SubViewport::get_size() const { diff --git a/scene/property_utils.cpp b/scene/property_utils.cpp index e2f1ac8224..2540a633a9 100644 --- a/scene/property_utils.cpp +++ b/scene/property_utils.cpp @@ -111,10 +111,37 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const } // Fall back to the default from the native class - if (r_is_class_default) { - *r_is_class_default = true; + { + if (r_is_class_default) { + *r_is_class_default = true; + } + bool valid = false; + Variant value = ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property, &valid); + if (valid) { + if (r_is_valid) { + *r_is_valid = true; + } + return value; + } else { + // Heuristically check if this is a synthetic property (whatever/0, whatever/1, etc.) + // because they are not in the class DB yet must have a default (null). + String prop_str = String(p_property); + int p = prop_str.rfind("/"); + if (p != -1 && p < prop_str.length() - 1) { + bool all_digits = true; + for (int i = p + 1; i < prop_str.length(); i++) { + if (prop_str[i] < '0' || prop_str[i] > '9') { + all_digits = false; + break; + } + } + if (r_is_valid) { + *r_is_valid = all_digits; + } + } + return Variant(); + } } - return ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property, r_is_valid); } // Like SceneState::PackState, but using a raw pointer to avoid the cost of diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 933021db75..e6b73b7780 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -1071,7 +1071,7 @@ void initialize_theme() { if (theme.is_valid()) { Theme::set_project_default(theme); if (font.is_valid()) { - Theme::set_default_font(font); + Theme::set_fallback_font(font); } } else { ERR_PRINT("Error loading custom theme '" + theme_path + "'"); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 48d36ff2f7..549bd3ba12 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -1053,17 +1053,17 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) { fill_default_theme(t, default_font, large_font, default_icon, default_style, default_scale); Theme::set_default(t); - Theme::set_default_base_scale(default_scale); - Theme::set_default_icon(default_icon); - Theme::set_default_style(default_style); - Theme::set_default_font(default_font); - Theme::set_default_font_size(default_font_size); + Theme::set_fallback_base_scale(default_scale); + Theme::set_fallback_icon(default_icon); + Theme::set_fallback_style(default_style); + Theme::set_fallback_font(default_font); + Theme::set_fallback_font_size(default_font_size); } void clear_default_theme() { Theme::set_project_default(nullptr); Theme::set_default(nullptr); - Theme::set_default_icon(nullptr); - Theme::set_default_style(nullptr); - Theme::set_default_font(nullptr); + Theme::set_fallback_icon(nullptr); + Theme::set_fallback_style(nullptr); + Theme::set_fallback_font(nullptr); } diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index b36204241a..f3e5ece1f9 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1659,18 +1659,6 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const { void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) { ERR_FAIL_INDEX(p_param, TEXTURE_MAX); - if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) { - // If no roughness texture is currently set, automatically set the recommended value - // for roughness when using a roughness map. - set_roughness(1.0); - } - - if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) { - // If no metallic texture is currently set, automatically set the recommended value - // for metallic when using a metallic map. - set_metallic(1.0); - } - textures[p_param] = p_texture; RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 186bbab689..8da287042e 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -36,11 +36,11 @@ Ref<Theme> Theme::default_theme; Ref<Theme> Theme::project_default_theme; // Universal default values, final fallback for every theme. -float Theme::default_base_scale = 1.0; -Ref<Texture2D> Theme::default_icon; -Ref<StyleBox> Theme::default_style; -Ref<Font> Theme::default_font; -int Theme::default_font_size = 16; +float Theme::fallback_base_scale = 1.0; +Ref<Texture2D> Theme::fallback_icon; +Ref<StyleBox> Theme::fallback_style; +Ref<Font> Theme::fallback_font; +int Theme::fallback_font_size = 16; // Dynamic properties. bool Theme::_set(const StringName &p_name, const Variant &p_value) { @@ -220,87 +220,107 @@ void Theme::set_project_default(const Ref<Theme> &p_project_default) { } // Universal fallback values for theme item types. -void Theme::set_default_base_scale(float p_base_scale) { - default_base_scale = p_base_scale; +void Theme::set_fallback_base_scale(float p_base_scale) { + fallback_base_scale = p_base_scale; } -void Theme::set_default_icon(const Ref<Texture2D> &p_icon) { - default_icon = p_icon; +void Theme::set_fallback_icon(const Ref<Texture2D> &p_icon) { + fallback_icon = p_icon; } -void Theme::set_default_style(const Ref<StyleBox> &p_style) { - default_style = p_style; +void Theme::set_fallback_style(const Ref<StyleBox> &p_style) { + fallback_style = p_style; } -void Theme::set_default_font(const Ref<Font> &p_font) { - default_font = p_font; +void Theme::set_fallback_font(const Ref<Font> &p_font) { + fallback_font = p_font; } -void Theme::set_default_font_size(int p_font_size) { - default_font_size = p_font_size; +void Theme::set_fallback_font_size(int p_font_size) { + fallback_font_size = p_font_size; +} + +float Theme::get_fallback_base_scale() { + return fallback_base_scale; +} + +Ref<Texture2D> Theme::get_fallback_icon() { + return fallback_icon; +} + +Ref<StyleBox> Theme::get_fallback_style() { + return fallback_style; +} + +Ref<Font> Theme::get_fallback_font() { + return fallback_font; +} + +int Theme::get_fallback_font_size() { + return fallback_font_size; } // Fallback values for theme item types, configurable per theme. -void Theme::set_default_theme_base_scale(float p_base_scale) { - if (default_theme_base_scale == p_base_scale) { +void Theme::set_default_base_scale(float p_base_scale) { + if (default_base_scale == p_base_scale) { return; } - default_theme_base_scale = p_base_scale; + default_base_scale = p_base_scale; _emit_theme_changed(); } -float Theme::get_default_theme_base_scale() const { - return default_theme_base_scale; +float Theme::get_default_base_scale() const { + return default_base_scale; } -bool Theme::has_default_theme_base_scale() const { - return default_theme_base_scale > 0.0; +bool Theme::has_default_base_scale() const { + return default_base_scale > 0.0; } -void Theme::set_default_theme_font(const Ref<Font> &p_default_font) { - if (default_theme_font == p_default_font) { +void Theme::set_default_font(const Ref<Font> &p_default_font) { + if (default_font == p_default_font) { return; } - if (default_theme_font.is_valid()) { - default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (default_font.is_valid()) { + default_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - default_theme_font = p_default_font; + default_font = p_default_font; - if (default_theme_font.is_valid()) { - default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + if (default_font.is_valid()) { + default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(); } -Ref<Font> Theme::get_default_theme_font() const { - return default_theme_font; +Ref<Font> Theme::get_default_font() const { + return default_font; } -bool Theme::has_default_theme_font() const { - return default_theme_font.is_valid(); +bool Theme::has_default_font() const { + return default_font.is_valid(); } -void Theme::set_default_theme_font_size(int p_font_size) { - if (default_theme_font_size == p_font_size) { +void Theme::set_default_font_size(int p_font_size) { + if (default_font_size == p_font_size) { return; } - default_theme_font_size = p_font_size; + default_font_size = p_font_size; _emit_theme_changed(); } -int Theme::get_default_theme_font_size() const { - return default_theme_font_size; +int Theme::get_default_font_size() const { + return default_font_size; } -bool Theme::has_default_theme_font_size() const { - return default_theme_font_size > 0; +bool Theme::has_default_font_size() const { + return default_font_size > 0; } // Icons. @@ -324,7 +344,7 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_the if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) { return icon_map[p_theme_type][p_name]; } else { - return default_icon; + return fallback_icon; } } @@ -411,7 +431,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_ if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) { return style_map[p_theme_type][p_name]; } else { - return default_style; + return fallback_style; } } @@ -497,15 +517,15 @@ void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, c Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_type) const { if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) { return font_map[p_theme_type][p_name]; - } else if (has_default_theme_font()) { - return default_theme_font; - } else { + } else if (has_default_font()) { return default_font; + } else { + return fallback_font; } } bool Theme::has_font(const StringName &p_name, const StringName &p_theme_type) const { - return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_theme_font()); + return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_font()); } bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const { @@ -577,15 +597,15 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_ty int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const { if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) { return font_size_map[p_theme_type][p_name]; - } else if (has_default_theme_font_size()) { - return default_theme_font_size; - } else { + } else if (has_default_font_size()) { return default_font_size; + } else { + return fallback_font_size; } } bool Theme::has_font_size(const StringName &p_name, const StringName &p_theme_type) const { - return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_theme_font_size()); + return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_font_size()); } bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const { @@ -1622,17 +1642,17 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("get_constant_list", "theme_type"), &Theme::_get_constant_list); ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list); - ClassDB::bind_method(D_METHOD("set_default_base_scale", "font_size"), &Theme::set_default_theme_base_scale); - ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_theme_base_scale); - ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_theme_base_scale); + ClassDB::bind_method(D_METHOD("set_default_base_scale", "base_scale"), &Theme::set_default_base_scale); + ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_base_scale); + ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_base_scale); - ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_theme_font); - ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_theme_font); - ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_theme_font); + ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_font); + ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_font); + ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_font); - ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_theme_font_size); - ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_theme_font_size); - ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_theme_font_size); + ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_font_size); + ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_font_size); + ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_font_size); ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "theme_type", "value"), &Theme::set_theme_item); ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "theme_type"), &Theme::get_theme_item); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 2e0a645005..822743a1fe 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -101,16 +101,16 @@ protected: static Ref<Theme> project_default_theme; // Universal default values, final fallback for every theme. - static float default_base_scale; - static Ref<Texture2D> default_icon; - static Ref<StyleBox> default_style; - static Ref<Font> default_font; - static int default_font_size; + static float fallback_base_scale; + static Ref<Texture2D> fallback_icon; + static Ref<StyleBox> fallback_style; + static Ref<Font> fallback_font; + static int fallback_font_size; // Default values configurable for each individual theme. - float default_theme_base_scale = 0.0; - Ref<Font> default_theme_font; - int default_theme_font_size = -1; + float default_base_scale = 0.0; + Ref<Font> default_font; + int default_font_size = -1; static void _bind_methods(); @@ -126,23 +126,29 @@ public: static Ref<Theme> get_project_default(); static void set_project_default(const Ref<Theme> &p_project_default); - static void set_default_base_scale(float p_base_scale); - static void set_default_icon(const Ref<Texture2D> &p_icon); - static void set_default_style(const Ref<StyleBox> &p_style); - static void set_default_font(const Ref<Font> &p_font); - static void set_default_font_size(int p_font_size); - - void set_default_theme_base_scale(float p_base_scale); - float get_default_theme_base_scale() const; - bool has_default_theme_base_scale() const; - - void set_default_theme_font(const Ref<Font> &p_default_font); - Ref<Font> get_default_theme_font() const; - bool has_default_theme_font() const; - - void set_default_theme_font_size(int p_font_size); - int get_default_theme_font_size() const; - bool has_default_theme_font_size() const; + static void set_fallback_base_scale(float p_base_scale); + static void set_fallback_icon(const Ref<Texture2D> &p_icon); + static void set_fallback_style(const Ref<StyleBox> &p_style); + static void set_fallback_font(const Ref<Font> &p_font); + static void set_fallback_font_size(int p_font_size); + + static float get_fallback_base_scale(); + static Ref<Texture2D> get_fallback_icon(); + static Ref<StyleBox> get_fallback_style(); + static Ref<Font> get_fallback_font(); + static int get_fallback_font_size(); + + void set_default_base_scale(float p_base_scale); + float get_default_base_scale() const; + bool has_default_base_scale() const; + + void set_default_font(const Ref<Font> &p_default_font); + Ref<Font> get_default_font() const; + bool has_default_font() const; + + void set_default_font_size(int p_font_size); + int get_default_font_size() const; + bool has_default_font_size() const; void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon); Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index ed34c906a1..57b73c1234 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -349,11 +349,11 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const { String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { ERR_FAIL_COND_V(!GDVIRTUAL_IS_OVERRIDDEN(_get_code), ""); - Vector<String> input_vars; + TypedArray<String> input_vars; for (int i = 0; i < get_input_port_count(); i++) { input_vars.push_back(p_input_vars[i]); } - Array output_vars; + TypedArray<String> output_vars; for (int i = 0; i < get_output_port_count(); i++) { output_vars.push_back(p_output_vars[i]); } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index c8b577088d..066c18e3bc 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -326,7 +326,7 @@ protected: GDVIRTUAL0RC(int, _get_output_port_count) GDVIRTUAL1RC(int, _get_output_port_type, int) GDVIRTUAL1RC(String, _get_output_port_name, int) - GDVIRTUAL4RC(String, _get_code, Vector<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) + GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) GDVIRTUAL1RC(String, _get_global_code, Shader::Mode) GDVIRTUAL0RC(bool, _is_highend) diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 6cce51cfaf..5507f206b5 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -1639,14 +1639,14 @@ void RendererStorageRD::material_initialize(RID p_rid) { } void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) { + material->uniform_dirty = material->uniform_dirty || p_uniform; + material->texture_dirty = material->texture_dirty || p_texture; + if (material->update_element.in_list()) { return; } material_update_list.add(&material->update_element); - - material->uniform_dirty = material->uniform_dirty || p_uniform; - material->texture_dirty = material->texture_dirty || p_texture; } void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 1db9593473..a94f70e20f 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2000,6 +2000,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(DECAL_FILTER_LINEAR_MIPMAPS); BIND_ENUM_CONSTANT(DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC); + /* GI API (affects VoxelGI and SDFGI) */ + + ClassDB::bind_method(D_METHOD("gi_set_use_half_resolution", "half_resolution"), &RenderingServer::gi_set_use_half_resolution); + /* VOXEL GI API */ ClassDB::bind_method(D_METHOD("voxel_gi_create"), &RenderingServer::voxel_gi_create); @@ -2325,6 +2329,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("environment_glow_set_use_high_quality", "enable"), &RenderingServer::environment_glow_set_use_high_quality); ClassDB::bind_method(D_METHOD("environment_set_ssr_roughness_quality", "quality"), &RenderingServer::environment_set_ssr_roughness_quality); ClassDB::bind_method(D_METHOD("environment_set_ssao_quality", "quality", "half_size", "adaptive_target", "blur_passes", "fadeout_from", "fadeout_to"), &RenderingServer::environment_set_ssao_quality); + ClassDB::bind_method(D_METHOD("environment_set_ssil_quality", "quality", "half_size", "adaptive_target", "blur_passes", "fadeout_from", "fadeout_to"), &RenderingServer::environment_set_ssil_quality); ClassDB::bind_method(D_METHOD("environment_set_sdfgi_ray_count", "ray_count"), &RenderingServer::environment_set_sdfgi_ray_count); ClassDB::bind_method(D_METHOD("environment_set_sdfgi_frames_to_converge", "frames"), &RenderingServer::environment_set_sdfgi_frames_to_converge); ClassDB::bind_method(D_METHOD("environment_set_sdfgi_frames_to_update_light", "frames"), &RenderingServer::environment_set_sdfgi_frames_to_update_light); @@ -2376,6 +2381,12 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_HIGH); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_ULTRA); + BIND_ENUM_CONSTANT(ENV_SSIL_QUALITY_VERY_LOW); + BIND_ENUM_CONSTANT(ENV_SSIL_QUALITY_LOW); + BIND_ENUM_CONSTANT(ENV_SSIL_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(ENV_SSIL_QUALITY_HIGH); + BIND_ENUM_CONSTANT(ENV_SSIL_QUALITY_ULTRA); + BIND_ENUM_CONSTANT(ENV_SDFGI_CASCADES_4); BIND_ENUM_CONSTANT(ENV_SDFGI_CASCADES_6); BIND_ENUM_CONSTANT(ENV_SDFGI_CASCADES_8); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index d36784dbab..ada50292fc 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -1608,6 +1608,7 @@ VARIANT_ENUM_CAST(RenderingServer::EnvironmentGlowBlendMode); VARIANT_ENUM_CAST(RenderingServer::EnvironmentToneMapper); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSRRoughnessQuality); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality); +VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSILQuality); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSDFGICascades); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSDFGIFramesToConverge); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSDFGIRayCount); diff --git a/tests/core/templates/test_local_vector.h b/tests/core/templates/test_local_vector.h index ca4a69b069..b2464c3914 100644 --- a/tests/core/templates/test_local_vector.h +++ b/tests/core/templates/test_local_vector.h @@ -37,6 +37,17 @@ namespace TestLocalVector { +TEST_CASE("[LocalVector] List Initialization.") { + LocalVector<int> vector{ 0, 1, 2, 3, 4 }; + + CHECK(vector.size() == 5); + CHECK(vector[0] == 0); + CHECK(vector[1] == 1); + CHECK(vector[2] == 2); + CHECK(vector[3] == 3); + CHECK(vector[4] == 4); +} + TEST_CASE("[LocalVector] Push Back.") { LocalVector<int> vector; vector.push_back(0); diff --git a/tests/core/templates/test_vector.h b/tests/core/templates/test_vector.h index b0dcff93fd..24b3547256 100644 --- a/tests/core/templates/test_vector.h +++ b/tests/core/templates/test_vector.h @@ -37,6 +37,17 @@ namespace TestVector { +TEST_CASE("[Vector] List initialization") { + Vector<int> vector{ 0, 1, 2, 3, 4 }; + + CHECK(vector.size() == 5); + CHECK(vector[0] == 0); + CHECK(vector[1] == 1); + CHECK(vector[2] == 2); + CHECK(vector[3] == 3); + CHECK(vector[4] == 4); +} + TEST_CASE("[Vector] Push back and append") { Vector<int> vector; vector.push_back(0); |