diff options
129 files changed, 1038 insertions, 565 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 2999154fd3..dbb72ae095 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -26,7 +26,7 @@ jobs: target: release_debug tools: true tests: false # Disabled due freeze caused by mix Mono build and CI - sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no + sconsflags: module_mono_enabled=yes doc-test: true bin: "./bin/godot.linuxbsd.opt.tools.64.mono" build-mono: true @@ -64,7 +64,7 @@ jobs: target: release tools: false tests: false - sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no + sconsflags: module_mono_enabled=yes debug_symbols=no build-mono: false artifact: true @@ -126,16 +126,6 @@ jobs: run: | ./modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --godot-platform=linuxbsd - # Rebuild with mono - - name: Compilation (mono_glue=yes) - uses: ./.github/actions/godot-build - if: ${{ matrix.build-mono }} - with: - sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }} mono_glue=yes - platform: linuxbsd - target: ${{ matrix.target }} - tools: ${{ matrix.tools }} - # Execute unit tests for the editor - name: Unit tests if: ${{ matrix.tests }} diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 6606557fce..3efc0e822a 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -36,6 +36,7 @@ #include "core/io/json.h" #include "core/license.gen.h" #include "core/os/os.h" +#include "core/variant/typed_array.h" #include "core/version.h" void Engine::set_physics_ticks_per_second(int p_ips) { @@ -136,8 +137,8 @@ Dictionary Engine::get_author_info() const { return dict; } -Array Engine::get_copyright_info() const { - Array components; +TypedArray<Dictionary> Engine::get_copyright_info() const { + TypedArray<Dictionary> components; for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) { const ComponentCopyright &cp_info = COPYRIGHT_INFO[component_index]; Dictionary component_dict; diff --git a/core/config/engine.h b/core/config/engine.h index b4364dbda4..121fd4d541 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -36,6 +36,9 @@ #include "core/templates/list.h" #include "core/templates/vector.h" +template <typename T> +class TypedArray; + class Engine { public: struct Singleton { @@ -139,7 +142,7 @@ public: Dictionary get_version_info() const; Dictionary get_author_info() const; - Array get_copyright_info() const; + TypedArray<Dictionary> get_copyright_info() const; Dictionary get_donor_info() const; Dictionary get_license_info() const; String get_license_text() const; diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 630bd68e65..7a9a2c4337 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -39,6 +39,7 @@ #include "core/math/geometry_2d.h" #include "core/math/geometry_3d.h" #include "core/os/keyboard.h" +#include "core/variant/typed_array.h" namespace core_bind { @@ -2022,10 +2023,10 @@ Dictionary ClassDB::get_signal(StringName p_class, StringName p_signal) const { } } -Array ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const { +TypedArray<Dictionary> ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const { List<MethodInfo> signals; ::ClassDB::get_signal_list(p_class, &signals, p_no_inheritance); - Array ret; + TypedArray<Dictionary> ret; for (const MethodInfo &E : signals) { ret.push_back(E.operator Dictionary()); @@ -2034,10 +2035,10 @@ Array ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const return ret; } -Array ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) const { +TypedArray<Dictionary> ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) const { List<PropertyInfo> plist; ::ClassDB::get_property_list(p_class, &plist, p_no_inheritance); - Array ret; + TypedArray<Dictionary> ret; for (const PropertyInfo &E : plist) { ret.push_back(E.operator Dictionary()); } @@ -2066,10 +2067,10 @@ bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inhe return ::ClassDB::has_method(p_class, p_method, p_no_inheritance); } -Array ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const { +TypedArray<Dictionary> ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const { List<MethodInfo> methods; ::ClassDB::get_method_list(p_class, &methods, p_no_inheritance); - Array ret; + TypedArray<Dictionary> ret; for (const MethodInfo &E : methods) { #ifdef DEBUG_METHODS_ENABLED @@ -2254,7 +2255,7 @@ Dictionary Engine::get_author_info() const { return ::Engine::get_singleton()->get_author_info(); } -Array Engine::get_copyright_info() const { +TypedArray<Dictionary> Engine::get_copyright_info() const { return ::Engine::get_singleton()->get_copyright_info(); } diff --git a/core/core_bind.h b/core/core_bind.h index 79230bd685..f7ba4f31cf 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -45,6 +45,8 @@ #include "core/templates/safe_refcount.h" class MainLoop; +template <typename T> +class TypedArray; namespace core_bind { @@ -602,15 +604,15 @@ public: bool has_signal(StringName p_class, StringName p_signal) const; Dictionary get_signal(StringName p_class, StringName p_signal) const; - Array get_signal_list(StringName p_class, bool p_no_inheritance = false) const; + TypedArray<Dictionary> get_signal_list(StringName p_class, bool p_no_inheritance = false) const; - Array get_property_list(StringName p_class, bool p_no_inheritance = false) const; + TypedArray<Dictionary> get_property_list(StringName p_class, bool p_no_inheritance = false) const; Variant get_property(Object *p_object, const StringName &p_property) const; Error set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const; bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false) const; - Array get_method_list(StringName p_class, bool p_no_inheritance = false) const; + TypedArray<Dictionary> get_method_list(StringName p_class, bool p_no_inheritance = false) const; PackedStringArray get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const; bool has_integer_constant(const StringName &p_class, const StringName &p_name) const; @@ -661,7 +663,7 @@ public: Dictionary get_version_info() const; Dictionary get_author_info() const; - Array get_copyright_info() const; + TypedArray<Dictionary> get_copyright_info() const; Dictionary get_donor_info() const; Dictionary get_license_info() const; String get_license_text() const; diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 867b1fc637..5cf951a93c 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -52,6 +52,9 @@ static String get_type_name(const PropertyInfo &p_info) { if (p_info.type == Variant::INT && (p_info.usage & (PROPERTY_USAGE_CLASS_IS_BITFIELD))) { return String("bitfield::") + String(p_info.class_name); } + if (p_info.type == Variant::INT && (p_info.usage & PROPERTY_USAGE_ARRAY)) { + return "int"; + } if (p_info.class_name != StringName()) { return p_info.class_name; } @@ -88,6 +91,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { } const uint32_t vec3_elems = 3; + const uint32_t vec4_elems = 4; const uint32_t ptrsize_32 = 4; const uint32_t ptrsize_64 = 8; static const char *build_config_name[4] = { "float_32", "float_64", "double_32", "double_64" }; @@ -138,7 +142,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::AABB, (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(double), (vec3_elems * 2) * sizeof(double) }, { Variant::BASIS, (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(double), (vec3_elems * 3) * sizeof(double) }, { Variant::TRANSFORM3D, (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(double), (vec3_elems * 4) * sizeof(double) }, - { Variant::PROJECTION, 4 * 4 * sizeof(float), 4 * 4 * sizeof(float), 4 * 4 * sizeof(double), 4 * 4 * sizeof(double) }, + { Variant::PROJECTION, (vec4_elems * 4) * sizeof(float), (vec4_elems * 4) * sizeof(float), (vec4_elems * 4) * sizeof(double), (vec4_elems * 4) * sizeof(double) }, { Variant::COLOR, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float) }, { Variant::STRING_NAME, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, { Variant::NODE_PATH, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, @@ -284,6 +288,10 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::BASIS, "z", vec3_elems * 2 * sizeof(float), vec3_elems * 2 * sizeof(float), vec3_elems * 2 * sizeof(double), vec3_elems * 2 * sizeof(double) }, { Variant::TRANSFORM3D, "basis", 0, 0, 0, 0 }, { Variant::TRANSFORM3D, "origin", (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(double), (vec3_elems * 3) * sizeof(double) }, + { Variant::PROJECTION, "x", 0, 0, 0, 0 }, + { Variant::PROJECTION, "y", vec4_elems * sizeof(float), vec4_elems * sizeof(float), vec4_elems * sizeof(double), vec4_elems * sizeof(double) }, + { Variant::PROJECTION, "z", vec4_elems * 2 * sizeof(float), vec4_elems * 2 * sizeof(float), vec4_elems * 2 * sizeof(double), vec4_elems * 2 * sizeof(double) }, + { Variant::PROJECTION, "w", vec4_elems * 3 * sizeof(float), vec4_elems * 3 * sizeof(float), vec4_elems * 3 * sizeof(double), vec4_elems * 3 * sizeof(double) }, { Variant::COLOR, "r", 0, 0, 0, 0 }, { Variant::COLOR, "g", sizeof(float), sizeof(float), sizeof(float), sizeof(float) }, { Variant::COLOR, "b", 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(float) }, @@ -840,12 +848,16 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<PropertyInfo> property_list; ClassDB::get_property_list(class_name, &property_list, true); for (const PropertyInfo &F : property_list) { - if (F.usage & PROPERTY_USAGE_CATEGORY || F.usage & PROPERTY_USAGE_GROUP || F.usage & PROPERTY_USAGE_SUBGROUP) { + if (F.usage & PROPERTY_USAGE_CATEGORY || F.usage & PROPERTY_USAGE_GROUP || F.usage & PROPERTY_USAGE_SUBGROUP || (F.type == Variant::NIL && F.usage & PROPERTY_USAGE_ARRAY)) { continue; //not real properties } if (F.name.begins_with("_")) { continue; //hidden property } + if (F.name.find("/") >= 0) { + // Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector. + continue; + } StringName property_name = F.name; Dictionary d2; d2["type"] = get_type_name(F); diff --git a/core/input/input.cpp b/core/input/input.cpp index e08647f5ea..ff7ac59e1f 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -767,9 +767,6 @@ Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, con return rel_warped; } -void Input::iteration(float p_step) { -} - void Input::action_press(const StringName &p_action, float p_strength) { Action action; diff --git a/core/input/input.h b/core/input/input.h index 3ad8c91ddf..a07174b887 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -114,6 +114,15 @@ private: int mouse_from_touch_index = -1; + struct VibrationInfo { + float weak_magnitude; + float strong_magnitude; + float duration; // Duration in seconds + uint64_t timestamp; + }; + + HashMap<int, VibrationInfo> joy_vibration; + struct VelocityTrack { uint64_t last_tick = 0; Vector2 velocity; @@ -226,15 +235,6 @@ private: EventDispatchFunc event_dispatch_function = nullptr; protected: - struct VibrationInfo { - float weak_magnitude; - float strong_magnitude; - float duration; // Duration in seconds - uint64_t timestamp; - }; - - HashMap<int, VibrationInfo> joy_vibration; - static void _bind_methods(); public: @@ -295,8 +295,6 @@ public: void action_press(const StringName &p_action, float p_strength = 1.f); void action_release(const StringName &p_action); - void iteration(float p_step); - void set_emulate_touch_from_mouse(bool p_emulate); bool is_emulating_touch_from_mouse() const; void ensure_touch_mouse_raised(); diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 41a0848d01..b4281820e2 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -209,8 +209,8 @@ bool AStar3D::has_point(int64_t p_id) const { return points.has(p_id); } -Array AStar3D::get_point_ids() { - Array point_list; +PackedInt64Array AStar3D::get_point_ids() { + PackedInt64Array point_list; for (OAHashMap<int64_t, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) { point_list.push_back(*(it.key)); @@ -605,7 +605,7 @@ Vector<int64_t> AStar2D::get_point_connections(int64_t p_id) { return astar.get_point_connections(p_id); } -Array AStar2D::get_point_ids() { +PackedInt64Array AStar2D::get_point_ids() { return astar.get_point_ids(); } diff --git a/core/math/a_star.h b/core/math/a_star.h index c1497d133f..a9e2a62bb2 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -133,7 +133,7 @@ public: void remove_point(int64_t p_id); bool has_point(int64_t p_id) const; Vector<int64_t> get_point_connections(int64_t p_id); - Array get_point_ids(); + PackedInt64Array get_point_ids(); void set_point_disabled(int64_t p_id, bool p_disabled = true); bool is_point_disabled(int64_t p_id) const; @@ -183,7 +183,7 @@ public: void remove_point(int64_t p_id); bool has_point(int64_t p_id) const; Vector<int64_t> get_point_connections(int64_t p_id); - Array get_point_ids(); + PackedInt64Array get_point_ids(); void set_point_disabled(int64_t p_id, bool p_disabled = true); bool is_point_disabled(int64_t p_id) const; diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 36358f6feb..c836a82e37 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -112,10 +112,11 @@ Quaternion Quaternion::exp() const { Quaternion src = *this; Vector3 src_v = Vector3(src.x, src.y, src.z); real_t theta = src_v.length(); - if (theta < CMP_EPSILON) { + src_v = src_v.normalized(); + if (theta < CMP_EPSILON || !src_v.is_normalized()) { return Quaternion(0, 0, 0, 1); } - return Quaternion(src_v.normalized(), theta); + return Quaternion(src_v, theta); } Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) const { diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 13be7516d5..c02be9e5b7 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3451,18 +3451,19 @@ String String::replacen(const String &p_key, const String &p_with) const { String String::repeat(int p_count) const { ERR_FAIL_COND_V_MSG(p_count < 0, "", "Parameter count should be a positive number."); - String new_string; - const char32_t *src = this->get_data(); - - new_string.resize(length() * p_count + 1); - new_string[length() * p_count] = 0; - - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < length(); j++) { - new_string[i * length() + j] = src[j]; - } - } - + int len = length(); + String new_string = *this; + new_string.resize(p_count * len + 1); + + char32_t *dst = new_string.ptrw(); + int offset = 1; + int stride = 1; + while (offset < p_count) { + memcpy(dst + offset * len, dst, stride * len * sizeof(char32_t)); + offset += stride; + stride = MIN(stride * 2, p_count - offset); + } + dst[p_count * len] = _null; return new_string; } diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml index 977e73e7ca..6e76df647e 100644 --- a/doc/classes/AStar2D.xml +++ b/doc/classes/AStar2D.xml @@ -218,7 +218,7 @@ </description> </method> <method name="get_point_ids"> - <return type="Array" /> + <return type="PackedInt64Array" /> <description> Returns an array of all point IDs. </description> diff --git a/doc/classes/AStar3D.xml b/doc/classes/AStar3D.xml index efce94e25d..45b1019bab 100644 --- a/doc/classes/AStar3D.xml +++ b/doc/classes/AStar3D.xml @@ -245,7 +245,7 @@ </description> </method> <method name="get_point_ids"> - <return type="Array" /> + <return type="PackedInt64Array" /> <description> Returns an array of all point IDs. </description> diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index 5bd1c82641..8dc80e3bdc 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -30,7 +30,7 @@ </description> </method> <method name="capture_get_device_list"> - <return type="Array" /> + <return type="PackedStringArray" /> <description> Returns the names of all audio input devices detected on the system. </description> @@ -117,7 +117,7 @@ </description> </method> <method name="get_device_list"> - <return type="Array" /> + <return type="PackedStringArray" /> <description> Returns the names of all audio devices detected on the system. </description> diff --git a/doc/classes/BitMap.xml b/doc/classes/BitMap.xml index 53fd9a7b67..9323642274 100644 --- a/doc/classes/BitMap.xml +++ b/doc/classes/BitMap.xml @@ -58,7 +58,7 @@ </description> </method> <method name="opaque_to_polygons" qualifiers="const"> - <return type="Array" /> + <return type="PackedVector2Array[]" /> <param index="0" name="rect" type="Rect2" /> <param index="1" name="epsilon" type="float" default="2.0" /> <description> diff --git a/doc/classes/ButtonGroup.xml b/doc/classes/ButtonGroup.xml index 8bedb5a1ac..277bda2836 100644 --- a/doc/classes/ButtonGroup.xml +++ b/doc/classes/ButtonGroup.xml @@ -11,7 +11,7 @@ </tutorials> <methods> <method name="get_buttons"> - <return type="Array" /> + <return type="BaseButton[]" /> <description> Returns an [Array] of [Button]s who have this as their [ButtonGroup] (see [member BaseButton.button_group]). </description> diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml index 6b379e0509..65fdecc3c6 100644 --- a/doc/classes/Camera3D.xml +++ b/doc/classes/Camera3D.xml @@ -37,7 +37,7 @@ </description> </method> <method name="get_frustum" qualifiers="const"> - <return type="Array" /> + <return type="Plane[]" /> <description> Returns the camera's frustum planes in world space units as an array of [Plane]s in the following order: near, far, left, top, right, bottom. Not to be confused with [member frustum_offset]. </description> diff --git a/doc/classes/CameraServer.xml b/doc/classes/CameraServer.xml index d7a9888fac..d346fbde4f 100644 --- a/doc/classes/CameraServer.xml +++ b/doc/classes/CameraServer.xml @@ -19,7 +19,7 @@ </description> </method> <method name="feeds"> - <return type="Array" /> + <return type="CameraFeed[]" /> <description> Returns an array of [CameraFeed]s. </description> diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml index 90ce52fdb0..58a536406f 100644 --- a/doc/classes/ClassDB.xml +++ b/doc/classes/ClassDB.xml @@ -66,7 +66,7 @@ </description> </method> <method name="class_get_method_list" qualifiers="const"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="class" type="StringName" /> <param index="1" name="no_inheritance" type="bool" default="false" /> <description> @@ -83,7 +83,7 @@ </description> </method> <method name="class_get_property_list" qualifiers="const"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="class" type="StringName" /> <param index="1" name="no_inheritance" type="bool" default="false" /> <description> @@ -99,7 +99,7 @@ </description> </method> <method name="class_get_signal_list" qualifiers="const"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="class" type="StringName" /> <param index="1" name="no_inheritance" type="bool" default="false" /> <description> diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml index 6513b1ee13..ca482a39e0 100644 --- a/doc/classes/CodeEdit.xml +++ b/doc/classes/CodeEdit.xml @@ -18,7 +18,7 @@ </description> </method> <method name="_filter_code_completion_candidates" qualifiers="virtual const"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="candidates" type="Dictionary[]" /> <description> Override this method to define what items in [param candidates] should be displayed. @@ -159,13 +159,13 @@ </description> </method> <method name="get_bookmarked_lines" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <description> Gets all bookmarked lines. </description> </method> <method name="get_breakpointed_lines" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <description> Gets all breakpointed lines. </description> @@ -226,7 +226,7 @@ </description> </method> <method name="get_executing_lines" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <description> Gets all executing lines. </description> diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml index 832f47e2bb..67d5a667e8 100644 --- a/doc/classes/CollisionObject2D.xml +++ b/doc/classes/CollisionObject2D.xml @@ -55,7 +55,7 @@ </description> </method> <method name="get_shape_owners"> - <return type="Array" /> + <return type="PackedInt32Array" /> <description> Returns an [Array] of [code]owner_id[/code] identifiers. You can use these ids in other methods that take [code]owner_id[/code] as an argument. </description> diff --git a/doc/classes/CollisionObject3D.xml b/doc/classes/CollisionObject3D.xml index 04ccf3fc62..4d10a33032 100644 --- a/doc/classes/CollisionObject3D.xml +++ b/doc/classes/CollisionObject3D.xml @@ -49,7 +49,7 @@ </description> </method> <method name="get_shape_owners"> - <return type="Array" /> + <return type="PackedInt32Array" /> <description> Returns an [Array] of [code]owner_id[/code] identifiers. You can use these ids in other methods that take [code]owner_id[/code] as an argument. </description> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 30d34e4f4d..b7a9ae235e 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -196,7 +196,7 @@ </description> </method> <method name="_structured_text_parser" qualifiers="virtual const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="args" type="Array" /> <param index="1" name="text" type="String" /> <description> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 989d0cdb55..bcad75215a 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -105,7 +105,7 @@ </description> </method> <method name="get_display_cutouts" qualifiers="const"> - <return type="Array" /> + <return type="Rect2[]" /> <description> Returns an [Array] of [Rect2], each of which is the bounding rectangle for a display cutout or notch. These are non-functional areas on edge-to-edge screens used by cameras and sensors. Returns an empty array if the device does not have cutouts. See also [method get_display_safe_area]. [b]Note:[/b] Currently only implemented on Android. Other platforms will return an empty array even if they do have display cutouts or notches. @@ -857,7 +857,7 @@ </description> </method> <method name="tts_get_voices" qualifiers="const"> - <return type="Array" /> + <return type="Dictionary[]" /> <description> Returns an [Array] of voice information dictionaries. Each [Dictionary] contains two [String] entries: diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index 3555d2fd48..f7f1d456d0 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -115,7 +115,7 @@ </tutorials> <methods> <method name="_get_import_options" qualifiers="virtual const"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="path" type="String" /> <param index="1" name="preset_index" type="int" /> <description> diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index beed364974..49cd715f5e 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -101,7 +101,7 @@ </description> </method> <method name="get_open_scenes" qualifiers="const"> - <return type="Array" /> + <return type="PackedStringArray" /> <description> Returns an [Array] with the file paths of the currently opened scenes. </description> @@ -166,7 +166,7 @@ </description> </method> <method name="make_mesh_previews"> - <return type="Array" /> + <return type="Texture2D[]" /> <param index="0" name="meshes" type="Array" /> <param index="1" name="preview_size" type="int" /> <description> diff --git a/doc/classes/EditorSelection.xml b/doc/classes/EditorSelection.xml index 9c3e87ddb0..54029c2ccf 100644 --- a/doc/classes/EditorSelection.xml +++ b/doc/classes/EditorSelection.xml @@ -31,7 +31,7 @@ </description> </method> <method name="get_transformable_selected_nodes"> - <return type="Array" /> + <return type="Node[]" /> <description> Gets the list of selected nodes, optimized for transform operations (i.e. moving them, rotating, etc). This list avoids situations where a node is selected and also child/grandchild. </description> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 033f63c5ce..c7ff0a2d59 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -85,7 +85,7 @@ </description> </method> <method name="get_changed_settings" qualifiers="const"> - <return type="Array" /> + <return type="PackedStringArray" /> <description> Gets an array of the settings which have been changed since the last save. Note that internally [code]changed_settings[/code] is cleared after a successful save, so generally the most appropriate place to use this method is when processing [constant NOTIFICATION_EDITOR_SETTINGS_CHANGED] </description> diff --git a/doc/classes/EditorSyntaxHighlighter.xml b/doc/classes/EditorSyntaxHighlighter.xml index 15b730acb4..51f4474fe7 100644 --- a/doc/classes/EditorSyntaxHighlighter.xml +++ b/doc/classes/EditorSyntaxHighlighter.xml @@ -17,7 +17,7 @@ </description> </method> <method name="_get_supported_languages" qualifiers="virtual const"> - <return type="Array" /> + <return type="PackedStringArray" /> <description> Virtual method which can be overridden to return the supported language names. </description> diff --git a/doc/classes/EditorVCSInterface.xml b/doc/classes/EditorVCSInterface.xml index cc75861130..89ba79f7d9 100644 --- a/doc/classes/EditorVCSInterface.xml +++ b/doc/classes/EditorVCSInterface.xml @@ -17,7 +17,7 @@ </description> </method> <method name="get_file_diff"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="file_path" type="String" /> <description> Returns an [Array] of [Dictionary] objects containing the diff output from the VCS in use, if a VCS addon is initialized, else returns an empty [Array] object. The diff contents also consist of some contextual lines which provide context to the observed line change in the file. diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 2350a1f51b..301a3e55fb 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -34,7 +34,7 @@ </description> </method> <method name="get_copyright_info" qualifiers="const"> - <return type="Array" /> + <return type="Dictionary[]" /> <description> Returns an Array of copyright information Dictionaries. [code]name[/code] - String, component name diff --git a/doc/classes/FontFile.xml b/doc/classes/FontFile.xml index 0f229ea19a..b9b20dc75b 100644 --- a/doc/classes/FontFile.xml +++ b/doc/classes/FontFile.xml @@ -146,7 +146,7 @@ </description> </method> <method name="get_glyph_list" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <param index="0" name="cache_index" type="int" /> <param index="1" name="size" type="Vector2i" /> <description> @@ -199,7 +199,7 @@ </description> </method> <method name="get_kerning_list" qualifiers="const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="cache_index" type="int" /> <param index="1" name="size" type="int" /> <description> @@ -233,7 +233,7 @@ </description> </method> <method name="get_size_cache_list" qualifiers="const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="cache_index" type="int" /> <description> Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index ee3c87b8e6..7b0fd4b17b 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -188,7 +188,7 @@ </description> </method> <method name="font_get_glyph_list" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <param index="0" name="font_rid" type="RID" /> <param index="1" name="size" type="Vector2i" /> <description> @@ -268,7 +268,7 @@ </description> </method> <method name="font_get_kerning_list" qualifiers="const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="font_rid" type="RID" /> <param index="1" name="size" type="int" /> <description> @@ -349,7 +349,7 @@ </description> </method> <method name="font_get_size_cache_list" qualifiers="const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="font_rid" type="RID" /> <description> Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. @@ -993,7 +993,7 @@ </description> </method> <method name="parse_structured_text" qualifiers="const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="parser_type" type="int" enum="TextServer.StructuredTextParser" /> <param index="1" name="args" type="Array" /> <param index="2" name="text" type="String" /> diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index 219052d3d5..17df7e841c 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -180,7 +180,7 @@ </description> </method> <method name="font_get_glyph_list" qualifiers="virtual const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <param index="0" name="font_rid" type="RID" /> <param index="1" name="size" type="Vector2i" /> <description> @@ -258,7 +258,7 @@ </description> </method> <method name="font_get_kerning_list" qualifiers="virtual const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="font_rid" type="RID" /> <param index="1" name="size" type="int" /> <description> @@ -339,7 +339,7 @@ </description> </method> <method name="font_get_size_cache_list" qualifiers="virtual const"> - <return type="Array" /> + <return type="Vector2i[]" /> <param index="0" name="font_rid" type="RID" /> <description> Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index f86c4d82ef..1f40641b80 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -50,7 +50,7 @@ Error AudioDriverALSA::init_device() { // If there is a specified device check that it is really present if (device_name != "Default") { - Array list = get_device_list(); + PackedStringArray list = get_device_list(); if (list.find(device_name) == -1) { device_name = "Default"; new_device = "Default"; @@ -266,8 +266,8 @@ AudioDriver::SpeakerMode AudioDriverALSA::get_speaker_mode() const { return speaker_mode; } -Array AudioDriverALSA::get_device_list() { - Array list; +PackedStringArray AudioDriverALSA::get_device_list() { + PackedStringArray list; list.push_back("Default"); diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h index dbb40fa088..3f9d9b33fb 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -77,7 +77,7 @@ public: virtual void start(); virtual int get_mix_rate() const; virtual SpeakerMode get_speaker_mode() const; - virtual Array get_device_list(); + virtual PackedStringArray get_device_list(); virtual String get_device(); virtual void set_device(String device); virtual void lock(); diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index cc38c2352f..51fb1f99e0 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -493,8 +493,8 @@ Error AudioDriverCoreAudio::capture_stop() { #ifdef MACOS_ENABLED -Array AudioDriverCoreAudio::_get_device_list(bool capture) { - Array list; +PackedStringArray AudioDriverCoreAudio::_get_device_list(bool capture) { + PackedStringArray list; list.push_back("Default"); @@ -637,7 +637,7 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) { } } -Array AudioDriverCoreAudio::get_device_list() { +PackedStringArray AudioDriverCoreAudio::get_device_list() { return _get_device_list(); } @@ -659,7 +659,7 @@ void AudioDriverCoreAudio::capture_set_device(const String &p_name) { } } -Array AudioDriverCoreAudio::capture_get_device_list() { +PackedStringArray AudioDriverCoreAudio::capture_get_device_list() { return _get_device_list(true); } diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h index 7fac8a99ed..aac5077bb1 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.h +++ b/drivers/coreaudio/audio_driver_coreaudio.h @@ -59,7 +59,7 @@ class AudioDriverCoreAudio : public AudioDriver { Vector<int16_t> input_buf; #ifdef MACOS_ENABLED - Array _get_device_list(bool capture = false); + PackedStringArray _get_device_list(bool capture = false); void _set_device(const String &device, bool capture = false); static OSStatus input_device_address_cb(AudioObjectID inObjectID, @@ -107,11 +107,11 @@ public: void stop(); #ifdef MACOS_ENABLED - virtual Array get_device_list(); + virtual PackedStringArray get_device_list(); virtual String get_device(); virtual void set_device(String device); - virtual Array capture_get_device_list(); + virtual PackedStringArray capture_get_device_list(); virtual void capture_set_device(const String &p_name); virtual String capture_get_device(); #endif diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index a6c35b6837..b18d383119 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -178,7 +178,7 @@ Error AudioDriverPulseAudio::detect_channels(bool capture) { Error AudioDriverPulseAudio::init_device() { // If there is a specified device check that it is really present if (device_name != "Default") { - Array list = get_device_list(); + PackedStringArray list = get_device_list(); if (list.find(device_name) == -1) { device_name = "Default"; new_device = "Default"; @@ -599,7 +599,7 @@ void AudioDriverPulseAudio::pa_sinklist_cb(pa_context *c, const pa_sink_info *l, ad->pa_status++; } -Array AudioDriverPulseAudio::get_device_list() { +PackedStringArray AudioDriverPulseAudio::get_device_list() { pa_devices.clear(); pa_devices.push_back("Default"); @@ -681,7 +681,7 @@ void AudioDriverPulseAudio::finish() { Error AudioDriverPulseAudio::capture_init_device() { // If there is a specified device check that it is really present if (capture_device_name != "Default") { - Array list = capture_get_device_list(); + PackedStringArray list = capture_get_device_list(); if (list.find(capture_device_name) == -1) { capture_device_name = "Default"; capture_new_device = "Default"; @@ -785,7 +785,7 @@ void AudioDriverPulseAudio::pa_sourcelist_cb(pa_context *c, const pa_source_info ad->pa_status++; } -Array AudioDriverPulseAudio::capture_get_device_list() { +PackedStringArray AudioDriverPulseAudio::capture_get_device_list() { pa_rec_devices.clear(); pa_rec_devices.push_back("Default"); diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index af96489972..27c684578e 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -67,8 +67,8 @@ class AudioDriverPulseAudio : public AudioDriver { int channels = 0; int pa_ready = 0; int pa_status = 0; - Array pa_devices; - Array pa_rec_devices; + PackedStringArray pa_devices; + PackedStringArray pa_rec_devices; bool active = false; bool thread_exited = false; @@ -103,11 +103,11 @@ public: virtual int get_mix_rate() const; virtual SpeakerMode get_speaker_mode() const; - virtual Array get_device_list(); + virtual PackedStringArray get_device_list(); virtual String get_device(); virtual void set_device(String device); - virtual Array capture_get_device_list(); + virtual PackedStringArray capture_get_device_list(); virtual void capture_set_device(const String &p_name); virtual String capture_get_device(); diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 3a62850339..8f5e35b251 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -553,8 +553,8 @@ AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const { return get_speaker_mode_by_total_channels(channels); } -Array AudioDriverWASAPI::audio_device_get_list(bool p_capture) { - Array list; +PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_capture) { + PackedStringArray list; IMMDeviceCollection *devices = nullptr; IMMDeviceEnumerator *enumerator = nullptr; @@ -563,14 +563,14 @@ Array AudioDriverWASAPI::audio_device_get_list(bool p_capture) { CoInitialize(nullptr); HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator); - ERR_FAIL_COND_V(hr != S_OK, Array()); + ERR_FAIL_COND_V(hr != S_OK, PackedStringArray()); hr = enumerator->EnumAudioEndpoints(p_capture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices); - ERR_FAIL_COND_V(hr != S_OK, Array()); + ERR_FAIL_COND_V(hr != S_OK, PackedStringArray()); UINT count = 0; hr = devices->GetCount(&count); - ERR_FAIL_COND_V(hr != S_OK, Array()); + ERR_FAIL_COND_V(hr != S_OK, PackedStringArray()); for (ULONG i = 0; i < count; i++) { IMMDevice *device = nullptr; @@ -600,7 +600,7 @@ Array AudioDriverWASAPI::audio_device_get_list(bool p_capture) { return list; } -Array AudioDriverWASAPI::get_device_list() { +PackedStringArray AudioDriverWASAPI::get_device_list() { return audio_device_get_list(false); } @@ -950,7 +950,7 @@ void AudioDriverWASAPI::capture_set_device(const String &p_name) { unlock(); } -Array AudioDriverWASAPI::capture_get_device_list() { +PackedStringArray AudioDriverWASAPI::capture_get_device_list() { return audio_device_get_list(true); } diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index 9058077a1f..d71e2e914b 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -91,7 +91,7 @@ class AudioDriverWASAPI : public AudioDriver { Error audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool reinit); Error audio_device_finish(AudioDeviceWASAPI *p_device); - Array audio_device_get_list(bool p_capture); + PackedStringArray audio_device_get_list(bool p_capture); public: virtual const char *get_name() const { @@ -103,7 +103,7 @@ public: virtual int get_mix_rate() const; virtual float get_latency(); virtual SpeakerMode get_speaker_mode() const; - virtual Array get_device_list(); + virtual PackedStringArray get_device_list(); virtual String get_device(); virtual void set_device(String device); virtual void lock(); @@ -112,7 +112,7 @@ public: virtual Error capture_start(); virtual Error capture_stop(); - virtual Array capture_get_device_list(); + virtual PackedStringArray capture_get_device_list(); virtual void capture_set_device(const String &p_name); virtual String capture_get_device(); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 3df3a3b76a..d95fe64a09 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -38,6 +38,7 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "scene/animation/animation_player.h" +#include "scene/animation/tween.h" #include "scene/gui/separator.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" @@ -5970,6 +5971,89 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { #undef NEW_POS undo_redo->commit_action(); } break; + + case EDIT_EASE_SELECTION: { + ease_dialog->popup_centered(Size2(200, 100) * EDSCALE); + } break; + case EDIT_EASE_CONFIRM: { + undo_redo->create_action(TTR("Make Easing Keys")); + + Tween::TransitionType transition_type = static_cast<Tween::TransitionType>(transition_selection->get_selected_id()); + Tween::EaseType ease_type = static_cast<Tween::EaseType>(ease_selection->get_selected_id()); + float fps = ease_fps->get_value(); + double dur_step = 1.0 / fps; + + // Organize track and key. + HashMap<int, Vector<int>> keymap; + Vector<int> tracks; + for (const KeyValue<SelectedKey, KeyInfo> &E : selection) { + if (!tracks.has(E.key.track)) { + tracks.append(E.key.track); + } + } + for (int i = 0; i < tracks.size(); i++) { + switch (animation->track_get_type(tracks[i])) { + case Animation::TYPE_VALUE: + case Animation::TYPE_POSITION_3D: + case Animation::TYPE_ROTATION_3D: + case Animation::TYPE_SCALE_3D: + case Animation::TYPE_BLEND_SHAPE: { + Vector<int> keys; + for (const KeyValue<SelectedKey, KeyInfo> &E : selection) { + if (E.key.track == tracks[i]) { + keys.append(E.key.key); + } + } + keys.sort(); + keymap.insert(tracks[i], keys); + } break; + default: { + } break; + } + } + + // Make easing. + HashMap<int, Vector<int>>::Iterator E = keymap.begin(); + while (E) { + int track = E->key; + Vector<int> keys = E->value; + int len = keys.size() - 1; + + // Make insert queue. + Vector<Pair<double, Variant>> insert_queue; + for (int i = 0; i < len; i++) { + // Check neighboring keys. + if (keys[i] + 1 == keys[i + 1]) { + double from_t = animation->track_get_key_time(track, keys[i]); + double to_t = animation->track_get_key_time(track, keys[i + 1]); + Variant from_v = animation->track_get_key_value(track, keys[i]); + Variant to_v = animation->track_get_key_value(track, keys[i + 1]); + Variant delta_v; + Variant::sub(to_v, from_v, delta_v); + double duration = to_t - from_t; + double fixed_duration = duration - 0.01; // Prevent to overwrap keys... + for (double delta_t = dur_step; delta_t < fixed_duration; delta_t += dur_step) { + Pair<double, Variant> keydata; + keydata.first = from_t + delta_t; + keydata.second = Tween::interpolate_variant(from_v, delta_v, delta_t, duration, transition_type, ease_type); + insert_queue.append(keydata); + } + } + } + + // Do insertion. + for (int i = 0; i < insert_queue.size(); i++) { + undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, insert_queue[i].first, insert_queue[i].second); + undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", track, insert_queue[i].first); + } + + ++E; + } + + undo_redo->commit_action(); + + } break; + case EDIT_DUPLICATE_SELECTION: { if (bezier_edit->is_visible()) { bezier_edit->duplicate_selection(); @@ -6061,8 +6145,115 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } break; case EDIT_APPLY_RESET: { AnimationPlayerEditor::get_singleton()->get_player()->apply_reset(true); + } break; + case EDIT_BAKE_ANIMATION: { + bake_dialog->popup_centered(Size2(200, 100) * EDSCALE); } break; + case EDIT_BAKE_ANIMATION_CONFIRM: { + undo_redo->create_action(TTR("Bake Animation as Linear keys.")); + + int track_len = animation->get_track_count(); + bool b_trs = bake_trs->is_pressed(); + bool b_bs = bake_blendshape->is_pressed(); + bool b_v = bake_value->is_pressed(); + + double anim_len = animation->get_length() + CMP_EPSILON; // For end key. + float fps = bake_fps->get_value(); + double dur_step = 1.0 / fps; + + for (int i = 0; i < track_len; i++) { + bool do_bake = false; + Animation::TrackType type = animation->track_get_type(i); + do_bake |= b_trs && (type == Animation::TYPE_POSITION_3D || type == Animation::TYPE_ROTATION_3D || type == Animation::TYPE_SCALE_3D); + do_bake |= b_bs && type == Animation::TYPE_BLEND_SHAPE; + do_bake |= b_v && type == Animation::TYPE_VALUE; + if (do_bake && !animation->track_is_compressed(i)) { + if (animation->track_get_interpolation_type(i) == Animation::INTERPOLATION_NEAREST) { + continue; // Nearest interpolation cannot be baked. + } + + // Make insert queue. + Vector<Pair<double, Variant>> insert_queue; + + switch (type) { + case Animation::TYPE_POSITION_3D: { + for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) { + Pair<double, Variant> keydata; + keydata.first = delta_t; + Vector3 v; + animation->position_track_interpolate(i, delta_t, &v); + keydata.second = v; + insert_queue.append(keydata); + } + } break; + case Animation::TYPE_ROTATION_3D: { + for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) { + Pair<double, Variant> keydata; + keydata.first = delta_t; + Quaternion v; + animation->rotation_track_interpolate(i, delta_t, &v); + keydata.second = v; + insert_queue.append(keydata); + } + } break; + case Animation::TYPE_SCALE_3D: { + for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) { + Pair<double, Variant> keydata; + keydata.first = delta_t; + Vector3 v; + animation->scale_track_interpolate(i, delta_t, &v); + keydata.second = v; + insert_queue.append(keydata); + } + } break; + case Animation::TYPE_BLEND_SHAPE: { + for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) { + Pair<double, Variant> keydata; + keydata.first = delta_t; + float v; + animation->blend_shape_track_interpolate(i, delta_t, &v); + keydata.second = v; + insert_queue.append(keydata); + } + } break; + case Animation::TYPE_VALUE: { + for (double delta_t = 0.0; delta_t < anim_len; delta_t += dur_step) { + Pair<double, Variant> keydata; + keydata.first = delta_t; + keydata.second = animation->value_track_interpolate(i, delta_t); + insert_queue.append(keydata); + } + } break; + default: { + } break; + } + + // Cleanup keys. + int key_len = animation->track_get_key_count(i); + for (int j = key_len - 1; j >= 0; j--) { + undo_redo->add_do_method(animation.ptr(), "track_remove_key", i, j); + } + + // Insert keys. + undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", i, Animation::INTERPOLATION_LINEAR); + for (int j = insert_queue.size() - 1; j >= 0; j--) { + undo_redo->add_do_method(animation.ptr(), "track_insert_key", i, insert_queue[j].first, insert_queue[j].second); + undo_redo->add_undo_method(animation.ptr(), "track_remove_key", i, j); + } + + // Undo methods. + undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_type", i, animation->track_get_interpolation_type(i)); + for (int j = key_len - 1; j >= 0; j--) { + undo_redo->add_undo_method(animation.ptr(), "track_insert_key", i, animation->track_get_key_time(i, j), animation->track_get_key_value(i, j), animation->track_get_key_transition(i, j)); + } + } + } + + undo_redo->commit_action(); + + } break; + case EDIT_OPTIMIZE_ANIMATION: { optimize_dialog->popup_centered(Size2(250, 180) * EDSCALE); @@ -6470,6 +6661,8 @@ AnimationTrackEditor::AnimationTrackEditor() { edit->get_popup()->add_item(TTR("Scale Selection"), EDIT_SCALE_SELECTION); edit->get_popup()->add_item(TTR("Scale From Cursor"), EDIT_SCALE_FROM_CURSOR); edit->get_popup()->add_separator(); + edit->get_popup()->add_item(TTR("Make Easing Selection"), EDIT_EASE_SELECTION); + edit->get_popup()->add_separator(); edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_SELECTION); edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection_transposed", TTR("Duplicate Transposed"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_TRANSPOSED); edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/add_reset_value", TTR("Add RESET Value(s)"))); @@ -6482,6 +6675,7 @@ AnimationTrackEditor::AnimationTrackEditor() { edit->get_popup()->add_separator(); edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/apply_reset", TTR("Apply Reset")), EDIT_APPLY_RESET); edit->get_popup()->add_separator(); + edit->get_popup()->add_item(TTR("Bake Animation"), EDIT_BAKE_ANIMATION); edit->get_popup()->add_item(TTR("Optimize Animation"), EDIT_OPTIMIZE_ANIMATION); edit->get_popup()->add_item(TTR("Clean-Up Animation"), EDIT_CLEAN_UP_ANIMATION); @@ -6604,6 +6798,88 @@ AnimationTrackEditor::AnimationTrackEditor() { scale_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_SCALE_CONFIRM)); add_child(scale_dialog); + // + ease_dialog = memnew(ConfirmationDialog); + ease_dialog->set_title(TTR("Select Transition and Easing")); + ease_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_EASE_CONFIRM)); + add_child(ease_dialog); + GridContainer *ease_grid = memnew(GridContainer); + ease_grid->set_columns(2); + ease_dialog->add_child(ease_grid); + transition_selection = memnew(OptionButton); + transition_selection->add_item("Linear", Tween::TRANS_LINEAR); + transition_selection->add_item("Sine", Tween::TRANS_SINE); + transition_selection->add_item("Quint", Tween::TRANS_QUINT); + transition_selection->add_item("Quart", Tween::TRANS_QUART); + transition_selection->add_item("Quad", Tween::TRANS_QUAD); + transition_selection->add_item("Expo", Tween::TRANS_EXPO); + transition_selection->add_item("Elastic", Tween::TRANS_ELASTIC); + transition_selection->add_item("Cubic", Tween::TRANS_CUBIC); + transition_selection->add_item("Circ", Tween::TRANS_CIRC); + transition_selection->add_item("Bounce", Tween::TRANS_BOUNCE); + transition_selection->add_item("Back", Tween::TRANS_BACK); + transition_selection->select(Tween::TRANS_LINEAR); // Default + ease_selection = memnew(OptionButton); + ease_selection->add_item("In", Tween::EASE_IN); + ease_selection->add_item("Out", Tween::EASE_OUT); + ease_selection->add_item("InOut", Tween::EASE_IN_OUT); + ease_selection->add_item("OutIn", Tween::EASE_OUT_IN); + ease_selection->select(Tween::EASE_IN_OUT); // Default + ease_fps = memnew(SpinBox); + ease_fps->set_min(1); + ease_fps->set_max(999); + ease_fps->set_step(1); + ease_fps->set_value(30); // Default + Label *ease_label1 = memnew(Label); + Label *ease_label2 = memnew(Label); + Label *ease_label3 = memnew(Label); + ease_label1->set_text("Transition Type:"); + ease_label2->set_text("Ease Type:"); + ease_label3->set_text("FPS:"); + ease_grid->add_child(ease_label1); + ease_grid->add_child(transition_selection); + ease_grid->add_child(ease_label2); + ease_grid->add_child(ease_selection); + ease_grid->add_child(ease_label3); + ease_grid->add_child(ease_fps); + + // + bake_dialog = memnew(ConfirmationDialog); + bake_dialog->set_title(TTR("Anim. Baker")); + bake_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_BAKE_ANIMATION_CONFIRM)); + add_child(bake_dialog); + GridContainer *bake_grid = memnew(GridContainer); + bake_grid->set_columns(2); + bake_dialog->add_child(bake_grid); + bake_trs = memnew(CheckBox); + bake_trs->set_pressed(true); + bake_blendshape = memnew(CheckBox); + bake_blendshape->set_pressed(true); + bake_value = memnew(CheckBox); + bake_value->set_pressed(true); + bake_fps = memnew(SpinBox); + bake_fps->set_min(1); + bake_fps->set_max(999); + bake_fps->set_step(1); + bake_fps->set_value(30); // Default + Label *bake_label1 = memnew(Label); + Label *bake_label2 = memnew(Label); + Label *bake_label3 = memnew(Label); + Label *bake_label4 = memnew(Label); + bake_label1->set_text("Pos/Rot/Scl3D Track:"); + bake_label2->set_text("Blendshape Track:"); + bake_label3->set_text("Value Track:"); + bake_label4->set_text("FPS:"); + bake_grid->add_child(bake_label1); + bake_grid->add_child(bake_trs); + bake_grid->add_child(bake_label2); + bake_grid->add_child(bake_blendshape); + bake_grid->add_child(bake_label3); + bake_grid->add_child(bake_value); + bake_grid->add_child(bake_label4); + bake_grid->add_child(bake_fps); + + // track_copy_dialog = memnew(ConfirmationDialog); add_child(track_copy_dialog); track_copy_dialog->set_title(TTR("Select Tracks to Copy")); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 806d3ffb14..5ebf25899f 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -32,6 +32,7 @@ #define ANIMATION_TRACK_EDITOR_H #include "editor/editor_data.h" +#include "editor/editor_properties.h" #include "editor/editor_spin_slider.h" #include "editor/property_selector.h" @@ -451,6 +452,12 @@ class AnimationTrackEditor : public VBoxContainer { ////////////// edit menu stuff + ConfirmationDialog *bake_dialog = nullptr; + CheckBox *bake_trs = nullptr; + CheckBox *bake_blendshape = nullptr; + CheckBox *bake_value = nullptr; + SpinBox *bake_fps = nullptr; + ConfirmationDialog *optimize_dialog = nullptr; SpinBox *optimize_velocity_error = nullptr; SpinBox *optimize_angular_error = nullptr; @@ -464,6 +471,11 @@ class AnimationTrackEditor : public VBoxContainer { ConfirmationDialog *scale_dialog = nullptr; SpinBox *scale = nullptr; + ConfirmationDialog *ease_dialog = nullptr; + OptionButton *transition_selection = nullptr; + OptionButton *ease_selection = nullptr; + SpinBox *ease_fps = nullptr; + void _select_all_tracks_for_copy(); void _edit_menu_about_to_popup(); @@ -521,6 +533,8 @@ public: EDIT_SCALE_SELECTION, EDIT_SCALE_FROM_CURSOR, EDIT_SCALE_CONFIRM, + EDIT_EASE_SELECTION, + EDIT_EASE_CONFIRM, EDIT_DUPLICATE_SELECTION, EDIT_DUPLICATE_TRANSPOSED, EDIT_ADD_RESET_KEY, @@ -529,6 +543,8 @@ public: EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY, // Next step without updating animation. EDIT_GOTO_PREV_STEP, EDIT_APPLY_RESET, + EDIT_BAKE_ANIMATION, + EDIT_BAKE_ANIMATION_CONFIRM, EDIT_OPTIMIZE_ANIMATION, EDIT_OPTIMIZE_ANIMATION_CONFIRM, EDIT_CLEAN_UP_ANIMATION, diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 9e72c8ec10..bdd30dc653 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1789,7 +1789,7 @@ void CodeTextEditor::toggle_bookmark() { } void CodeTextEditor::goto_next_bookmark() { - Array bmarks = text_editor->get_bookmarked_lines(); + PackedInt32Array bmarks = text_editor->get_bookmarked_lines(); if (bmarks.size() <= 0) { return; } @@ -1813,7 +1813,7 @@ void CodeTextEditor::goto_next_bookmark() { } void CodeTextEditor::goto_prev_bookmark() { - Array bmarks = text_editor->get_bookmarked_lines(); + PackedInt32Array bmarks = text_editor->get_bookmarked_lines(); if (bmarks.size() <= 0) { return; } diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 64bdac1e77..231ae198d2 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -1143,8 +1143,8 @@ void EditorSelection::_emit_change() { emitted = false; } -Array EditorSelection::_get_transformable_selected_nodes() { - Array ret; +TypedArray<Node> EditorSelection::_get_transformable_selected_nodes() { + TypedArray<Node> ret; for (const Node *E : selected_node_list) { ret.push_back(E); diff --git a/editor/editor_data.h b/editor/editor_data.h index 655a62a9ae..1da188c546 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -271,7 +271,7 @@ class EditorSelection : public Object { List<Node *> selected_node_list; void _update_node_list(); - Array _get_transformable_selected_nodes(); + TypedArray<Node> _get_transformable_selected_nodes(); void _emit_change(); protected: diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 2e64e46519..b0bd500ef8 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -48,7 +48,7 @@ #include "scene/gui/popup_menu.h" #include "servers/rendering_server.h" -Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_size) { +TypedArray<Texture2D> EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_size) { Vector<Ref<Mesh>> meshes; for (int i = 0; i < p_meshes.size(); i++) { @@ -56,7 +56,7 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_ } Vector<Ref<Texture2D>> textures = make_mesh_previews(meshes, nullptr, p_preview_size); - Array ret; + TypedArray<Texture2D> ret; for (int i = 0; i < textures.size(); i++) { ret.push_back(textures[i]); } @@ -216,8 +216,8 @@ Node *EditorInterface::get_edited_scene_root() { return EditorNode::get_singleton()->get_edited_scene(); } -Array EditorInterface::get_open_scenes() const { - Array ret; +PackedStringArray EditorInterface::get_open_scenes() const { + PackedStringArray ret; Vector<EditorData::EditedScene> scenes = EditorNode::get_editor_data().get_edited_scenes(); int scns_amount = scenes.size(); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 201c7790a3..8357f0960a 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -67,7 +67,7 @@ protected: static void _bind_methods(); static EditorInterface *singleton; - Array _make_mesh_previews(const Array &p_meshes, int p_preview_size); + TypedArray<Texture2D> _make_mesh_previews(const Array &p_meshes, int p_preview_size); public: static EditorInterface *get_singleton() { return singleton; } @@ -87,7 +87,7 @@ public: String get_playing_scene() const; Node *get_edited_scene_root(); - Array get_open_scenes() const; + PackedStringArray get_open_scenes() const; ScriptEditor *get_script_editor(); EditorCommandPalette *get_command_palette() const; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 36e64cbd7a..4437b1b166 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -963,8 +963,8 @@ void EditorSettings::save() { } } -Array EditorSettings::get_changed_settings() const { - Array arr; +PackedStringArray EditorSettings::get_changed_settings() const { + PackedStringArray arr; for (const String &setting : changed_settings) { arr.push_back(setting); } diff --git a/editor/editor_settings.h b/editor/editor_settings.h index f921171c57..09bc4caa22 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -141,7 +141,7 @@ public: } } void add_property_hint(const PropertyInfo &p_hint); - Array get_changed_settings() const; + PackedStringArray get_changed_settings() const; bool check_changed_settings_in_group(const String &p_setting_prefix) const; void mark_setting_changed(const String &p_setting); diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp index 3f2012cc16..cb188f9c3e 100644 --- a/editor/editor_vcs_interface.cpp +++ b/editor/editor_vcs_interface.cpp @@ -82,8 +82,8 @@ void EditorVCSInterface::_unstage_file(String p_file_path) { void EditorVCSInterface::_commit(String p_msg) { } -Array EditorVCSInterface::_get_file_diff(String p_file_path) { - return Array(); +TypedArray<Dictionary> EditorVCSInterface::_get_file_diff(String p_file_path) { + return TypedArray<Dictionary>(); } bool EditorVCSInterface::_shut_down() { @@ -133,11 +133,11 @@ void EditorVCSInterface::commit(String p_msg) { } } -Array EditorVCSInterface::get_file_diff(String p_file_path) { +TypedArray<Dictionary> EditorVCSInterface::get_file_diff(String p_file_path) { if (is_addon_ready()) { return call("_get_file_diff", p_file_path); } - return Array(); + return TypedArray<Dictionary>(); } bool EditorVCSInterface::shut_down() { diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index 6a6fca7eba..d6d7ffa0e9 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -52,7 +52,7 @@ protected: virtual void _stage_file(String p_file_path); virtual void _unstage_file(String p_file_path); virtual void _commit(String p_msg); - virtual Array _get_file_diff(String p_file_path); + virtual TypedArray<Dictionary> _get_file_diff(String p_file_path); virtual bool _shut_down(); virtual String _get_project_name(); virtual String _get_vcs_name(); @@ -76,7 +76,7 @@ public: void stage_file(String p_file_path); void unstage_file(String p_file_path); void commit(String p_msg); - Array get_file_diff(String p_file_path); + TypedArray<Dictionary> get_file_diff(String p_file_path); bool shut_down(); String get_project_name(); String get_vcs_name(); diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index e822b4963a..3305f241c0 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -115,7 +115,7 @@ void EditorImportPlugin::get_import_options(const String &p_path, List<ResourceI Array needed; needed.push_back("name"); needed.push_back("default_value"); - Array options; + TypedArray<Dictionary> options; if (GDVIRTUAL_CALL(_get_import_options, p_path, p_preset, options)) { for (int i = 0; i < options.size(); i++) { Dictionary d = options[i]; diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index 4548513b6f..e9749c240f 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -32,6 +32,7 @@ #define EDITOR_IMPORT_PLUGIN_H #include "core/io/resource_importer.h" +#include "core/variant/typed_array.h" class EditorImportPlugin : public ResourceImporter { GDCLASS(EditorImportPlugin, ResourceImporter); @@ -44,7 +45,7 @@ protected: GDVIRTUAL0RC(int, _get_preset_count) GDVIRTUAL1RC(String, _get_preset_name, int) GDVIRTUAL0RC(Vector<String>, _get_recognized_extensions) - GDVIRTUAL2RC(Array, _get_import_options, String, int) + GDVIRTUAL2RC(TypedArray<Dictionary>, _get_import_options, String, int) GDVIRTUAL0RC(String, _get_save_extension) GDVIRTUAL0RC(String, _get_resource_type) GDVIRTUAL0RC(float, _get_priority) diff --git a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp index 2fa602846c..685cb16eb1 100644 --- a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp +++ b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp @@ -41,14 +41,13 @@ void PostImportPluginSkeletonRestFixer::get_internal_import_options(InternalImpo r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/apply_node_transforms"), true)); r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/normalize_position_tracks"), true)); r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/overwrite_axis"), true)); - r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/fix_silhouette/enable"), false)); - r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "retarget/rest_fixer/fix_silhouette/threshold"), 15)); - // TODO: PostImportPlugin need to be implemented such as validate_option(PropertyInfo &property, const Dictionary &p_options). // get_internal_option_visibility() is not sufficient because it can only retrieve options implemented in the core and can only read option values. // r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "retarget/rest_fixer/filter", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::STRING_NAME, PROPERTY_HINT_ENUM, "Hips,Spine,Chest")), Array())); r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "retarget/rest_fixer/fix_silhouette/filter", PROPERTY_HINT_ARRAY_TYPE, "StringName"), Array())); + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "retarget/rest_fixer/fix_silhouette/threshold"), 15)); + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "retarget/rest_fixer/fix_silhouette/base_height_adjustment", PROPERTY_HINT_RANGE, "-1,1,0.01"), 0.0)); } } @@ -192,53 +191,6 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory is_rest_changed = true; } - // Set motion scale to Skeleton if normalize position tracks. - if (bool(p_options["retarget/rest_fixer/normalize_position_tracks"])) { - int src_bone_idx = src_skeleton->find_bone(profile->get_scale_base_bone()); - if (src_bone_idx >= 0) { - real_t motion_scale = abs(src_skeleton->get_bone_global_rest(src_bone_idx).origin.y); - if (motion_scale > 0) { - src_skeleton->set_motion_scale(motion_scale); - } - } - - TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); - while (nodes.size()) { - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); - List<StringName> anims; - ap->get_animation_list(&anims); - for (const StringName &name : anims) { - Ref<Animation> anim = ap->get_animation(name); - int track_len = anim->get_track_count(); - for (int i = 0; i < track_len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_POSITION_3D) { - continue; - } - - if (anim->track_is_compressed(i)) { - continue; // Shouldn't occur in internal_process(). - } - - String track_path = String(anim->track_get_path(i).get_concatenated_names()); - Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); - if (node) { - Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); - if (track_skeleton) { - if (track_skeleton && track_skeleton == src_skeleton) { - real_t mlt = 1 / src_skeleton->get_motion_scale(); - int key_len = anim->track_get_key_count(i); - for (int j = 0; j < key_len; j++) { - Vector3 pos = static_cast<Vector3>(anim->track_get_key_value(i, j)); - anim->track_set_key_value(i, j, pos * mlt); - } - } - } - } - } - } - } - } - // Complement Rotation track for compatibility between different rests. { TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); @@ -406,6 +358,52 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory } } + // Adjust scale base bone height. + float base_adjustment = float(p_options["retarget/rest_fixer/fix_silhouette/base_height_adjustment"]); + if (!Math::is_zero_approx(base_adjustment)) { + StringName scale_base_bone_name = profile->get_scale_base_bone(); + int src_bone_idx = src_skeleton->find_bone(scale_base_bone_name); + Transform3D src_rest = src_skeleton->get_bone_rest(src_bone_idx); + src_skeleton->set_bone_rest(src_bone_idx, Transform3D(src_rest.basis, Vector3(src_rest.origin.x, src_rest.origin.y + base_adjustment, src_rest.origin.z))); + + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int track_len = anim->get_track_count(); + for (int i = 0; i < track_len; i++) { + if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_POSITION_3D) { + continue; + } + + if (anim->track_is_compressed(i)) { + continue; // Shouldn't occur in internal_process(). + } + + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (node) { + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton && track_skeleton == src_skeleton) { + StringName bn = anim->track_get_path(i).get_concatenated_subnames(); + if (bn == scale_base_bone_name) { + int key_len = anim->track_get_key_count(i); + for (int j = 0; j < key_len; j++) { + Vector3 pos = static_cast<Vector3>(anim->track_get_key_value(i, j)); + pos.y += base_adjustment; + anim->track_set_key_value(i, j, pos); + } + } + } + } + } + } + } + } + // For skin modification in overwrite rest. for (int i = 0; i < src_skeleton->get_bone_count(); i++) { silhouette_diff_w[i] = old_skeleton_global_rest[i] * src_skeleton->get_bone_global_rest(i).inverse(); @@ -414,6 +412,51 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory is_rest_changed = true; } + // Set motion scale to Skeleton if normalize position tracks. + if (bool(p_options["retarget/rest_fixer/normalize_position_tracks"])) { + int src_bone_idx = src_skeleton->find_bone(profile->get_scale_base_bone()); + if (src_bone_idx >= 0) { + real_t motion_scale = abs(src_skeleton->get_bone_global_rest(src_bone_idx).origin.y); + if (motion_scale > 0) { + src_skeleton->set_motion_scale(motion_scale); + } + } + + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int track_len = anim->get_track_count(); + for (int i = 0; i < track_len; i++) { + if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_POSITION_3D) { + continue; + } + + if (anim->track_is_compressed(i)) { + continue; // Shouldn't occur in internal_process(). + } + + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (node) { + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton && track_skeleton == src_skeleton) { + real_t mlt = 1 / src_skeleton->get_motion_scale(); + int key_len = anim->track_get_key_count(i); + for (int j = 0; j < key_len; j++) { + Vector3 pos = static_cast<Vector3>(anim->track_get_key_value(i, j)); + anim->track_set_key_value(i, j, pos * mlt); + } + } + } + } + } + } + } + // Overwrite axis. if (bool(p_options["retarget/rest_fixer/overwrite_axis"])) { LocalVector<Transform3D> old_skeleton_rest; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index de13c77e1a..e8c3cb8d60 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -66,12 +66,12 @@ String EditorSyntaxHighlighter::_get_name() const { return "Unnamed"; } -Array EditorSyntaxHighlighter::_get_supported_languages() const { - Array ret; +PackedStringArray EditorSyntaxHighlighter::_get_supported_languages() const { + PackedStringArray ret; if (GDVIRTUAL_CALL(_get_supported_languages, ret)) { return ret; } - return Array(); + return PackedStringArray(); } Ref<EditorSyntaxHighlighter> EditorSyntaxHighlighter::_create() const { @@ -1732,7 +1732,7 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) { continue; } - Array bpoints = se->get_breakpoints(); + PackedInt32Array bpoints = se->get_breakpoints(); for (int j = 0; j < bpoints.size(); j++) { p_breakpoints->push_back(base + ":" + itos((int)bpoints[j] + 1)); } @@ -2380,8 +2380,8 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, se->add_syntax_highlighter(highlighter); if (script != nullptr && !highlighter_set) { - Array languages = highlighter->_get_supported_languages(); - if (languages.find(script->get_language()->get_name()) > -1) { + PackedStringArray languages = highlighter->_get_supported_languages(); + if (languages.has(script->get_language()->get_name())) { se->set_syntax_highlighter(highlighter); highlighter_set = true; } diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 9f088aac49..5bd93e6e42 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -59,11 +59,11 @@ protected: static void _bind_methods(); GDVIRTUAL0RC(String, _get_name) - GDVIRTUAL0RC(Array, _get_supported_languages) + GDVIRTUAL0RC(PackedStringArray, _get_supported_languages) public: virtual String _get_name() const; - virtual Array _get_supported_languages() const; + virtual PackedStringArray _get_supported_languages() const; void _set_edited_resource(const Ref<Resource> &p_res) { edited_resourse = p_res; } Ref<RefCounted> _get_edited_resource() { return edited_resourse; } @@ -156,7 +156,7 @@ public: virtual void ensure_focus() = 0; virtual void tag_saved_version() = 0; virtual void reload(bool p_soft) {} - virtual Array get_breakpoints() = 0; + virtual PackedInt32Array get_breakpoints() = 0; virtual void set_breakpoint(int p_line, bool p_enabled) = 0; virtual void clear_breakpoints() = 0; virtual void add_callback(const String &p_function, PackedStringArray p_args) = 0; diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 5d5f452390..5e7db17edf 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -596,7 +596,7 @@ void ScriptTextEditor::_update_bookmark_list() { bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); - Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines(); + PackedInt32Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines(); if (bookmark_list.size() == 0) { return; } @@ -751,7 +751,7 @@ void ScriptTextEditor::_update_breakpoint_list() { breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT); breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT); - Array breakpoint_list = code_editor->get_text_editor()->get_breakpointed_lines(); + PackedInt32Array breakpoint_list = code_editor->get_text_editor()->get_breakpointed_lines(); if (breakpoint_list.size() == 0) { return; } @@ -1264,7 +1264,7 @@ void ScriptTextEditor::_edit_option(int p_op) { EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak); } break; case DEBUG_REMOVE_ALL_BREAKPOINTS: { - Array bpoints = tx->get_breakpointed_lines(); + PackedInt32Array bpoints = tx->get_breakpointed_lines(); for (int i = 0; i < bpoints.size(); i++) { int line = bpoints[i]; @@ -1274,7 +1274,7 @@ void ScriptTextEditor::_edit_option(int p_op) { } } break; case DEBUG_GOTO_NEXT_BREAKPOINT: { - Array bpoints = tx->get_breakpointed_lines(); + PackedInt32Array bpoints = tx->get_breakpointed_lines(); if (bpoints.size() <= 0) { return; } @@ -1300,7 +1300,7 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case DEBUG_GOTO_PREV_BREAKPOINT: { - Array bpoints = tx->get_breakpointed_lines(); + PackedInt32Array bpoints = tx->get_breakpointed_lines(); if (bpoints.size() <= 0) { return; } @@ -1441,7 +1441,7 @@ void ScriptTextEditor::reload(bool p_soft) { scr->get_language()->reload_tool_script(scr, soft); } -Array ScriptTextEditor::get_breakpoints() { +PackedInt32Array ScriptTextEditor::get_breakpoints() { return code_editor->get_text_editor()->get_breakpointed_lines(); } diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index fc87c84a2c..8d2fb98721 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -229,7 +229,7 @@ public: virtual void clear_executing_line() override; virtual void reload(bool p_soft) override; - virtual Array get_breakpoints() override; + virtual PackedInt32Array get_breakpoints() override; virtual void set_breakpoint(int p_line, bool p_enabled) override; virtual void clear_breakpoints() override; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index d70c50f72a..4641df3dca 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -994,7 +994,7 @@ void ShaderEditor::_update_bookmark_list() { bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); - Array bookmark_list = shader_editor->get_text_editor()->get_bookmarked_lines(); + PackedInt32Array bookmark_list = shader_editor->get_text_editor()->get_bookmarked_lines(); if (bookmark_list.size() == 0) { return; } diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 196d87da36..0900415b04 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -128,8 +128,8 @@ Control *TextEditor::get_base_editor() const { return code_editor->get_text_editor(); } -Array TextEditor::get_breakpoints() { - return Array(); +PackedInt32Array TextEditor::get_breakpoints() { + return PackedInt32Array(); } void TextEditor::reload_text() { @@ -165,7 +165,7 @@ void TextEditor::_update_bookmark_list() { bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); - Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines(); + PackedInt32Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines(); if (bookmark_list.size() == 0) { return; } diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index 4f0121da52..15f7c45653 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -118,7 +118,7 @@ public: virtual Variant get_edit_state() override; virtual void set_edit_state(const Variant &p_state) override; virtual Vector<String> get_functions() override; - virtual Array get_breakpoints() override; + virtual PackedInt32Array get_breakpoints() override; virtual void set_breakpoint(int p_line, bool p_enabled) override{}; virtual void clear_breakpoints() override{}; virtual void goto_line(int p_line, bool p_with_error = false) override; diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index cf55465417..6db499f2c7 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -242,7 +242,7 @@ void VersionControlEditorPlugin::_view_file_diff() { } void VersionControlEditorPlugin::_display_file_diff(String p_file_path) { - Array diff_content = EditorVCSInterface::get_singleton()->get_file_diff(p_file_path); + TypedArray<Dictionary> diff_content = EditorVCSInterface::get_singleton()->get_file_diff(p_file_path); diff_file_name->set_text(p_file_path); diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index e7299b4d3a..681aa45c8f 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -526,8 +526,8 @@ String GDScriptSyntaxHighlighter::_get_name() const { return "GDScript"; } -Array GDScriptSyntaxHighlighter::_get_supported_languages() const { - Array languages; +PackedStringArray GDScriptSyntaxHighlighter::_get_supported_languages() const { + PackedStringArray languages; languages.push_back("GDScript"); return languages; } diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h index 7987582f07..f434d03a31 100644 --- a/modules/gdscript/editor/gdscript_highlighter.h +++ b/modules/gdscript/editor/gdscript_highlighter.h @@ -88,7 +88,7 @@ public: virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override; virtual String _get_name() const override; - virtual Array _get_supported_languages() const override; + virtual PackedStringArray _get_supported_languages() const override; virtual Ref<EditorSyntaxHighlighter> _create() const override; }; diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index 1e1204aa57..cc1ca9131d 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -66,17 +66,24 @@ static void _editor_init() { bool blend_enabled = GLOBAL_GET("filesystem/import/blender/enabled"); // Defined here because EditorSettings doesn't exist in `register_gltf_types` yet. - EDITOR_DEF_RST("filesystem/import/blender/blender3_path", ""); + String blender3_path = EDITOR_DEF_RST("filesystem/import/blender/blender3_path", ""); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "filesystem/import/blender/blender3_path", PROPERTY_HINT_GLOBAL_DIR)); if (blend_enabled) { - Ref<EditorSceneFormatImporterBlend> importer; - importer.instantiate(); - ResourceImporterScene::add_importer(importer); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (blender3_path.is_empty()) { + WARN_PRINT("Blend file import is enabled in the project settings, but no Blender path is configured in the editor settings. Blend files will not be imported."); + } else if (!da->file_exists(blender3_path)) { + WARN_PRINT("Blend file import is enabled, but the Blender path doesn't point to an accessible file. Blend files will not be imported."); + } else { + Ref<EditorSceneFormatImporterBlend> importer; + importer.instantiate(); + ResourceImporterScene::add_importer(importer); - Ref<EditorFileSystemImportFormatSupportQueryBlend> blend_import_query; - blend_import_query.instantiate(); - EditorFileSystem::get_singleton()->add_import_format_support_query(blend_import_query); + Ref<EditorFileSystemImportFormatSupportQueryBlend> blend_import_query; + blend_import_query.instantiate(); + EditorFileSystem::get_singleton()->add_import_format_support_query(blend_import_query); + } } // FBX to glTF importer. @@ -89,9 +96,9 @@ static void _editor_init() { if (fbx_enabled) { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); if (fbx2gltf_path.is_empty()) { - WARN_PRINT("FBX file import is enabled, but no FBX2glTF path is configured. FBX files will not be imported."); + WARN_PRINT("FBX file import is enabled in the project settings, but no FBX2glTF path is configured in the editor settings. FBX files will not be imported."); } else if (!da->file_exists(fbx2gltf_path)) { - WARN_PRINT("FBX file import is enabled, but the FBX2glTF path doesn't point to a valid FBX2glTF executable. FBX files will not be imported."); + WARN_PRINT("FBX file import is enabled, but the FBX2glTF path doesn't point to an accessible file. FBX files will not be imported."); } else { Ref<EditorSceneFormatImporterFBX> importer; importer.instantiate(); diff --git a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs index 188bbb775c..069908c426 100644 --- a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs @@ -26,7 +26,7 @@ public partial class _CLASS_ : _BASE_ // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); - Vector3 direction = Transform.basis.Xform(new Vector3(inputDir.x, 0, inputDir.y)).Normalized(); + Vector3 direction = (Transform.basis * new Vector3(inputDir.x, 0, inputDir.y)).Normalized(); if (direction != Vector3.Zero) { velocity.x = direction.x * Speed; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index 646681a9b1..4cb9bf5758 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -618,41 +618,6 @@ namespace Godot return tr; } - /// <summary> - /// Returns a vector transformed (multiplied) by the basis matrix. - /// </summary> - /// <seealso cref="XformInv(Vector3)"/> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public Vector3 Xform(Vector3 v) - { - return new Vector3 - ( - Row0.Dot(v), - Row1.Dot(v), - Row2.Dot(v) - ); - } - - /// <summary> - /// Returns a vector transformed (multiplied) by the transposed basis matrix. - /// - /// Note: This results in a multiplication by the inverse of the - /// basis matrix only if it represents a rotation-reflection. - /// </summary> - /// <seealso cref="Xform(Vector3)"/> - /// <param name="v">A vector to inversely transform.</param> - /// <returns>The inversely transformed vector.</returns> - public Vector3 XformInv(Vector3 v) - { - return new Vector3 - ( - Row0[0] * v.x + Row1[0] * v.y + Row2[0] * v.z, - Row0[1] * v.x + Row1[1] * v.y + Row2[1] * v.z, - Row0[2] * v.x + Row1[2] * v.y + Row2[2] * v.z - ); - } - private static readonly Basis[] _orthoBases = { new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f), new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f), @@ -857,6 +822,41 @@ namespace Godot } /// <summary> + /// Returns a Vector3 transformed (multiplied) by the basis matrix. + /// </summary> + /// <param name="basis">The basis matrix transformation to apply.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The transformed Vector3.</returns> + public static Vector3 operator *(Basis basis, Vector3 vector) + { + return new Vector3 + ( + basis.Row0.Dot(vector), + basis.Row1.Dot(vector), + basis.Row2.Dot(vector) + ); + } + + /// <summary> + /// Returns a Vector3 transformed (multiplied) by the transposed basis matrix. + /// + /// Note: This results in a multiplication by the inverse of the + /// basis matrix only if it represents a rotation-reflection. + /// </summary> + /// <param name="vector">A Vector3 to inversely transform.</param> + /// <param name="basis">The basis matrix transformation to apply.</param> + /// <returns>The inversely transformed vector.</returns> + public static Vector3 operator *(Vector3 vector, Basis basis) + { + return new Vector3 + ( + basis.Row0[0] * vector.x + basis.Row1[0] * vector.y + basis.Row2[0] * vector.z, + basis.Row0[1] * vector.x + basis.Row1[1] * vector.y + basis.Row2[1] * vector.z, + basis.Row0[2] * vector.x + basis.Row1[2] * vector.y + basis.Row2[2] * vector.z + ); + } + + /// <summary> /// Returns <see langword="true"/> if the basis matrices are exactly /// equal. Note: Due to floating-point precision errors, consider using /// <see cref="IsEqualApprox"/> instead, which is more reliable. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs index df16fe5718..3dcf433c4a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs @@ -355,7 +355,7 @@ namespace Godot public int GetPixelsPerMeter(int forPixelWidth) { - Vector3 result = Xform(new Vector3(1, 0, -1)); + Vector3 result = this * new Vector3(1, 0, -1); return (int)((result.x * (real_t)0.5 + (real_t)0.5) * forPixelWidth); } @@ -588,22 +588,54 @@ namespace Godot } /// <summary> - /// Returns a vector transformed (multiplied) by this projection. + /// Returns a Vector4 transformed (multiplied) by the projection. /// </summary> /// <param name="proj">The projection to apply.</param> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public static Vector4 operator *(Projection proj, Vector4 v) + /// <param name="vector">A Vector4 to transform.</param> + /// <returns>The transformed Vector4.</returns> + public static Vector4 operator *(Projection proj, Vector4 vector) { return new Vector4( - proj.x.x * v.x + proj.y.x * v.y + proj.z.x * v.z + proj.w.x * v.w, - proj.x.y * v.x + proj.y.y * v.y + proj.z.y * v.z + proj.w.y * v.w, - proj.x.z * v.x + proj.y.z * v.y + proj.z.z * v.z + proj.w.z * v.w, - proj.x.w * v.x + proj.y.w * v.y + proj.z.w * v.z + proj.w.w * v.w + proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x * vector.w, + proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y * vector.w, + proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z * vector.w, + proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w * vector.w ); } /// <summary> + /// Returns a Vector4 transformed (multiplied) by the inverse projection. + /// </summary> + /// <param name="proj">The projection to apply.</param> + /// <param name="vector">A Vector4 to transform.</param> + /// <returns>The inversely transformed Vector4.</returns> + public static Vector4 operator *(Vector4 vector, Projection proj) + { + return new Vector4( + proj.x.x * vector.x + proj.x.y * vector.y + proj.x.z * vector.z + proj.x.w * vector.w, + proj.y.x * vector.x + proj.y.y * vector.y + proj.y.z * vector.z + proj.y.w * vector.w, + proj.z.x * vector.x + proj.z.y * vector.y + proj.z.z * vector.z + proj.z.w * vector.w, + proj.w.x * vector.x + proj.w.y * vector.y + proj.w.z * vector.z + proj.w.w * vector.w + ); + } + + /// <summary> + /// Returns a Vector3 transformed (multiplied) by the projection. + /// </summary> + /// <param name="proj">The projection to apply.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The transformed Vector3.</returns> + public static Vector3 operator *(Projection proj, Vector3 vector) + { + Vector3 ret = new Vector3( + proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x, + proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y, + proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z + ); + return ret / (proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w); + } + + /// <summary> /// Returns <see langword="true"/> if the projections are exactly equal. /// </summary> /// <param name="left">The left projection.</param> @@ -714,21 +746,6 @@ namespace Godot } } - /// <summary> - /// Returns a vector transformed (multiplied) by this projection. - /// </summary> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - private Vector3 Xform(Vector3 v) - { - Vector3 ret = new Vector3( - x.x * v.x + y.x * v.y + z.x * v.z + w.x, - x.y * v.x + y.y * v.y + z.y * v.z + w.y, - x.z * v.x + y.z * v.y + z.z * v.z + w.z - ); - return ret / (x.w * v.x + y.w * v.y + z.w * v.z + w.w); - } - // Constants private static readonly Projection _zero = new Projection( new Vector4(0, 0, 0, 0), diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index 90e4e3b41e..4260ff22e7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -313,24 +313,6 @@ namespace Godot ); } - /// <summary> - /// Returns a vector transformed (multiplied) by this quaternion. - /// </summary> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public Vector3 Xform(Vector3 v) - { -#if DEBUG - if (!IsNormalized()) - { - throw new InvalidOperationException("Quaternion is not normalized"); - } -#endif - var u = new Vector3(x, y, z); - Vector3 uv = u.Cross(v); - return v + (((uv * w) + u.Cross(uv)) * 2); - } - // Constants private static readonly Quaternion _identity = new Quaternion(0, 0, 0, 1); @@ -461,6 +443,36 @@ namespace Godot } /// <summary> + /// Returns a Vector3 rotated (multiplied) by the quaternion. + /// </summary> + /// <param name="quaternion">The quaternion to rotate by.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The rotated Vector3.</returns> + public static Vector3 operator *(Quaternion quaternion, Vector3 vector) + { +#if DEBUG + if (!quaternion.IsNormalized()) + { + throw new InvalidOperationException("Quaternion is not normalized"); + } +#endif + var u = new Vector3(quaternion.x, quaternion.y, quaternion.z); + Vector3 uv = u.Cross(vector); + return vector + (((uv * quaternion.w) + u.Cross(uv)) * 2); + } + + /// <summary> + /// Returns a Vector3 rotated (multiplied) by the inverse quaternion. + /// </summary> + /// <param name="vector">A Vector3 to inversely rotate.</param> + /// <param name="quaternion">The quaternion to rotate by.</param> + /// <returns>The inversely rotated Vector3.</returns> + public static Vector3 operator *(Vector3 vector, Quaternion quaternion) + { + return quaternion.Inverse() * vector; + } + + /// <summary> /// Adds each component of the left <see cref="Quaternion"/> /// to the right <see cref="Quaternion"/>. This operation is not /// meaningful on its own, but it can be used as a part of a @@ -503,38 +515,6 @@ namespace Godot } /// <summary> - /// Rotates (multiplies) the <see cref="Vector3"/> - /// by the given <see cref="Quaternion"/>. - /// </summary> - /// <param name="quat">The quaternion to rotate by.</param> - /// <param name="vec">The vector to rotate.</param> - /// <returns>The rotated vector.</returns> - public static Vector3 operator *(Quaternion quat, Vector3 vec) - { -#if DEBUG - if (!quat.IsNormalized()) - { - throw new InvalidOperationException("Quaternion is not normalized."); - } -#endif - var u = new Vector3(quat.x, quat.y, quat.z); - Vector3 uv = u.Cross(vec); - return vec + (((uv * quat.w) + u.Cross(uv)) * 2); - } - - /// <summary> - /// Inversely rotates (multiplies) the <see cref="Vector3"/> - /// by the given <see cref="Quaternion"/>. - /// </summary> - /// <param name="vec">The vector to rotate.</param> - /// <param name="quat">The quaternion to rotate by.</param> - /// <returns>The inversely rotated vector.</returns> - public static Vector3 operator *(Vector3 vec, Quaternion quat) - { - return quat.Inverse() * vec; - } - - /// <summary> /// Multiplies each component of the <see cref="Quaternion"/> /// by the given <see cref="real_t"/>. This operation is not /// meaningful on its own, but it can be used as a part of a diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index ab2c0cd785..70cf8bbe22 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -384,31 +384,6 @@ namespace Godot return copy; } - /// <summary> - /// Returns a vector transformed (multiplied) by this transformation matrix. - /// </summary> - /// <seealso cref="XformInv(Vector2)"/> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - [Obsolete("Xform is deprecated. Use the multiplication operator (Transform2D * Vector2) instead.")] - public Vector2 Xform(Vector2 v) - { - return new Vector2(Tdotx(v), Tdoty(v)) + origin; - } - - /// <summary> - /// Returns a vector transformed (multiplied) by the inverse transformation matrix. - /// </summary> - /// <seealso cref="Xform(Vector2)"/> - /// <param name="v">A vector to inversely transform.</param> - /// <returns>The inversely transformed vector.</returns> - [Obsolete("XformInv is deprecated. Use the multiplication operator (Vector2 * Transform2D) instead.")] - public Vector2 XformInv(Vector2 v) - { - Vector2 vInv = v - origin; - return new Vector2(x.Dot(vInv), y.Dot(vInv)); - } - // Constants private static readonly Transform2D _identity = new Transform2D(1, 0, 0, 1, 0, 0); private static readonly Transform2D _flipX = new Transform2D(-1, 0, 0, 1, 0, 0); @@ -502,7 +477,7 @@ namespace Godot } /// <summary> - /// Returns a Vector2 transformed (multiplied) by transformation matrix. + /// Returns a Vector2 transformed (multiplied) by the transformation matrix. /// </summary> /// <param name="transform">The transformation to apply.</param> /// <param name="vector">A Vector2 to transform.</param> @@ -525,7 +500,7 @@ namespace Godot } /// <summary> - /// Returns a Rect2 transformed (multiplied) by transformation matrix. + /// Returns a Rect2 transformed (multiplied) by the transformation matrix. /// </summary> /// <param name="transform">The transformation to apply.</param> /// <param name="rect">A Rect2 to transform.</param> @@ -536,7 +511,7 @@ namespace Godot Vector2 toX = transform.x * rect.Size.x; Vector2 toY = transform.y * rect.Size.y; - return new Rect2(pos, rect.Size).Expand(pos + toX).Expand(pos + toY).Expand(pos + toX + toY); + return new Rect2(pos, new Vector2()).Expand(pos + toX).Expand(pos + toY).Expand(pos + toX + toY); } /// <summary> @@ -552,11 +527,11 @@ namespace Godot Vector2 to2 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y + rect.Size.y) * transform; Vector2 to3 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y) * transform; - return new Rect2(pos, rect.Size).Expand(to1).Expand(to2).Expand(to3); + return new Rect2(pos, new Vector2()).Expand(to1).Expand(to2).Expand(to3); } /// <summary> - /// Returns a copy of the given Vector2[] transformed (multiplied) by transformation matrix. + /// Returns a copy of the given Vector2[] transformed (multiplied) by the transformation matrix. /// </summary> /// <param name="transform">The transformation to apply.</param> /// <param name="array">A Vector2[] to transform.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 810f55e150..5481225e3f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -108,7 +108,7 @@ namespace Godot public Transform3D AffineInverse() { Basis basisInv = basis.Inverse(); - return new Transform3D(basisInv, basisInv.Xform(-origin)); + return new Transform3D(basisInv, basisInv * -origin); } /// <summary> @@ -147,7 +147,7 @@ namespace Godot public Transform3D Inverse() { Basis basisTr = basis.Transposed(); - return new Transform3D(basisTr, basisTr.Xform(-origin)); + return new Transform3D(basisTr, basisTr * -origin); } /// <summary> @@ -286,43 +286,6 @@ namespace Godot )); } - /// <summary> - /// Returns a vector transformed (multiplied) by this transformation matrix. - /// </summary> - /// <seealso cref="XformInv(Vector3)"/> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public Vector3 Xform(Vector3 v) - { - return new Vector3 - ( - basis.Row0.Dot(v) + origin.x, - basis.Row1.Dot(v) + origin.y, - basis.Row2.Dot(v) + origin.z - ); - } - - /// <summary> - /// Returns a vector transformed (multiplied) by the transposed transformation matrix. - /// - /// Note: This results in a multiplication by the inverse of the - /// transformation matrix only if it represents a rotation-reflection. - /// </summary> - /// <seealso cref="Xform(Vector3)"/> - /// <param name="v">A vector to inversely transform.</param> - /// <returns>The inversely transformed vector.</returns> - public Vector3 XformInv(Vector3 v) - { - Vector3 vInv = v - origin; - - return new Vector3 - ( - (basis.Row0[0] * vInv.x) + (basis.Row1[0] * vInv.y) + (basis.Row2[0] * vInv.z), - (basis.Row0[1] * vInv.x) + (basis.Row1[1] * vInv.y) + (basis.Row2[1] * vInv.z), - (basis.Row0[2] * vInv.x) + (basis.Row1[2] * vInv.y) + (basis.Row2[2] * vInv.z) - ); - } - // Constants private static readonly Transform3D _identity = new Transform3D(Basis.Identity, Vector3.Zero); private static readonly Transform3D _flipX = new Transform3D(new Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1), Vector3.Zero); @@ -399,12 +362,188 @@ namespace Godot /// <returns>The composed transform.</returns> public static Transform3D operator *(Transform3D left, Transform3D right) { - left.origin = left.Xform(right.origin); + left.origin = left * right.origin; left.basis *= right.basis; return left; } /// <summary> + /// Returns a Vector3 transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The transformed Vector3.</returns> + public static Vector3 operator *(Transform3D transform, Vector3 vector) + { + return new Vector3 + ( + transform.basis.Row0.Dot(vector) + transform.origin.x, + transform.basis.Row1.Dot(vector) + transform.origin.y, + transform.basis.Row2.Dot(vector) + transform.origin.z + ); + } + + /// <summary> + /// Returns a Vector3 transformed (multiplied) by the transposed transformation matrix. + /// + /// Note: This results in a multiplication by the inverse of the + /// transformation matrix only if it represents a rotation-reflection. + /// </summary> + /// <param name="vector">A Vector3 to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed Vector3.</returns> + public static Vector3 operator *(Vector3 vector, Transform3D transform) + { + Vector3 vInv = vector - transform.origin; + + return new Vector3 + ( + (transform.basis.Row0[0] * vInv.x) + (transform.basis.Row1[0] * vInv.y) + (transform.basis.Row2[0] * vInv.z), + (transform.basis.Row0[1] * vInv.x) + (transform.basis.Row1[1] * vInv.y) + (transform.basis.Row2[1] * vInv.z), + (transform.basis.Row0[2] * vInv.x) + (transform.basis.Row1[2] * vInv.y) + (transform.basis.Row2[2] * vInv.z) + ); + } + + /// <summary> + /// Returns an AABB transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="aabb">An AABB to transform.</param> + /// <returns>The transformed AABB.</returns> + public static AABB operator *(Transform3D transform, AABB aabb) + { + Vector3 min = aabb.Position; + Vector3 max = aabb.Position + aabb.Size; + + Vector3 tmin = transform.origin; + Vector3 tmax = transform.origin; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + real_t e = transform.basis[i][j] * min[j]; + real_t f = transform.basis[i][j] * max[j]; + if (e < f) + { + tmin[i] += e; + tmax[i] += f; + } + else + { + tmin[i] += f; + tmax[i] += e; + } + } + } + + return new AABB(tmin, tmax - tmin); + } + + /// <summary> + /// Returns an AABB transformed (multiplied) by the inverse transformation matrix. + /// </summary> + /// <param name="aabb">An AABB to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed AABB.</returns> + public static AABB operator *(AABB aabb, Transform3D transform) + { + Vector3 pos = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y + aabb.Size.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to1 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y + aabb.Size.y, aabb.Position.z) * transform; + Vector3 to2 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to3 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y, aabb.Position.z) * transform; + Vector3 to4 = new Vector3(aabb.Position.x, aabb.Position.y + aabb.Size.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to5 = new Vector3(aabb.Position.x, aabb.Position.y + aabb.Size.y, aabb.Position.z) * transform; + Vector3 to6 = new Vector3(aabb.Position.x, aabb.Position.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to7 = new Vector3(aabb.Position.x, aabb.Position.y, aabb.Position.z) * transform; + + return new AABB(pos, new Vector3()).Expand(to1).Expand(to2).Expand(to3).Expand(to4).Expand(to5).Expand(to6).Expand(to7); + } + + /// <summary> + /// Returns a Plane transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="plane">A Plane to transform.</param> + /// <returns>The transformed Plane.</returns> + public static Plane operator *(Transform3D transform, Plane plane) + { + Basis bInvTrans = transform.basis.Inverse().Transposed(); + + // Transform a single point on the plane. + Vector3 point = transform * (plane.Normal * plane.D); + + // Use inverse transpose for correct normals with non-uniform scaling. + Vector3 normal = (bInvTrans * plane.Normal).Normalized(); + + real_t d = normal.Dot(point); + return new Plane(normal, d); + } + + /// <summary> + /// Returns a Plane transformed (multiplied) by the inverse transformation matrix. + /// </summary> + /// <param name="plane">A Plane to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed Plane.</returns> + public static Plane operator *(Plane plane, Transform3D transform) + { + Transform3D tInv = transform.AffineInverse(); + Basis bTrans = transform.basis.Transposed(); + + // Transform a single point on the plane. + Vector3 point = tInv * (plane.Normal * plane.D); + + // Note that instead of precalculating the transpose, an alternative + // would be to use the transpose for the basis transform. + // However that would be less SIMD friendly (requiring a swizzle). + // So the cost is one extra precalced value in the calling code. + // This is probably worth it, as this could be used in bottleneck areas. And + // where it is not a bottleneck, the non-fast method is fine. + + // Use transpose for correct normals with non-uniform scaling. + Vector3 normal = (bTrans * plane.Normal).Normalized(); + + real_t d = normal.Dot(point); + return new Plane(normal, d); + } + + /// <summary> + /// Returns a copy of the given Vector3[] transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="array">A Vector3[] to transform.</param> + /// <returns>The transformed copy of the Vector3[].</returns> + public static Vector3[] operator *(Transform3D transform, Vector3[] array) + { + Vector3[] newArray = new Vector3[array.Length]; + + for (int i = 0; i < array.Length; i++) + { + newArray[i] = transform * array[i]; + } + + return newArray; + } + + /// <summary> + /// Returns a copy of the given Vector3[] transformed (multiplied) by the inverse transformation matrix. + /// </summary> + /// <param name="array">A Vector3[] to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed copy of the Vector3[].</returns> + public static Vector3[] operator *(Vector3[] array, Transform3D transform) + { + Vector3[] newArray = new Vector3[array.Length]; + + for (int i = 0; i < array.Length; i++) + { + newArray[i] = array[i] * transform; + } + + return newArray; + } + + /// <summary> /// Returns <see langword="true"/> if the transforms are exactly equal. /// Note: Due to floating-point precision errors, consider using /// <see cref="IsEqualApprox"/> instead, which is more reliable. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index e796d2f20f..2643f352d7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -518,7 +518,7 @@ namespace Godot throw new ArgumentException("Argument is not normalized", nameof(axis)); } #endif - return new Basis(axis, angle).Xform(this); + return new Basis(axis, angle) * this; } /// <summary> diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml index 9adb6acd9c..56404f796c 100644 --- a/modules/regex/doc_classes/RegEx.xml +++ b/modules/regex/doc_classes/RegEx.xml @@ -76,7 +76,7 @@ </description> </method> <method name="get_names" qualifiers="const"> - <return type="Array" /> + <return type="PackedStringArray" /> <description> Returns an array of names of named capturing groups in the compiled pattern. They are ordered by appearance. </description> diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index 569066867a..b2e6ea1004 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -351,8 +351,8 @@ int RegEx::get_group_count() const { return count; } -Array RegEx::get_names() const { - Array result; +PackedStringArray RegEx::get_names() const { + PackedStringArray result; ERR_FAIL_COND_V(!is_valid(), result); diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 9296de929f..6920d2634d 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -94,7 +94,7 @@ public: bool is_valid() const; String get_pattern() const; int get_group_count() const; - Array get_names() const; + PackedStringArray get_names() const; RegEx(); RegEx(const String &p_pattern); diff --git a/modules/regex/tests/test_regex.h b/modules/regex/tests/test_regex.h index 91af393db1..c81094d3ae 100644 --- a/modules/regex/tests/test_regex.h +++ b/modules/regex/tests/test_regex.h @@ -46,7 +46,7 @@ TEST_CASE("[RegEx] Initialization") { CHECK(re1.get_pattern() == pattern); CHECK(re1.get_group_count() == 1); - Array names = re1.get_names(); + PackedStringArray names = re1.get_names(); CHECK(names.size() == 1); CHECK(names[0] == "vowel"); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index c0cff08f13..e80eb43369 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2170,12 +2170,12 @@ double TextServerAdvanced::font_get_oversampling(const RID &p_font_rid) const { return fd->oversampling; } -Array TextServerAdvanced::font_get_size_cache_list(const RID &p_font_rid) const { +TypedArray<Vector2i> TextServerAdvanced::font_get_size_cache_list(const RID &p_font_rid) const { FontAdvanced *fd = font_owner.get_or_null(p_font_rid); - ERR_FAIL_COND_V(!fd, Array()); + ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>()); MutexLock lock(fd->mutex); - Array ret; + TypedArray<Vector2i> ret; for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) { ret.push_back(E.key); } @@ -2454,15 +2454,15 @@ PackedInt32Array TextServerAdvanced::font_get_texture_offsets(const RID &p_font_ return tex.offsets; } -Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { +PackedInt32Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { FontAdvanced *fd = font_owner.get_or_null(p_font_rid); - ERR_FAIL_COND_V(!fd, Array()); + ERR_FAIL_COND_V(!fd, PackedInt32Array()); MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); - ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Array()); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), PackedInt32Array()); - Array ret; + PackedInt32Array ret; const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; for (const KeyValue<int32_t, FontGlyph> &E : gl) { ret.push_back(E.key); @@ -2811,16 +2811,16 @@ Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, in #endif } -Array TextServerAdvanced::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { +TypedArray<Vector2i> TextServerAdvanced::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { FontAdvanced *fd = font_owner.get_or_null(p_font_rid); - ERR_FAIL_COND_V(!fd, Array()); + ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>()); MutexLock lock(fd->mutex); Vector2i size = _get_size(fd, p_size); - ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Array()); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), TypedArray<Vector2i>()); - Array ret; + TypedArray<Vector2i> ret; for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) { ret.push_back(E.key); } @@ -3065,7 +3065,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can if (gl.texture_idx != -1) { Color modulate = p_color; #ifdef MODULE_FREETYPE_ENABLED - if (fd->cache[size]->face && FT_HAS_COLOR(fd->cache[size]->face)) { + if (fd->cache[size]->face && fd->cache[size]->textures[gl.texture_idx].format == Image::FORMAT_RGBA8) { modulate.r = modulate.g = modulate.b = 1.0; } #endif diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 7ae329d616..6c3e8dbdcb 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -537,7 +537,7 @@ public: virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) override; virtual double font_get_oversampling(const RID &p_font_rid) const override; - virtual Array font_get_size_cache_list(const RID &p_font_rid) const override; + virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override; virtual void font_clear_size_cache(const RID &p_font_rid) override; virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override; @@ -566,7 +566,7 @@ public: virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override; virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override; - virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; + virtual PackedInt32Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override; virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override; @@ -590,7 +590,7 @@ public: virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; - virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; + virtual TypedArray<Vector2i> font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override; virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 3b91c6981e..016bcfc886 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -1259,12 +1259,12 @@ double TextServerFallback::font_get_oversampling(const RID &p_font_rid) const { return fd->oversampling; } -Array TextServerFallback::font_get_size_cache_list(const RID &p_font_rid) const { +TypedArray<Vector2i> TextServerFallback::font_get_size_cache_list(const RID &p_font_rid) const { FontFallback *fd = font_owner.get_or_null(p_font_rid); - ERR_FAIL_COND_V(!fd, Array()); + ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>()); MutexLock lock(fd->mutex); - Array ret; + TypedArray<Vector2i> ret; for (const KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) { ret.push_back(E.key); } @@ -1543,15 +1543,15 @@ PackedInt32Array TextServerFallback::font_get_texture_offsets(const RID &p_font_ return tex.offsets; } -Array TextServerFallback::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { +PackedInt32Array TextServerFallback::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { FontFallback *fd = font_owner.get_or_null(p_font_rid); - ERR_FAIL_COND_V(!fd, Array()); + ERR_FAIL_COND_V(!fd, PackedInt32Array()); MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); - ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Array()); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), PackedInt32Array()); - Array ret; + PackedInt32Array ret; const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; for (const KeyValue<int32_t, FontGlyph> &E : gl) { ret.push_back(E.key); @@ -1886,16 +1886,16 @@ Dictionary TextServerFallback::font_get_glyph_contours(const RID &p_font_rid, in #endif } -Array TextServerFallback::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { +TypedArray<Vector2i> TextServerFallback::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { FontFallback *fd = font_owner.get_or_null(p_font_rid); - ERR_FAIL_COND_V(!fd, Array()); + ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>()); MutexLock lock(fd->mutex); Vector2i size = _get_size(fd, p_size); - ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Array()); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), TypedArray<Vector2i>()); - Array ret; + TypedArray<Vector2i> ret; for (const KeyValue<Vector2i, Vector2> &E : fd->cache[size]->kerning_map) { ret.push_back(E.key); } @@ -2122,7 +2122,7 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can if (gl.texture_idx != -1) { Color modulate = p_color; #ifdef MODULE_FREETYPE_ENABLED - if (fd->cache[size]->face && FT_HAS_COLOR(fd->cache[size]->face)) { + if (fd->cache[size]->face && fd->cache[size]->textures[gl.texture_idx].format == Image::FORMAT_RGBA8) { modulate.r = modulate.g = modulate.b = 1.0; } #endif diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index fef19d442b..8e81433a2a 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -417,7 +417,7 @@ public: virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) override; virtual double font_get_oversampling(const RID &p_font_rid) const override; - virtual Array font_get_size_cache_list(const RID &p_font_rid) const override; + virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override; virtual void font_clear_size_cache(const RID &p_font_rid) override; virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override; @@ -446,7 +446,7 @@ public: virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override; virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override; - virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; + virtual PackedInt32Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override; virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override; @@ -469,7 +469,7 @@ public: virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; - virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; + virtual TypedArray<Vector2i> font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override; virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override; diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index a5eb09f786..fec48d1807 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -2850,8 +2850,8 @@ void VisualScriptEditor::reload(bool p_soft) { _update_graph(); } -Array VisualScriptEditor::get_breakpoints() { - Array breakpoints; +PackedInt32Array VisualScriptEditor::get_breakpoints() { + PackedInt32Array breakpoints; List<StringName> functions; script->get_function_list(&functions); for (int i = 0; i < functions.size(); i++) { diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index 306f71ecf8..0378da9700 100644 --- a/modules/visual_script/editor/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -341,7 +341,7 @@ public: virtual void ensure_focus() override; virtual void tag_saved_version() override; virtual void reload(bool p_soft) override; - virtual Array get_breakpoints() override; + virtual PackedInt32Array get_breakpoints() override; virtual void set_breakpoint(int p_line, bool p_enable) override{}; virtual void clear_breakpoints() override{}; virtual void add_callback(const String &p_function, PackedStringArray p_args) override; diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index b51dd18af6..d3bce12de1 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -83,7 +83,7 @@ bool DisplayServerAndroid::tts_is_paused() const { return TTS_Android::is_paused(); } -Array DisplayServerAndroid::tts_get_voices() const { +TypedArray<Dictionary> DisplayServerAndroid::tts_get_voices() const { return TTS_Android::get_voices(); } @@ -136,7 +136,7 @@ bool DisplayServerAndroid::clipboard_has() const { } } -Array DisplayServerAndroid::get_display_cutouts() const { +TypedArray<Rect2> DisplayServerAndroid::get_display_cutouts() const { GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); ERR_FAIL_NULL_V(godot_io_java, Array()); return godot_io_java->get_display_cutouts(); diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 2f30642319..6e14ba3e23 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -93,7 +93,7 @@ public: virtual bool tts_is_speaking() const override; virtual bool tts_is_paused() const override; - virtual Array tts_get_voices() const override; + virtual TypedArray<Dictionary> tts_get_voices() const override; virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override; virtual void tts_pause() override; @@ -104,7 +104,7 @@ public: virtual String clipboard_get() const override; virtual bool clipboard_has() const override; - virtual Array get_display_cutouts() const override; + virtual TypedArray<Rect2> get_display_cutouts() const override; virtual Rect2i get_display_safe_area() const override; virtual void screen_set_keep_on(bool p_enable) override; diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index 5877c15114..cea64a7f22 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -165,8 +165,8 @@ float GodotIOJavaWrapper::get_screen_refresh_rate(float fallback) { return fallback; } -Array GodotIOJavaWrapper::get_display_cutouts() { - Array result; +TypedArray<Rect2> GodotIOJavaWrapper::get_display_cutouts() { + TypedArray<Rect2> result; ERR_FAIL_NULL_V(_get_display_cutouts, result); JNIEnv *env = get_jni_env(); ERR_FAIL_NULL_V(env, result); diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index dc68f4d90d..9a1a877b6f 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -38,7 +38,7 @@ #include <jni.h> #include "core/math/rect2i.h" -#include "core/variant/array.h" +#include "core/variant/typed_array.h" #include "string_android.h" // Class that makes functions in java/src/org/godotengine/godot/GodotIO.java callable from C++ @@ -78,7 +78,7 @@ public: int get_screen_dpi(); float get_scaled_density(); float get_screen_refresh_rate(float fallback); - Array get_display_cutouts(); + TypedArray<Rect2> get_display_cutouts(); Rect2i get_display_safe_area(); String get_unique_id(); bool has_vk(); diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h index bbb2dd3ab3..f3624f24ab 100644 --- a/platform/ios/display_server_ios.h +++ b/platform/ios/display_server_ios.h @@ -127,7 +127,7 @@ public: virtual bool tts_is_speaking() const override; virtual bool tts_is_paused() const override; - virtual Array tts_get_voices() const override; + virtual TypedArray<Dictionary> tts_get_voices() const override; virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override; virtual void tts_pause() override; diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 6ce7e676a2..74d6bc2e97 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -336,8 +336,8 @@ bool DisplayServerIOS::tts_is_paused() const { return [tts isPaused]; } -Array DisplayServerIOS::tts_get_voices() const { - ERR_FAIL_COND_V(!tts, Array()); +TypedArray<Dictionary> DisplayServerIOS::tts_get_voices() const { + ERR_FAIL_COND_V(!tts, TypedArray<Dictionary>()); return [tts getVoices]; } diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index 48f637fcfe..30240ad2db 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -296,7 +296,7 @@ void DisplayServerJavaScript::update_voices_callback(int p_size, const char **p_ } } -Array DisplayServerJavaScript::tts_get_voices() const { +TypedArray<Dictionary> DisplayServerJavaScript::tts_get_voices() const { godot_js_tts_get_voices(update_voices_callback); return voices; } diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index fb7f5d02a8..cbb91477b7 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -124,7 +124,7 @@ public: // tts virtual bool tts_is_speaking() const override; virtual bool tts_is_paused() const override; - virtual Array tts_get_voices() const override; + virtual TypedArray<Dictionary> tts_get_voices() const override; virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override; virtual void tts_pause() override; diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 8efbd2e3c5..63998e2fde 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -322,8 +322,8 @@ bool DisplayServerX11::tts_is_paused() const { return tts->is_paused(); } -Array DisplayServerX11::tts_get_voices() const { - ERR_FAIL_COND_V(!tts, Array()); +TypedArray<Dictionary> DisplayServerX11::tts_get_voices() const { + ERR_FAIL_COND_V(!tts, TypedArray<Dictionary>()); return tts->get_voices(); } diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 9ce6a557db..0174cfb881 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -308,7 +308,7 @@ public: #ifdef SPEECHD_ENABLED virtual bool tts_is_speaking() const override; virtual bool tts_is_paused() const override; - virtual Array tts_get_voices() const override; + virtual TypedArray<Dictionary> tts_get_voices() const override; virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override; virtual void tts_pause() override; diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 5fda5dd974..e305ff3593 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -277,7 +277,7 @@ public: virtual bool tts_is_speaking() const override; virtual bool tts_is_paused() const override; - virtual Array tts_get_voices() const override; + virtual TypedArray<Dictionary> tts_get_voices() const override; virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override; virtual void tts_pause() override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 8142f44bb0..fa6bcda902 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1656,7 +1656,7 @@ bool DisplayServerMacOS::tts_is_paused() const { return [tts isPaused]; } -Array DisplayServerMacOS::tts_get_voices() const { +TypedArray<Dictionary> DisplayServerMacOS::tts_get_voices() const { ERR_FAIL_COND_V(!tts, Array()); return [tts getVoices]; } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 8c8dbef8a4..7eb61b3038 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -144,8 +144,8 @@ bool DisplayServerWindows::tts_is_paused() const { return tts->is_paused(); } -Array DisplayServerWindows::tts_get_voices() const { - ERR_FAIL_COND_V(!tts, Array()); +TypedArray<Dictionary> DisplayServerWindows::tts_get_voices() const { + ERR_FAIL_COND_V(!tts, TypedArray<Dictionary>()); return tts->get_voices(); } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index db9b589304..556ce9ff5d 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -478,7 +478,7 @@ public: virtual bool tts_is_speaking() const override; virtual bool tts_is_paused() const override; - virtual Array tts_get_voices() const override; + virtual TypedArray<Dictionary> tts_get_voices() const override; virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override; virtual void tts_pause() override; diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 7f991df36c..85de1fedee 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -361,8 +361,8 @@ void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) { } } -Array CollisionObject2D::_get_shape_owners() { - Array ret; +PackedInt32Array CollisionObject2D::_get_shape_owners() { + PackedInt32Array ret; for (const KeyValue<uint32_t, ShapeData> &E : shapes) { ret.push_back(E.key); } diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index f03c6fc72e..af216edc98 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -125,7 +125,7 @@ public: uint32_t create_shape_owner(Object *p_owner); void remove_shape_owner(uint32_t owner); void get_shape_owners(List<uint32_t> *r_owners); - Array _get_shape_owners(); + PackedInt32Array _get_shape_owners(); void shape_owner_set_transform(uint32_t p_owner, const Transform2D &p_transform); Transform2D shape_owner_get_transform(uint32_t p_owner) const; diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index e07f89fc65..b8b6296c45 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -485,7 +485,7 @@ void Camera3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera3D::get_keep_aspect_mode); ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera3D::set_doppler_tracking); ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera3D::get_doppler_tracking); - ClassDB::bind_method(D_METHOD("get_frustum"), &Camera3D::get_frustum); + ClassDB::bind_method(D_METHOD("get_frustum"), &Camera3D::_get_frustum); ClassDB::bind_method(D_METHOD("is_position_in_frustum", "world_point"), &Camera3D::is_position_in_frustum); ClassDB::bind_method(D_METHOD("get_camera_rid"), &Camera3D::get_camera); ClassDB::bind_method(D_METHOD("get_pyramid_shape_rid"), &Camera3D::get_pyramid_shape_rid); @@ -615,6 +615,11 @@ Vector<Plane> Camera3D::get_frustum() const { return cm.get_projection_planes(get_camera_transform()); } +TypedArray<Plane> Camera3D::_get_frustum() const { + Variant ret = get_frustum(); + return ret; +} + bool Camera3D::is_position_in_frustum(const Vector3 &p_position) const { Vector<Plane> frustum = get_frustum(); for (int i = 0; i < frustum.size(); i++) { diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index 1a00017b0b..bba9b7d1e4 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -86,6 +86,7 @@ private: // void _camera_make_current(Node *p_camera); friend class Viewport; void _update_audio_listener_state(); + TypedArray<Plane> _get_frustum() const; DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED; Ref<VelocityTracker3D> velocity_tracker; diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 22de9a47a2..48eb2a66b1 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -546,8 +546,8 @@ void CollisionObject3D::get_shape_owners(List<uint32_t> *r_owners) { } } -Array CollisionObject3D::_get_shape_owners() { - Array ret; +PackedInt32Array CollisionObject3D::_get_shape_owners() { + PackedInt32Array ret; for (const KeyValue<uint32_t, ShapeData> &E : shapes) { ret.push_back(E.key); } diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 3f0d070db4..51c31da79f 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -135,7 +135,7 @@ public: uint32_t create_shape_owner(Object *p_owner); void remove_shape_owner(uint32_t owner); void get_shape_owners(List<uint32_t> *r_owners); - Array _get_shape_owners(); + PackedInt32Array _get_shape_owners(); void shape_owner_set_transform(uint32_t p_owner, const Transform3D &p_transform); Transform3D shape_owner_get_transform(uint32_t p_owner) const; diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index f2d3dda792..35036b70d8 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -432,7 +432,7 @@ void Label3D::_shape() { TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i))); } - Array stt; + TypedArray<Vector2i> stt; if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) { GDVIRTUAL_CALL(_structured_text_parser, st_args, text, stt); } else { diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index dbc71cd9e7..7d9f83b7a2 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -479,12 +479,8 @@ Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, f case Variant::QUATERNION: { Quaternion i = p_initial_val; Quaternion d = p_delta_val; - Quaternion r; - - APPLY_EQUATION(x); - APPLY_EQUATION(y); - APPLY_EQUATION(z); - APPLY_EQUATION(w); + Quaternion r = i * d; + r = i.slerp(r, run_equation(p_trans, p_ease, p_time, 0.0, 1.0, p_duration)); return r; } diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 776623f7ce..4bc2fe6ed9 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -490,8 +490,8 @@ void ButtonGroup::get_buttons(List<BaseButton *> *r_buttons) { } } -Array ButtonGroup::_get_buttons() { - Array btns; +TypedArray<BaseButton> ButtonGroup::_get_buttons() { + TypedArray<BaseButton> btns; for (const BaseButton *E : buttons) { btns.push_back(E); } diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 7cf8de6432..68f26b13fd 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -151,7 +151,7 @@ protected: public: BaseButton *get_pressed_button(); void get_buttons(List<BaseButton *> *r_buttons); - Array _get_buttons(); + TypedArray<BaseButton> _get_buttons(); ButtonGroup(); }; diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 8968c1cc17..e54ba7ce13 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -1280,8 +1280,8 @@ void CodeEdit::clear_breakpointed_lines() { } } -Array CodeEdit::get_breakpointed_lines() const { - Array ret; +PackedInt32Array CodeEdit::get_breakpointed_lines() const { + PackedInt32Array ret; for (int i = 0; i < get_line_count(); i++) { if (is_line_breakpointed(i)) { ret.append(i); @@ -1309,8 +1309,8 @@ void CodeEdit::clear_bookmarked_lines() { } } -Array CodeEdit::get_bookmarked_lines() const { - Array ret; +PackedInt32Array CodeEdit::get_bookmarked_lines() const { + PackedInt32Array ret; for (int i = 0; i < get_line_count(); i++) { if (is_line_bookmarked(i)) { ret.append(i); @@ -1338,8 +1338,8 @@ void CodeEdit::clear_executing_lines() { } } -Array CodeEdit::get_executing_lines() const { - Array ret; +PackedInt32Array CodeEdit::get_executing_lines() const { + PackedInt32Array ret; for (int i = 0; i < get_line_count(); i++) { if (is_line_executing(i)) { ret.append(i); @@ -2769,7 +2769,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() { i++; } - Array completion_options; + TypedArray<Dictionary> completion_options; GDVIRTUAL_CALL(_filter_code_completion_candidates, completion_options_sources, completion_options); diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index 08bd91a368..2065f3e681 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -266,7 +266,7 @@ protected: GDVIRTUAL1(_confirm_code_completion, bool) GDVIRTUAL1(_request_code_completion, bool) - GDVIRTUAL1RC(Array, _filter_code_completion_candidates, TypedArray<Dictionary>) + GDVIRTUAL1RC(TypedArray<Dictionary>, _filter_code_completion_candidates, TypedArray<Dictionary>) public: /* General overrides */ @@ -322,19 +322,19 @@ public: void set_line_as_breakpoint(int p_line, bool p_breakpointed); bool is_line_breakpointed(int p_line) const; void clear_breakpointed_lines(); - Array get_breakpointed_lines() const; + PackedInt32Array get_breakpointed_lines() const; // bookmarks void set_line_as_bookmarked(int p_line, bool p_bookmarked); bool is_line_bookmarked(int p_line) const; void clear_bookmarked_lines(); - Array get_bookmarked_lines() const; + PackedInt32Array get_bookmarked_lines() const; // executing lines void set_line_as_executing(int p_line, bool p_executing); bool is_line_executing(int p_line) const; void clear_executing_lines(); - Array get_executing_lines() const; + PackedInt32Array get_executing_lines() const; /* Line numbers */ void set_draw_line_numbers(bool p_draw); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 545c39a605..9667cfe197 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2946,13 +2946,13 @@ void Control::end_bulk_theme_override() { // Internationalization. -Array Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { +TypedArray<Vector2i> Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { if (p_parser_type == TextServer::STRUCTURED_TEXT_CUSTOM) { - Array ret; + TypedArray<Vector2i> ret; if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret)) { return ret; } else { - return Array(); + return TypedArray<Vector2i>(); } } else { return TS->parse_structured_text(p_parser_type, p_args, p_text); diff --git a/scene/gui/control.h b/scene/gui/control.h index a50c66b634..d7e120260c 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -328,7 +328,7 @@ protected: // Internationalization. - virtual Array structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; + virtual TypedArray<Vector2i> structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; // Base object overrides. @@ -341,7 +341,7 @@ protected: // Exposed virtual methods. GDVIRTUAL1RC(bool, _has_point, Vector2) - GDVIRTUAL2RC(Array, _structured_text_parser, Array, String) + GDVIRTUAL2RC(TypedArray<Vector2i>, _structured_text_parser, Array, String) GDVIRTUAL0RC(Vector2, _get_minimum_size) GDVIRTUAL1RC(Variant, _get_drag_data, Vector2) diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index d7aa516ee6..9505a30540 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -98,11 +98,10 @@ void SplitContainer::_resort() { // Compute the final middle separation middle_sep = no_offset_middle_sep; if (!collapsed) { - int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, (get_size()[axis] - ms_second[axis] - sep) - no_offset_middle_sep); - middle_sep += clamped_split_offset; + int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, get_size()[axis] - ms_second[axis] - sep); + middle_sep = MAX(middle_sep, clamped_split_offset); if (should_clamp_split_offset) { split_offset = clamped_split_offset; - should_clamp_split_offset = false; } } diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index bef431e980..9b1adde00a 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -31,6 +31,7 @@ #include "bit_map.h" #include "core/io/image_loader.h" +#include "core/variant/typed_array.h" void BitMap::create(const Size2 &p_size) { ERR_FAIL_COND(p_size.width < 1); @@ -576,12 +577,12 @@ void BitMap::shrink_mask(int p_pixels, const Rect2 &p_rect) { grow_mask(-p_pixels, p_rect); } -Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const { +TypedArray<PackedVector2Array> BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const { Vector<Vector<Vector2>> result = clip_opaque_to_polygons(p_rect, p_epsilon); // Convert result to bindable types - Array result_array; + TypedArray<PackedVector2Array> result_array; result_array.resize(result.size()); for (int i = 0; i < result.size(); i++) { const Vector<Vector2> &polygon = result[i]; diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index 0d0d779c32..d8507dfa8b 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -35,6 +35,9 @@ #include "core/io/resource.h" #include "core/io/resource_loader.h" +template <typename T> +class TypedArray; + class BitMap : public Resource { GDCLASS(BitMap, Resource); OBJ_SAVE_TYPE(BitMap); @@ -45,7 +48,7 @@ class BitMap : public Resource { Vector<Vector2> _march_square(const Rect2i &rect, const Point2i &start) const; - Array _opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const; + TypedArray<PackedVector2Array> _opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const; protected: void _set_data(const Dictionary &p_d); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index e7d5d40777..f8651fecd6 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -1267,7 +1267,7 @@ void FontFile::_get_property_list(List<PropertyInfo> *p_list) const { } for (int i = 0; i < cache.size(); i++) { String prefix = "cache/" + itos(i) + "/"; - Array sizes = get_size_cache_list(i); + TypedArray<Vector2i> sizes = get_size_cache_list(i); p_list->push_back(PropertyInfo(Variant::DICTIONARY, prefix + "variation_coordinates", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); p_list->push_back(PropertyInfo(Variant::INT, "face_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); p_list->push_back(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); @@ -1289,7 +1289,7 @@ void FontFile::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, prefix_sz + "textures/" + itos(k) + "/offsets", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); p_list->push_back(PropertyInfo(Variant::OBJECT, prefix_sz + "textures/" + itos(k) + "/image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)); } - Array glyphs = get_glyph_list(i, sz); + PackedInt32Array glyphs = get_glyph_list(i, sz); for (int k = 0; k < glyphs.size(); k++) { const int32_t &gl = glyphs[k]; if (sz.y == 0) { @@ -1301,7 +1301,7 @@ void FontFile::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, prefix_sz + "glyphs/" + itos(gl) + "/texture_idx", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); } if (sz.y == 0) { - Array kerning_map = get_kerning_list(i, sz.x); + TypedArray<Vector2i> kerning_map = get_kerning_list(i, sz.x); for (int k = 0; k < kerning_map.size(); k++) { const Vector2i &gl_pair = kerning_map[k]; p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "kerning_overrides/" + itos(gl_pair.x) + "/" + itos(gl_pair.y), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); @@ -2089,7 +2089,7 @@ void FontFile::remove_cache(int p_cache_index) { emit_changed(); } -Array FontFile::get_size_cache_list(int p_cache_index) const { +TypedArray<Vector2i> FontFile::get_size_cache_list(int p_cache_index) const { ERR_FAIL_COND_V(p_cache_index < 0, Array()); _ensure_rid(p_cache_index); return TS->font_get_size_cache_list(cache[p_cache_index]); @@ -2260,8 +2260,8 @@ PackedInt32Array FontFile::get_texture_offsets(int p_cache_index, const Vector2i return TS->font_get_texture_offsets(cache[p_cache_index], p_size, p_texture_index); } -Array FontFile::get_glyph_list(int p_cache_index, const Vector2i &p_size) const { - ERR_FAIL_COND_V(p_cache_index < 0, Array()); +PackedInt32Array FontFile::get_glyph_list(int p_cache_index, const Vector2i &p_size) const { + ERR_FAIL_COND_V(p_cache_index < 0, PackedInt32Array()); _ensure_rid(p_cache_index); return TS->font_get_glyph_list(cache[p_cache_index], p_size); } @@ -2338,7 +2338,7 @@ int FontFile::get_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, i return TS->font_get_glyph_texture_idx(cache[p_cache_index], p_size, p_glyph); } -Array FontFile::get_kerning_list(int p_cache_index, int p_size) const { +TypedArray<Vector2i> FontFile::get_kerning_list(int p_cache_index, int p_size) const { ERR_FAIL_COND_V(p_cache_index < 0, Array()); _ensure_rid(p_cache_index); return TS->font_get_kerning_list(cache[p_cache_index], p_size); diff --git a/scene/resources/font.h b/scene/resources/font.h index 696152a23b..decbcfbb69 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -230,7 +230,7 @@ public: virtual void clear_cache(); virtual void remove_cache(int p_cache_index); - virtual Array get_size_cache_list(int p_cache_index) const; + virtual TypedArray<Vector2i> get_size_cache_list(int p_cache_index) const; virtual void clear_size_cache(int p_cache_index); virtual void remove_size_cache(int p_cache_index, const Vector2i &p_size); @@ -271,7 +271,7 @@ public: virtual void set_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset); virtual PackedInt32Array get_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index) const; - virtual Array get_glyph_list(int p_cache_index, const Vector2i &p_size) const; + virtual PackedInt32Array get_glyph_list(int p_cache_index, const Vector2i &p_size) const; virtual void clear_glyphs(int p_cache_index, const Vector2i &p_size); virtual void remove_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_glyph); @@ -290,7 +290,7 @@ public: virtual void set_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx); virtual int get_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const; - virtual Array get_kerning_list(int p_cache_index, int p_size) const; + virtual TypedArray<Vector2i> get_kerning_list(int p_cache_index, int p_size) const; virtual void clear_kerning_map(int p_cache_index, int p_size); virtual void remove_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair); diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 9052f8e05e..64695557aa 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -144,8 +144,8 @@ int AudioDriver::get_total_channels_by_speaker_mode(AudioDriver::SpeakerMode p_m ERR_FAIL_V(2); } -Array AudioDriver::get_device_list() { - Array list; +PackedStringArray AudioDriver::get_device_list() { + PackedStringArray list; list.push_back("Default"); @@ -156,8 +156,8 @@ String AudioDriver::get_device() { return "Default"; } -Array AudioDriver::capture_get_device_list() { - Array list; +PackedStringArray AudioDriver::capture_get_device_list() { + PackedStringArray list; list.push_back("Default"); @@ -1637,7 +1637,7 @@ Ref<AudioBusLayout> AudioServer::generate_bus_layout() const { return state; } -Array AudioServer::get_device_list() { +PackedStringArray AudioServer::get_device_list() { return AudioDriver::get_singleton()->get_device_list(); } @@ -1649,7 +1649,7 @@ void AudioServer::set_device(String device) { AudioDriver::get_singleton()->set_device(device); } -Array AudioServer::capture_get_device_list() { +PackedStringArray AudioServer::capture_get_device_list() { return AudioDriver::get_singleton()->capture_get_device_list(); } diff --git a/servers/audio_server.h b/servers/audio_server.h index 5613267909..588107c25d 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -94,7 +94,7 @@ public: virtual void start() = 0; virtual int get_mix_rate() const = 0; virtual SpeakerMode get_speaker_mode() const = 0; - virtual Array get_device_list(); + virtual PackedStringArray get_device_list(); virtual String get_device(); virtual void set_device(String device) {} virtual void lock() = 0; @@ -105,7 +105,7 @@ public: virtual Error capture_stop() { return FAILED; } virtual void capture_set_device(const String &p_name) {} virtual String capture_get_device() { return "Default"; } - virtual Array capture_get_device_list(); // TODO: convert this and get_device_list to PackedStringArray + virtual PackedStringArray capture_get_device_list(); virtual float get_latency() { return 0; } @@ -419,11 +419,11 @@ public: void set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout); Ref<AudioBusLayout> generate_bus_layout() const; - Array get_device_list(); + PackedStringArray get_device_list(); String get_device(); void set_device(String device); - Array capture_get_device_list(); + PackedStringArray capture_get_device_list(); String capture_get_device(); void capture_set_device(const String &p_name); diff --git a/servers/camera_server.cpp b/servers/camera_server.cpp index 91df3afadd..b83b41a571 100644 --- a/servers/camera_server.cpp +++ b/servers/camera_server.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "camera_server.h" +#include "core/variant/typed_array.h" #include "rendering_server.h" #include "servers/camera/camera_feed.h" @@ -143,8 +144,8 @@ int CameraServer::get_feed_count() { return feeds.size(); }; -Array CameraServer::get_feeds() { - Array return_feeds; +TypedArray<CameraFeed> CameraServer::get_feeds() { + TypedArray<CameraFeed> return_feeds; int cc = get_feed_count(); return_feeds.resize(cc); diff --git a/servers/camera_server.h b/servers/camera_server.h index b70938c34f..c6fb906b3c 100644 --- a/servers/camera_server.h +++ b/servers/camera_server.h @@ -43,6 +43,8 @@ **/ class CameraFeed; +template <typename T> +class TypedArray; class CameraServer : public Object { GDCLASS(CameraServer, Object); @@ -100,7 +102,7 @@ public: // Get our feeds. Ref<CameraFeed> get_feed(int p_index); int get_feed_count(); - Array get_feeds(); + TypedArray<CameraFeed> get_feeds(); // Intended for use with custom CameraServer implementation. RID feed_texture(int p_id, FeedImage p_texture); diff --git a/servers/display_server.cpp b/servers/display_server.cpp index ff6d769a86..0c05570b23 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -256,14 +256,14 @@ void DisplayServer::tts_resume() { WARN_PRINT("TTS is not supported by this display server."); } -Array DisplayServer::tts_get_voices() const { +TypedArray<Dictionary> DisplayServer::tts_get_voices() const { WARN_PRINT("TTS is not supported by this display server."); - return Array(); + return TypedArray<Dictionary>(); } PackedStringArray DisplayServer::tts_get_voices_for_language(const String &p_language) const { PackedStringArray ret; - Array voices = tts_get_voices(); + TypedArray<Dictionary> voices = tts_get_voices(); for (int i = 0; i < voices.size(); i++) { const Dictionary &voice = voices[i]; if (voice.has("id") && voice.has("language") && voice["language"].operator String().begins_with(p_language)) { diff --git a/servers/display_server.h b/servers/display_server.h index a5c42617af..4e52c58633 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -198,7 +198,7 @@ private: public: virtual bool tts_is_speaking() const; virtual bool tts_is_paused() const; - virtual Array tts_get_voices() const; + virtual TypedArray<Dictionary> tts_get_voices() const; virtual PackedStringArray tts_get_voices_for_language(const String &p_language) const; virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false); @@ -230,7 +230,7 @@ public: virtual void clipboard_set_primary(const String &p_text); virtual String clipboard_get_primary() const; - virtual Array get_display_cutouts() const { return Array(); } + virtual TypedArray<Rect2> get_display_cutouts() const { return TypedArray<Rect2>(); } virtual Rect2i get_display_safe_area() const { return screen_get_usable_rect(); } enum { diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 59310ab69b..c53560523d 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -634,12 +634,12 @@ double TextServerExtension::font_get_oversampling(const RID &p_font_rid) const { return 0.0; } -Array TextServerExtension::font_get_size_cache_list(const RID &p_font_rid) const { - Array ret; +TypedArray<Vector2i> TextServerExtension::font_get_size_cache_list(const RID &p_font_rid) const { + TypedArray<Vector2i> ret; if (GDVIRTUAL_CALL(font_get_size_cache_list, p_font_rid, ret)) { return ret; } - return Array(); + return TypedArray<Vector2i>(); } void TextServerExtension::font_clear_size_cache(const RID &p_font_rid) { @@ -750,12 +750,12 @@ PackedInt32Array TextServerExtension::font_get_texture_offsets(const RID &p_font return PackedInt32Array(); } -Array TextServerExtension::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { - Array ret; +PackedInt32Array TextServerExtension::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { + PackedInt32Array ret; if (GDVIRTUAL_CALL(font_get_glyph_list, p_font_rid, p_size, ret)) { return ret; } - return Array(); + return PackedInt32Array(); } void TextServerExtension::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) { @@ -850,12 +850,12 @@ Dictionary TextServerExtension::font_get_glyph_contours(const RID &p_font_rid, i return Dictionary(); } -Array TextServerExtension::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { - Array ret; +TypedArray<Vector2i> TextServerExtension::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { + TypedArray<Vector2i> ret; if (GDVIRTUAL_CALL(font_get_kerning_list, p_font_rid, p_size, ret)) { return ret; } - return Array(); + return TypedArray<Vector2i>(); } void TextServerExtension::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) { diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 81af1b60e5..15cffdf152 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -35,6 +35,7 @@ #include "core/object/script_language.h" #include "core/os/thread_safe.h" #include "core/variant/native_ptr.h" +#include "core/variant/typed_array.h" #include "servers/text_server.h" class TextServerExtension : public TextServer { @@ -172,10 +173,10 @@ public: GDVIRTUAL2(font_set_oversampling, RID, double); GDVIRTUAL1RC(double, font_get_oversampling, RID); - virtual Array font_get_size_cache_list(const RID &p_font_rid) const override; + virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override; virtual void font_clear_size_cache(const RID &p_font_rid) override; virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override; - GDVIRTUAL1RC(Array, font_get_size_cache_list, RID); + GDVIRTUAL1RC(TypedArray<Vector2i>, font_get_size_cache_list, RID); GDVIRTUAL1(font_clear_size_cache, RID); GDVIRTUAL2(font_remove_size_cache, RID, const Vector2i &); @@ -221,10 +222,10 @@ public: GDVIRTUAL4(font_set_texture_offsets, RID, const Vector2i &, int64_t, const PackedInt32Array &); GDVIRTUAL3RC(PackedInt32Array, font_get_texture_offsets, RID, const Vector2i &, int64_t); - virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; + virtual PackedInt32Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override; virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override; - GDVIRTUAL2RC(Array, font_get_glyph_list, RID, const Vector2i &); + GDVIRTUAL2RC(PackedInt32Array, font_get_glyph_list, RID, const Vector2i &); GDVIRTUAL2(font_clear_glyphs, RID, const Vector2i &); GDVIRTUAL3(font_remove_glyph, RID, const Vector2i &, int64_t); @@ -262,10 +263,10 @@ public: virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; GDVIRTUAL3RC(Dictionary, font_get_glyph_contours, RID, int64_t, int64_t); - virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; + virtual TypedArray<Vector2i> font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override; virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override; - GDVIRTUAL2RC(Array, font_get_kerning_list, RID, int64_t); + GDVIRTUAL2RC(TypedArray<Vector2i>, font_get_kerning_list, RID, int64_t); GDVIRTUAL2(font_clear_kerning_map, RID, int64_t); GDVIRTUAL3(font_remove_kerning, RID, int64_t, const Vector2i &); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 2bf0837d88..75712d0c5a 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "servers/text_server.h" +#include "core/variant/typed_array.h" #include "servers/rendering_server.h" TextServerManager *TextServerManager::singleton = nullptr; @@ -1585,8 +1586,8 @@ String TextServer::strip_diacritics(const String &p_string) const { return result; } -Array TextServer::parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { - Array ret; +TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { + TypedArray<Vector2i> ret; switch (p_parser_type) { case STRUCTURED_TEXT_URI: { int prev = 0; diff --git a/servers/text_server.h b/servers/text_server.h index d45bea3271..6360cc1726 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -37,6 +37,9 @@ #include "core/variant/native_ptr.h" #include "core/variant/variant.h" +template <typename T> +class TypedArray; + struct Glyph; struct CaretInfo; @@ -269,7 +272,7 @@ public: virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) = 0; virtual double font_get_oversampling(const RID &p_font_rid) const = 0; - virtual Array font_get_size_cache_list(const RID &p_font_rid) const = 0; + virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const = 0; virtual void font_clear_size_cache(const RID &p_font_rid) = 0; virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) = 0; @@ -298,7 +301,7 @@ public: virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) = 0; virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const = 0; - virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const = 0; + virtual PackedInt32Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const = 0; virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) = 0; virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) = 0; @@ -321,7 +324,7 @@ public: virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const = 0; - virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const = 0; + virtual TypedArray<Vector2i> font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const = 0; virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) = 0; virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) = 0; @@ -476,7 +479,7 @@ public: virtual String string_to_upper(const String &p_string, const String &p_language = "") const = 0; virtual String string_to_lower(const String &p_string, const String &p_language = "") const = 0; - Array parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; + TypedArray<Vector2i> parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; TextServer(); ~TextServer(); diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index 7605f24cf8..4fc88f398f 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -74,7 +74,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") { code_edit->set_line_as_breakpoint(0, true); CHECK(code_edit->is_line_breakpointed(0)); - CHECK(code_edit->get_breakpointed_lines()[0] == Variant(0)); + CHECK(code_edit->get_breakpointed_lines()[0] == 0); SIGNAL_CHECK("breakpoint_toggled", args); code_edit->set_line_as_breakpoint(0, false); @@ -451,7 +451,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") { ERR_PRINT_ON; code_edit->set_line_as_bookmarked(0, true); - CHECK(code_edit->get_bookmarked_lines()[0] == Variant(0)); + CHECK(code_edit->get_bookmarked_lines()[0] == 0); CHECK(code_edit->is_line_bookmarked(0)); code_edit->set_line_as_bookmarked(0, false); @@ -657,7 +657,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") { ERR_PRINT_ON; code_edit->set_line_as_executing(0, true); - CHECK(code_edit->get_executing_lines()[0] == Variant(0)); + CHECK(code_edit->get_executing_lines()[0] == 0); CHECK(code_edit->is_line_executing(0)); code_edit->set_line_as_executing(0, false); |