summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/linux_builds.yml12
-rw-r--r--SConstruct7
-rw-r--r--core/io/file_access_compressed.cpp4
-rw-r--r--core/io/file_access_zip.cpp2
-rw-r--r--core/io/resource.cpp4
-rw-r--r--core/math/basis.cpp39
-rw-r--r--core/math/basis.h7
-rw-r--r--core/math/transform_3d.cpp24
-rw-r--r--core/math/transform_3d.h3
-rw-r--r--core/object/script_language.h1
-rw-r--r--core/os/os.cpp2
-rw-r--r--core/variant/variant_setget.cpp2
-rw-r--r--doc/classes/EditorExportPlugin.xml12
-rw-r--r--doc/classes/EditorSceneFormatImporter.xml22
-rw-r--r--doc/classes/PackedByteArray.xml2
-rw-r--r--doc/classes/PackedColorArray.xml2
-rw-r--r--doc/classes/PackedFloat32Array.xml2
-rw-r--r--doc/classes/PackedFloat64Array.xml2
-rw-r--r--doc/classes/PackedInt32Array.xml2
-rw-r--r--doc/classes/PackedInt64Array.xml2
-rw-r--r--doc/classes/PackedStringArray.xml2
-rw-r--r--doc/classes/PackedVector2Array.xml2
-rw-r--r--doc/classes/PackedVector3Array.xml2
-rw-r--r--doc/classes/RayCast3D.xml3
-rw-r--r--doc/classes/StreamPeer.xml2
-rw-r--r--doc/classes/Transform3D.xml6
-rw-r--r--doc/classes/Vector2.xml12
-rw-r--r--doc/classes/Vector2i.xml4
-rw-r--r--doc/classes/Vector3.xml10
-rw-r--r--doc/classes/VisualShaderNodeCustom.xml2
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp4
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp4
-rw-r--r--editor/code_editor.cpp4
-rw-r--r--editor/editor_asset_installer.cpp4
-rw-r--r--editor/editor_export.cpp9
-rw-r--r--editor/editor_export.h5
-rw-r--r--editor/editor_fonts.cpp4
-rw-r--r--editor/editor_resource_picker.cpp38
-rw-r--r--editor/editor_themes.cpp2
-rw-r--r--editor/export_template_manager.cpp6
-rw-r--r--editor/import/editor_import_collada.cpp4
-rw-r--r--editor/import/editor_import_collada.h4
-rw-r--r--editor/import/resource_importer_obj.cpp4
-rw-r--r--editor/import/resource_importer_obj.h4
-rw-r--r--editor/import/resource_importer_scene.cpp104
-rw-r--r--editor/import/resource_importer_scene.h21
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp14
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp157
-rw-r--r--editor/plugins/node_3d_editor_plugin.h2
-rw-r--r--editor/project_manager.cpp6
-rwxr-xr-xmisc/scripts/file_format.sh2
-rw-r--r--modules/camera/camera_osx.mm2
-rw-r--r--modules/fbx/editor_scene_importer_fbx.cpp7
-rw-r--r--modules/fbx/editor_scene_importer_fbx.h5
-rw-r--r--modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd41
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.cpp8
-rw-r--r--modules/gltf/editor_scene_importer_gltf.cpp4
-rw-r--r--modules/gltf/editor_scene_importer_gltf.h4
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml3
-rw-r--r--modules/gridmap/grid_map.cpp18
-rw-r--r--modules/gridmap/grid_map.h6
-rw-r--r--modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs67
-rw-r--r--platform/android/export/export_plugin.cpp4
-rw-r--r--platform/iphone/export/export_plugin.cpp2
-rw-r--r--platform/iphone/ios.mm2
-rw-r--r--platform/iphone/joypad_iphone.mm2
-rw-r--r--platform/javascript/display_server_javascript.cpp4
-rw-r--r--platform/javascript/export/export_plugin.cpp2
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp4
-rw-r--r--platform/osx/export/export_plugin.cpp123
-rw-r--r--platform/osx/export/export_plugin.h7
-rw-r--r--platform/osx/os_osx.mm4
-rw-r--r--platform/uwp/export/export_plugin.cpp2
-rw-r--r--scene/2d/navigation_region_2d.cpp8
-rw-r--r--scene/3d/node_3d.cpp11
-rw-r--r--scene/gui/code_edit.cpp103
-rw-r--r--scene/gui/control.cpp51
-rw-r--r--scene/gui/subviewport_container.cpp1
-rw-r--r--scene/main/node.cpp21
-rw-r--r--scene/main/viewport.cpp6
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/default_theme/default_theme.cpp16
-rw-r--r--scene/resources/theme.cpp138
-rw-r--r--scene/resources/theme.h56
-rw-r--r--scene/resources/visual_shader.cpp4
-rw-r--r--scene/resources/visual_shader.h2
-rw-r--r--servers/navigation_server_2d.cpp2
-rw-r--r--servers/navigation_server_2d.h2
-rw-r--r--servers/navigation_server_3d.cpp2
-rw-r--r--servers/navigation_server_3d.h2
90 files changed, 888 insertions, 460 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index 92c2e3c516..eeca57a22e 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -122,13 +122,13 @@ jobs:
${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true
git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$'
- # Download, unzip and setup SwiftShader library [4466040]
+ # Download, unzip and setup SwiftShader library
+ # See https://github.com/godotengine/regression-test-project/releases/tag/_ci-deps for details
- name: Download SwiftShader
if: ${{ matrix.tests }}
run: |
- wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/swiftshader2.zip
- unzip swiftshader2.zip
- rm swiftshader2.zip
+ wget https://github.com/godotengine/regression-test-project/releases/download/_ci-deps/swiftshader-ubuntu20.04-20211002.zip
+ unzip swiftshader-ubuntu20.04-20211002.zip
curr="$(pwd)/libvk_swiftshader.so"
sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json
@@ -136,9 +136,9 @@ jobs:
- name: Download test project
if: ${{ matrix.proj-test }}
run: |
- wget https://github.com/qarmin/RegressionTestProject/archive/4.0.zip
+ wget https://github.com/godotengine/regression-test-project/archive/4.0.zip
unzip 4.0.zip
- mv "RegressionTestProject-4.0" "test_project"
+ mv "regression-test-project-4.0" "test_project"
# Editor is quite complicated piece of software, so it is easy to introduce bug here
- name: Open and close editor
diff --git a/SConstruct b/SConstruct
index 9dcc6c554f..bdf4937cd7 100644
--- a/SConstruct
+++ b/SConstruct
@@ -300,13 +300,6 @@ opts.Update(env_base)
env_base["platform"] = selected_platform # Must always be re-set after calling opts.Update().
Help(opts.GenerateHelpText(env_base))
-# Detect and print a warning listing unknown SCons variables to ease troubleshooting.
-unknown = opts.UnknownVariables()
-if unknown:
- print("WARNING: Unknown SCons variables were passed and will be ignored:")
- for item in unknown.items():
- print(" " + item[0] + "=" + item[1])
-
# add default include paths
env_base.Prepend(CPPPATH=["#"])
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 715468f71d..526952b14f 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -312,10 +312,10 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con
} else {
read_block--;
at_end = true;
- if (i < p_length - 1) {
+ if (i + 1 < p_length) {
read_eof = true;
}
- return i;
+ return i + 1;
}
}
}
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index d90a0c9110..6347862775 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -189,7 +189,7 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, uint6
f.package = pkg_num;
unzGetFilePos(zfile, &f.file_pos);
- String fname = String("res://") + filename_inzip;
+ String fname = String("res://") + String::utf8(filename_inzip);
files[fname] = f;
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 311d71638b..66d5c54b53 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -520,8 +520,8 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
FileAccess *f = nullptr;
if (p_file) {
- f = FileAccess::open(p_file, FileAccess::WRITE);
- ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String(p_file) + "'.");
+ f = FileAccess::open(String::utf8(p_file), FileAccess::WRITE);
+ ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String::utf8(p_file) + "'.");
}
const String *K = nullptr;
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 6159e78bab..a9b4651664 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -94,6 +94,18 @@ Basis Basis::orthonormalized() const {
return c;
}
+void Basis::orthogonalize() {
+ Vector3 scl = get_scale();
+ orthonormalize();
+ scale_local(scl);
+}
+
+Basis Basis::orthogonalized() const {
+ Basis c = *this;
+ c.orthogonalize();
+ return c;
+}
+
bool Basis::is_orthogonal() const {
Basis identity;
Basis m = (*this) * transposed();
@@ -237,6 +249,24 @@ void Basis::scale_local(const Vector3 &p_scale) {
*this = scaled_local(p_scale);
}
+void Basis::scale_orthogonal(const Vector3 &p_scale) {
+ *this = scaled_orthogonal(p_scale);
+}
+
+Basis Basis::scaled_orthogonal(const Vector3 &p_scale) const {
+ Basis m = *this;
+ Vector3 s = Vector3(-1, -1, -1) + p_scale;
+ Vector3 dots;
+ Basis b;
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ dots[j] += s[i] * abs(m.get_axis(i).normalized().dot(b.get_axis(j)));
+ }
+ }
+ m.scale_local(Vector3(1, 1, 1) + dots);
+ return m;
+}
+
float Basis::get_uniform_scale() const {
return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0;
}
@@ -931,6 +961,15 @@ void Basis::_set_diagonal(const Vector3 &p_diag) {
elements[2][2] = p_diag.z;
}
+Basis Basis::lerp(const Basis &p_to, const real_t &p_weight) const {
+ Basis b;
+ b.elements[0] = elements[0].lerp(p_to.elements[0], p_weight);
+ b.elements[1] = elements[1].lerp(p_to.elements[1], p_weight);
+ b.elements[2] = elements[2].lerp(p_to.elements[2], p_weight);
+
+ return b;
+}
+
Basis Basis::slerp(const Basis &p_to, const real_t &p_weight) const {
//consider scale
Quaternion from(*this);
diff --git a/core/math/basis.h b/core/math/basis.h
index 48367631d5..709f2cb3cf 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -123,6 +123,9 @@ public:
void scale_local(const Vector3 &p_scale);
Basis scaled_local(const Vector3 &p_scale) const;
+ void scale_orthogonal(const Vector3 &p_scale);
+ Basis scaled_orthogonal(const Vector3 &p_scale) const;
+
void make_scale_uniform();
float get_uniform_scale() const;
@@ -168,6 +171,7 @@ public:
bool is_diagonal() const;
bool is_rotation() const;
+ Basis lerp(const Basis &p_to, const real_t &p_weight) const;
Basis slerp(const Basis &p_to, const real_t &p_weight) const;
void rotate_sh(real_t *p_values);
@@ -233,6 +237,9 @@ public:
void orthonormalize();
Basis orthonormalized() const;
+ void orthogonalize();
+ Basis orthogonalized() const;
+
#ifdef MATH_CHECKS
bool is_symmetric() const;
#endif
diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp
index 1e0ee13504..e5374315e2 100644
--- a/core/math/transform_3d.cpp
+++ b/core/math/transform_3d.cpp
@@ -80,9 +80,11 @@ void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, con
origin = p_eye;
}
-Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const {
+Transform3D Transform3D::sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const {
/* not sure if very "efficient" but good enough? */
+ Transform3D interp;
+
Vector3 src_scale = basis.get_scale();
Quaternion src_rot = basis.get_rotation_quaternion();
Vector3 src_loc = origin;
@@ -91,13 +93,21 @@ Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t
Quaternion dst_rot = p_transform.basis.get_rotation_quaternion();
Vector3 dst_loc = p_transform.origin;
- Transform3D interp;
interp.basis.set_quaternion_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.lerp(dst_scale, p_c));
interp.origin = src_loc.lerp(dst_loc, p_c);
return interp;
}
+Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const {
+ Transform3D interp;
+
+ interp.basis = basis.lerp(p_transform.basis, p_c);
+ interp.origin = origin.lerp(p_transform.origin, p_c);
+
+ return interp;
+}
+
void Transform3D::scale(const Vector3 &p_scale) {
basis.scale(p_scale);
origin *= p_scale;
@@ -139,6 +149,16 @@ Transform3D Transform3D::orthonormalized() const {
return _copy;
}
+void Transform3D::orthogonalize() {
+ basis.orthogonalize();
+}
+
+Transform3D Transform3D::orthogonalized() const {
+ Transform3D _copy = *this;
+ _copy.orthogonalize();
+ return _copy;
+}
+
bool Transform3D::is_equal_approx(const Transform3D &p_transform) const {
return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin);
}
diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h
index 4356aa4e79..c0ef2ecfc1 100644
--- a/core/math/transform_3d.h
+++ b/core/math/transform_3d.h
@@ -69,6 +69,8 @@ public:
void orthonormalize();
Transform3D orthonormalized() const;
+ void orthogonalize();
+ Transform3D orthogonalized() const;
bool is_equal_approx(const Transform3D &p_transform) const;
bool operator==(const Transform3D &p_transform) const;
@@ -99,6 +101,7 @@ public:
void operator*=(const real_t p_val);
Transform3D operator*(const real_t p_val) const;
+ Transform3D sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const;
Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const;
_FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const {
diff --git a/core/object/script_language.h b/core/object/script_language.h
index 23c8667afd..4b18d9a5e8 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -227,6 +227,7 @@ struct ScriptCodeCompletionOption {
Color font_color;
RES icon;
Variant default_value;
+ Vector<Pair<int, int>> matches;
ScriptCodeCompletionOption() {}
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 506e968bf6..0032e8e4bc 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -346,7 +346,7 @@ String OS::get_model_name() const {
}
void OS::set_cmdline(const char *p_execpath, const List<String> &p_args) {
- _execpath = p_execpath;
+ _execpath = String::utf8(p_execpath);
_cmdline = p_args;
}
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index dff46f2042..fa8d26a72b 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -2120,7 +2120,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case BASIS: {
- r_dst = Transform3D(*a._data._basis).interpolate_with(Transform3D(*b._data._basis), c).basis;
+ r_dst = a._data._basis->lerp(*b._data._basis, c);
}
return;
case TRANSFORM3D: {
diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml
index 3830bfc60e..9c01921df1 100644
--- a/doc/classes/EditorExportPlugin.xml
+++ b/doc/classes/EditorExportPlugin.xml
@@ -96,12 +96,22 @@
Adds a static lib from the given [code]path[/code] to the iOS project.
</description>
</method>
+ <method name="add_osx_plugin_file">
+ <return type="void" />
+ <argument index="0" name="path" type="String" />
+ <description>
+ Adds file or directory matching [code]path[/code] to [code]PlugIns[/code] directory of macOS app bundle.
+ [b]Note:[/b] This is useful only for macOS exports.
+ </description>
+ </method>
<method name="add_shared_object">
<return type="void" />
<argument index="0" name="path" type="String" />
<argument index="1" name="tags" type="PackedStringArray" />
<description>
- Adds a shared object with the given [code]tags[/code] and destination [code]path[/code].
+ Adds a shared object or a directory containing only shared objects with the given [code]tags[/code] and destination [code]path[/code].
+ [b]Note:[/b] In case of macOS exports, those shared objects will be added to [code]Frameworks[/code] directory of app bundle.
+ In case of a directory code-sign will error if you place non code object in directory.
</description>
</method>
<method name="skip">
diff --git a/doc/classes/EditorSceneFormatImporter.xml b/doc/classes/EditorSceneFormatImporter.xml
index 5b5d6c4598..63f4cde5f3 100644
--- a/doc/classes/EditorSceneFormatImporter.xml
+++ b/doc/classes/EditorSceneFormatImporter.xml
@@ -37,7 +37,8 @@
<return type="Animation" />
<argument index="0" name="path" type="String" />
<argument index="1" name="flags" type="int" />
- <argument index="2" name="bake_fps" type="int" />
+ <argument index="2" name="options" type="Dictionary" />
+ <argument index="3" name="bake_fps" type="int" />
<description>
</description>
</method>
@@ -45,23 +46,8 @@
<return type="Object" />
<argument index="0" name="path" type="String" />
<argument index="1" name="flags" type="int" />
- <argument index="2" name="bake_fps" type="int" />
- <description>
- </description>
- </method>
- <method name="import_animation_from_other_importer">
- <return type="Animation" />
- <argument index="0" name="path" type="String" />
- <argument index="1" name="flags" type="int" />
- <argument index="2" name="bake_fps" type="int" />
- <description>
- </description>
- </method>
- <method name="import_scene_from_other_importer">
- <return type="Node" />
- <argument index="0" name="path" type="String" />
- <argument index="1" name="flags" type="int" />
- <argument index="2" name="bake_fps" type="int" />
+ <argument index="2" name="options" type="Dictionary" />
+ <argument index="3" name="bake_fps" type="int" />
<description>
</description>
</method>
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index b16d45b8ca..686854ffe8 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -363,7 +363,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the size of the array.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml
index 13d7440bb9..d875549319 100644
--- a/doc/classes/PackedColorArray.xml
+++ b/doc/classes/PackedColorArray.xml
@@ -126,7 +126,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the size of the array.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml
index 151014192f..6c77c4bee2 100644
--- a/doc/classes/PackedFloat32Array.xml
+++ b/doc/classes/PackedFloat32Array.xml
@@ -127,7 +127,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the size of the array.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml
index 963a02ace8..a8282c099a 100644
--- a/doc/classes/PackedFloat64Array.xml
+++ b/doc/classes/PackedFloat64Array.xml
@@ -127,7 +127,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the size of the array.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml
index cef113dee9..da26e93b96 100644
--- a/doc/classes/PackedInt32Array.xml
+++ b/doc/classes/PackedInt32Array.xml
@@ -127,7 +127,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the array size.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml
index 072df519c6..9ddf43a837 100644
--- a/doc/classes/PackedInt64Array.xml
+++ b/doc/classes/PackedInt64Array.xml
@@ -127,7 +127,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the array size.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml
index 0bded150a3..439d59dde7 100644
--- a/doc/classes/PackedStringArray.xml
+++ b/doc/classes/PackedStringArray.xml
@@ -127,7 +127,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the size of the array.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml
index 8e993c41ab..8c4f052016 100644
--- a/doc/classes/PackedVector2Array.xml
+++ b/doc/classes/PackedVector2Array.xml
@@ -127,7 +127,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the size of the array.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml
index df69e3cd4a..8229af984d 100644
--- a/doc/classes/PackedVector3Array.xml
+++ b/doc/classes/PackedVector3Array.xml
@@ -126,7 +126,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
- Returns the size of the array.
+ Returns the number of elements in the array.
</description>
</method>
<method name="slice" qualifiers="const">
diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml
index 8abd3f84b1..8a8d6e73f0 100644
--- a/doc/classes/RayCast3D.xml
+++ b/doc/classes/RayCast3D.xml
@@ -38,8 +38,7 @@
<method name="force_raycast_update">
<return type="void" />
<description>
- Updates the collision information for the ray.
- Use this method to update the collision information immediately instead of waiting for the next [code]_physics_process[/code] call, for example if the ray or its parent has changed state.
+ Updates the collision information for the ray. Use this method to update the collision information immediately instead of waiting for the next [code]_physics_process[/code] call, for example if the ray or its parent has changed state.
[b]Note:[/b] [member enabled] does not need to be [code]true[/code] for this to work.
</description>
</method>
diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml
index 805f056289..69d224ed24 100644
--- a/doc/classes/StreamPeer.xml
+++ b/doc/classes/StreamPeer.xml
@@ -70,7 +70,7 @@
<return type="String" />
<argument index="0" name="bytes" type="int" default="-1" />
<description>
- Gets a string with byte-length [code]bytes[/code] from the stream. If [code]bytes[/code] is negative (default) the length will be read from the stream using the reverse process of [method put_string].
+ Gets an ASCII string with byte-length [code]bytes[/code] from the stream. If [code]bytes[/code] is negative (default) the length will be read from the stream using the reverse process of [method put_string].
</description>
</method>
<method name="get_u16">
diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml
index e62cb9216e..e679a8cfeb 100644
--- a/doc/classes/Transform3D.xml
+++ b/doc/classes/Transform3D.xml
@@ -60,13 +60,13 @@
<argument index="0" name="xform" type="Transform3D" />
<argument index="1" name="weight" type="float" />
<description>
- Interpolates the transform to other Transform3D by weight amount (on the range of 0.0 to 1.0).
+ Returns a transform interpolated between this transform and another by a given [code]weight[/code] (on the range of 0.0 to 1.0).
</description>
</method>
<method name="inverse" qualifiers="const">
<return type="Transform3D" />
<description>
- Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use affine_inverse for transforms with scaling).
+ Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use [method affine_inverse] for transforms with scaling).
</description>
</method>
<method name="is_equal_approx" qualifiers="const">
@@ -88,7 +88,7 @@
<method name="orthonormalized" qualifiers="const">
<return type="Transform3D" />
<description>
- Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors.
+ Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors (scale of 1 or -1).
</description>
</method>
<method name="rotated" qualifiers="const">
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 7e773a0249..e7faa3ef0f 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -95,7 +95,7 @@
<method name="ceil" qualifiers="const">
<return type="Vector2" />
<description>
- Returns the vector with all components rounded up (towards positive infinity).
+ Returns a new vector with all components rounded up (towards positive infinity).
</description>
</method>
<method name="clamp" qualifiers="const">
@@ -158,7 +158,7 @@
<method name="floor" qualifiers="const">
<return type="Vector2" />
<description>
- Returns the vector with all components rounded down (towards negative infinity).
+ Returns a new vector with all components rounded down (towards negative infinity).
</description>
</method>
<method name="from_angle" qualifiers="static">
@@ -231,7 +231,7 @@
<argument index="0" name="to" type="Vector2" />
<argument index="1" name="delta" type="float" />
<description>
- Moves the vector toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value.
+ Returns a new vector moved toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value.
</description>
</method>
<method name="normalized" qualifiers="const">
@@ -264,7 +264,7 @@
<return type="Vector2" />
<argument index="0" name="b" type="Vector2" />
<description>
- Returns the vector projected onto the vector [code]b[/code].
+ Returns this vector projected onto the vector [code]b[/code].
</description>
</method>
<method name="reflect" qualifiers="const">
@@ -284,13 +284,13 @@
<method name="round" qualifiers="const">
<return type="Vector2" />
<description>
- Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
+ Returns a new vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
</description>
</method>
<method name="sign" qualifiers="const">
<return type="Vector2" />
<description>
- Returns the vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
+ Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
</description>
</method>
<method name="slerp" qualifiers="const">
diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml
index a9334d924f..74c9c23de0 100644
--- a/doc/classes/Vector2i.xml
+++ b/doc/classes/Vector2i.xml
@@ -53,7 +53,7 @@
<method name="aspect" qualifiers="const">
<return type="float" />
<description>
- Returns the ratio of [member x] to [member y].
+ Returns the aspect ratio of this vector, the ratio of [member x] to [member y].
</description>
</method>
<method name="clamp" qualifiers="const">
@@ -79,7 +79,7 @@
<method name="sign" qualifiers="const">
<return type="Vector2i" />
<description>
- Returns the vector with each component set to one or negative one, depending on the signs of the components.
+ Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
</description>
</method>
</methods>
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index da5e4f4f43..8d2ef0ecd9 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -96,7 +96,7 @@
<argument index="2" name="post_b" type="Vector3" />
<argument index="3" name="weight" type="float" />
<description>
- Performs a cubic interpolation between vectors [code]pre_a[/code], [code]a[/code], [code]b[/code], [code]post_b[/code] ([code]a[/code] is current), by the given amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation.
+ Performs a cubic interpolation between this vector and [code]b[/code] using [code]pre_a[/code] and [code]post_b[/code] as handles, and returns the result at position [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation.
</description>
</method>
<method name="direction_to" qualifiers="const">
@@ -201,7 +201,7 @@
<argument index="0" name="to" type="Vector3" />
<argument index="1" name="delta" type="float" />
<description>
- Moves this vector toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value.
+ Returns a new vector moved toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value.
</description>
</method>
<method name="normalized" qualifiers="const">
@@ -246,7 +246,7 @@
<return type="Vector3" />
<argument index="0" name="b" type="Vector3" />
<description>
- Returns this vector projected onto another vector [code]b[/code].
+ Returns this vector projected onto the vector [code]b[/code].
</description>
</method>
<method name="reflect" qualifiers="const">
@@ -267,13 +267,13 @@
<method name="round" qualifiers="const">
<return type="Vector3" />
<description>
- Returns this vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
+ Returns a new vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
</description>
</method>
<method name="sign" qualifiers="const">
<return type="Vector3" />
<description>
- Returns a vector with each component set to one or negative one, depending on the signs of this vector's components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
+ Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
</description>
</method>
<method name="signed_angle_to" qualifiers="const">
diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml
index 995f2796dd..b9ff711f44 100644
--- a/doc/classes/VisualShaderNodeCustom.xml
+++ b/doc/classes/VisualShaderNodeCustom.xml
@@ -25,7 +25,7 @@
</method>
<method name="_get_code" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="input_vars" type="PackedStringArray" />
+ <argument index="0" name="input_vars" type="String[]" />
<argument index="1" name="output_vars" type="String[]" />
<argument index="2" name="mode" type="int" enum="Shader.Mode" />
<argument index="3" name="type" type="int" enum="VisualShader.Type" />
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 9cf2b7a7eb..7884269103 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -283,9 +283,9 @@ Array AudioDriverALSA::get_device_list() {
if (name != nullptr && !strncmp(name, "plughw", 6)) {
if (desc) {
- list.push_back(String(name) + ";" + String(desc));
+ list.push_back(String::utf8(name) + ";" + String::utf8(desc));
} else {
- list.push_back(String(name));
+ list.push_back(String::utf8(name));
}
}
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 7364dbe2e7..e37a53fede 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -540,7 +540,7 @@ Array AudioDriverCoreAudio::_get_device_list(bool capture) {
ERR_FAIL_NULL_V_MSG(buffer, list, "Out of memory.");
if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) {
// Append the ID to the name in case we have devices with duplicate name
- list.push_back(String(buffer) + " (" + itos(audioDevices[i]) + ")");
+ list.push_back(String::utf8(buffer) + " (" + itos(audioDevices[i]) + ")");
}
memfree(buffer);
@@ -597,7 +597,7 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
char *buffer = (char *)memalloc(maxSize);
ERR_FAIL_NULL_MSG(buffer, "Out of memory.");
if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) {
- String name = String(buffer) + " (" + itos(audioDevices[i]) + ")";
+ String name = String::utf8(buffer) + " (" + itos(audioDevices[i]) + ")";
if (name == device) {
deviceId = audioDevices[i];
found = true;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index a1704e37a7..4669e56e20 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1548,7 +1548,9 @@ void CodeTextEditor::set_error_pos(int p_line, int p_column) {
void CodeTextEditor::goto_error() {
if (!error->get_text().is_empty()) {
- text_editor->unfold_line(error_line);
+ if (text_editor->get_line_count() != error_line) {
+ text_editor->unfold_line(error_line);
+ }
text_editor->set_caret_line(error_line);
text_editor->set_caret_column(error_column);
text_editor->center_viewport_to_caret();
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index 4d6b2e2750..1de67149c6 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -124,7 +124,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
char fname[16384];
unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String name = fname;
+ String name = String::utf8(fname);
files_sorted.insert(name);
ret = unzGoToNextFile(pkg);
@@ -303,7 +303,7 @@ void EditorAssetInstaller::ok_pressed() {
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String name = fname;
+ String name = String::utf8(fname);
if (status_map.has(name) && status_map[name]->is_checked(0)) {
String path = status_map[name]->get_metadata(0);
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index d681074bf5..014e27ae15 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -620,6 +620,14 @@ String EditorExportPlugin::get_ios_cpp_code() const {
return ios_cpp_code;
}
+void EditorExportPlugin::add_osx_plugin_file(const String &p_path) {
+ osx_plugin_files.push_back(p_path);
+}
+
+const Vector<String> &EditorExportPlugin::get_osx_plugin_files() const {
+ return osx_plugin_files;
+}
+
void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) {
ios_project_static_libs.push_back(p_path);
}
@@ -660,6 +668,7 @@ void EditorExportPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags);
ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file);
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code);
+ ClassDB::bind_method(D_METHOD("add_osx_plugin_file", "path"), &EditorExportPlugin::add_osx_plugin_file);
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);
GDVIRTUAL_BIND(_export_file, "path", "type", "features");
diff --git a/editor/editor_export.h b/editor/editor_export.h
index fd885ad313..3d46ae1996 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -308,6 +308,8 @@ class EditorExportPlugin : public RefCounted {
Vector<String> ios_bundle_files;
String ios_cpp_code;
+ Vector<String> osx_plugin_files;
+
_FORCE_INLINE_ void _clear() {
shared_objects.clear();
extra_files.clear();
@@ -321,6 +323,7 @@ class EditorExportPlugin : public RefCounted {
ios_plist_content = "";
ios_linker_flags = "";
ios_cpp_code = "";
+ osx_plugin_files.clear();
}
void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features);
@@ -341,6 +344,7 @@ protected:
void add_ios_linker_flags(const String &p_flags);
void add_ios_bundle_file(const String &p_path);
void add_ios_cpp_code(const String &p_code);
+ void add_osx_plugin_file(const String &p_path);
void skip();
@@ -361,6 +365,7 @@ public:
String get_ios_linker_flags() const;
Vector<String> get_ios_bundle_files() const;
String get_ios_cpp_code() const;
+ const Vector<String> &get_osx_plugin_files() const;
EditorExportPlugin();
};
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 827eb76db5..d556255a8f 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -273,8 +273,8 @@ void editor_register_fonts(Ref<Theme> p_theme) {
// Default font
MAKE_DEFAULT_FONT(df, String());
- p_theme->set_default_theme_font(df); // Default theme font
- p_theme->set_default_theme_font_size(default_font_size);
+ p_theme->set_default_font(df); // Default theme font
+ p_theme->set_default_font_size(default_font_size);
p_theme->set_font_size("main_size", "EditorFonts", default_font_size);
p_theme->set_font("main", "EditorFonts", df);
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index b20aee82e6..421d16313a 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -49,6 +49,7 @@ void EditorResourcePicker::_update_resource() {
if (edited_resource == RES()) {
assign_button->set_icon(Ref<Texture2D>());
assign_button->set_text(TTR("[empty]"));
+ assign_button->set_tooltip("");
} else {
assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object"));
@@ -56,14 +57,15 @@ void EditorResourcePicker::_update_resource() {
assign_button->set_text(edited_resource->get_name());
} else if (edited_resource->get_path().is_resource_file()) {
assign_button->set_text(edited_resource->get_path().get_file());
- assign_button->set_tooltip(edited_resource->get_path());
} else {
assign_button->set_text(edited_resource->get_class());
}
+ String resource_path;
if (edited_resource->get_path().is_resource_file()) {
- assign_button->set_tooltip(edited_resource->get_path());
+ resource_path = edited_resource->get_path() + "\n";
}
+ assign_button->set_tooltip(resource_path + TTR("Type:") + " " + edited_resource->get_class());
// Preview will override the above, so called at the end.
EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id());
@@ -514,12 +516,14 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, Set<String> *
}
if (p_with_convert) {
- if (base == "StandardMaterial3D") {
+ if (base == "BaseMaterial3D") {
p_vector->insert("Texture2D");
} else if (base == "ShaderMaterial") {
p_vector->insert("Shader");
} else if (base == "Font") {
p_vector->insert("FontData");
+ } else if (base == "Texture2D") {
+ p_vector->insert("Image");
}
}
}
@@ -636,26 +640,46 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
for (Set<String>::Element *E = allowed_types.front(); E; E = E->next()) {
String at = E->get().strip_edges();
- if (at == "StandardMaterial3D" && ClassDB::is_parent_class(dropped_resource->get_class(), "Texture2D")) {
- Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D);
+ if (at == "BaseMaterial3D" && ClassDB::is_parent_class(dropped_resource->get_class(), "Texture2D")) {
+ // Use existing resource if possible and only replace its data.
+ Ref<StandardMaterial3D> mat = edited_resource;
+ if (!mat.is_valid()) {
+ mat.instantiate();
+ }
mat->set_texture(StandardMaterial3D::TextureParam::TEXTURE_ALBEDO, dropped_resource);
dropped_resource = mat;
break;
}
if (at == "ShaderMaterial" && ClassDB::is_parent_class(dropped_resource->get_class(), "Shader")) {
- Ref<ShaderMaterial> mat = memnew(ShaderMaterial);
+ Ref<ShaderMaterial> mat = edited_resource;
+ if (!mat.is_valid()) {
+ mat.instantiate();
+ }
mat->set_shader(dropped_resource);
dropped_resource = mat;
break;
}
if (at == "Font" && ClassDB::is_parent_class(dropped_resource->get_class(), "FontData")) {
- Ref<Font> font = memnew(Font);
+ Ref<Font> font = edited_resource;
+ if (!font.is_valid()) {
+ font.instantiate();
+ }
font->add_data(dropped_resource);
dropped_resource = font;
break;
}
+
+ if (at == "Texture2D" && ClassDB::is_parent_class(dropped_resource->get_class(), "Image")) {
+ Ref<ImageTexture> texture = edited_resource;
+ if (!texture.is_valid()) {
+ texture.instantiate();
+ }
+ texture->create_from_image(dropped_resource);
+ dropped_resource = texture;
+ break;
+ }
}
}
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 7b60c4a384..a8a1dc37ab 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -294,7 +294,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Ref<Theme> theme = Ref<Theme>(memnew(Theme));
// Controls may rely on the scale for their internal drawing logic.
- theme->set_default_theme_base_scale(EDSCALE);
+ theme->set_default_base_scale(EDSCALE);
// Theme settings
Color accent_color = EDITOR_GET("interface/theme/accent_color");
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index f12a851388..8c34609e9c 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -396,7 +396,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String file = fname;
+ String file = String::utf8(fname);
if (file.ends_with("version.txt")) {
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -457,7 +457,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
char fname[16384];
unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String file_path(String(fname).simplify_path());
+ String file_path(String::utf8(fname).simplify_path());
String file = file_path.get_file();
@@ -698,7 +698,7 @@ Error ExportTemplateManager::install_android_template_from_file(const String &p_
char fpath[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fpath, 16384, nullptr, 0, nullptr, 0);
- String path = fpath;
+ String path = String::utf8(fpath);
String base_dir = path.get_base_dir();
if (!path.ends_with("/")) {
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index da45c15573..22b2bd1ed4 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -1755,7 +1755,7 @@ void EditorSceneFormatImporterCollada::get_extensions(List<String> *r_extensions
r_extensions->push_back("dae");
}
-Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
if (r_err) {
*r_err = OK;
}
@@ -1811,7 +1811,7 @@ Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint3
return state.scene;
}
-Ref<Animation> EditorSceneFormatImporterCollada::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorSceneFormatImporterCollada::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
ColladaImport state;
state.use_mesh_builtin_materials = false;
diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h
index 90bfcbf4f3..c32d785d1c 100644
--- a/editor/import/editor_import_collada.h
+++ b/editor/import/editor_import_collada.h
@@ -39,8 +39,8 @@ class EditorSceneFormatImporterCollada : public EditorSceneFormatImporter {
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr) override;
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr) override;
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override;
EditorSceneFormatImporterCollada();
};
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index f3f7b7ebd2..96645665aa 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -424,7 +424,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
return OK;
}
-Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
List<Ref<Mesh>> meshes;
Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, false, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps);
@@ -459,7 +459,7 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
return scene;
}
-Ref<Animation> EditorOBJImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorOBJImporter::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
return Ref<Animation>();
}
diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h
index 6f1acc26fa..d7e3f0209d 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -39,8 +39,8 @@ class EditorOBJImporter : public EditorSceneFormatImporter {
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override;
EditorOBJImporter();
};
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 889c0fbad2..e801cd4553 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -30,9 +30,9 @@
#include "resource_importer_scene.h"
+#include "core/error/error_macros.h"
#include "core/io/resource_saver.h"
#include "editor/editor_node.h"
-
#include "editor/import/scene_import_settings.h"
#include "scene/3d/area_3d.h"
#include "scene/3d/collision_shape_3d.h"
@@ -73,18 +73,26 @@ void EditorSceneFormatImporter::get_extensions(List<String> *r_extensions) const
ERR_FAIL();
}
-Node *EditorSceneFormatImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
- Object *ret;
- if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, p_bake_fps, ret)) {
+Node *EditorSceneFormatImporter::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+ Dictionary options_dict;
+ for (const KeyValue<StringName, Variant> &elem : p_options) {
+ options_dict[elem.key] = elem.value;
+ }
+ Object *ret = nullptr;
+ if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, options_dict, p_bake_fps, ret)) {
return Object::cast_to<Node>(ret);
}
ERR_FAIL_V(nullptr);
}
-Ref<Animation> EditorSceneFormatImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorSceneFormatImporter::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
+ Dictionary options_dict;
+ for (const KeyValue<StringName, Variant> &elem : p_options) {
+ options_dict[elem.key] = elem.value;
+ }
Ref<Animation> ret;
- if (GDVIRTUAL_CALL(_import_animation, p_path, p_flags, p_bake_fps, ret)) {
+ if (GDVIRTUAL_CALL(_import_animation, p_path, p_flags, options_dict, p_bake_fps, ret)) {
return ret;
}
@@ -101,25 +109,11 @@ Variant EditorSceneFormatImporter::get_option_visibility(const String &p_path, c
return ret;
}
-//for documenters, these functions are useful when an importer calls an external conversion helper (like, fbx2gltf),
-//and you want to load the resulting file
-
-Node *EditorSceneFormatImporter::import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
- return ResourceImporterScene::get_singleton()->import_scene_from_other_importer(this, p_path, p_flags, p_bake_fps);
-}
-
-Ref<Animation> EditorSceneFormatImporter::import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
- return ResourceImporterScene::get_singleton()->import_animation_from_other_importer(this, p_path, p_flags, p_bake_fps);
-}
-
void EditorSceneFormatImporter::_bind_methods() {
- ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneFormatImporter::import_scene_from_other_importer);
- ClassDB::bind_method(D_METHOD("import_animation_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneFormatImporter::import_animation_from_other_importer);
-
GDVIRTUAL_BIND(_get_import_flags);
GDVIRTUAL_BIND(_get_extensions);
- GDVIRTUAL_BIND(_import_scene, "path", "flags", "bake_fps");
- GDVIRTUAL_BIND(_import_animation, "path", "flags", "bake_fps");
+ GDVIRTUAL_BIND(_import_scene, "path", "flags", "options", "bake_fps");
+ GDVIRTUAL_BIND(_import_animation, "path", "flags", "options", "bake_fps");
GDVIRTUAL_BIND(_get_import_options, "path");
GDVIRTUAL_BIND(_get_option_visibility, "path", "option");
@@ -1473,64 +1467,6 @@ void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_
}
}
-Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneFormatImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
- Ref<EditorSceneFormatImporter> importer;
- String ext = p_path.get_extension().to_lower();
-
- for (Set<Ref<EditorSceneFormatImporter>>::Element *E = importers.front(); E; E = E->next()) {
- if (E->get().ptr() == p_exception) {
- continue;
- }
- List<String> extensions;
- E->get()->get_extensions(&extensions);
-
- for (const String &F : extensions) {
- if (F.to_lower() == ext) {
- importer = E->get();
- break;
- }
- }
-
- if (importer.is_valid()) {
- break;
- }
- }
-
- ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
-
- List<String> missing;
- Error err;
- return importer->import_scene(p_path, p_flags, p_bake_fps, &missing, &err);
-}
-
-Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(EditorSceneFormatImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
- Ref<EditorSceneFormatImporter> importer;
- String ext = p_path.get_extension().to_lower();
-
- for (Set<Ref<EditorSceneFormatImporter>>::Element *E = importers.front(); E; E = E->next()) {
- if (E->get().ptr() == p_exception) {
- continue;
- }
- List<String> extensions;
- E->get()->get_extensions(&extensions);
-
- for (const String &F : extensions) {
- if (F.to_lower() == ext) {
- importer = E->get();
- break;
- }
- }
-
- if (importer.is_valid()) {
- break;
- }
- }
-
- ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
-
- return importer->import_animation(p_path, p_flags, p_bake_fps);
-}
-
void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches) {
ImporterMeshInstance3D *src_mesh_node = Object::cast_to<ImporterMeshInstance3D>(p_node);
if (src_mesh_node) {
@@ -1886,7 +1822,7 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) {
ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
Error err = OK;
- Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, 15, nullptr, &err);
+ Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, Map<StringName, Variant>(), 15, nullptr, &err);
if (!scene || err != OK) {
return nullptr;
}
@@ -1944,7 +1880,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
Error err = OK;
List<String> missing_deps; // for now, not much will be done with this
- Node *scene = importer->import_scene(src_path, import_flags, fps, &missing_deps, &err);
+ Node *scene = importer->import_scene(src_path, import_flags, p_options, fps, &missing_deps, &err);
if (!scene || err != OK) {
return err;
}
@@ -2121,7 +2057,7 @@ void EditorSceneFormatImporterESCN::get_extensions(List<String> *r_extensions) c
r_extensions->push_back("escn");
}
-Node *EditorSceneFormatImporterESCN::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneFormatImporterESCN::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
Error error;
Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error);
ERR_FAIL_COND_V_MSG(!ps.is_valid(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'.");
@@ -2132,6 +2068,6 @@ Node *EditorSceneFormatImporterESCN::import_scene(const String &p_path, uint32_t
return scene;
}
-Ref<Animation> EditorSceneFormatImporterESCN::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorSceneFormatImporterESCN::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
ERR_FAIL_V(Ref<Animation>());
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 17ae0e797b..00d095eac1 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -31,7 +31,9 @@
#ifndef RESOURCEIMPORTERSCENE_H
#define RESOURCEIMPORTERSCENE_H
+#include "core/error/error_macros.h"
#include "core/io/resource_importer.h"
+#include "core/variant/dictionary.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/animation.h"
#include "scene/resources/mesh.h"
@@ -48,13 +50,13 @@ class EditorSceneFormatImporter : public RefCounted {
protected:
static void _bind_methods();
- Node *import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
- Ref<Animation> import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
+ Node *import_scene_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options, int p_bake_fps);
+ Ref<Animation> import_animation_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options, int p_bake_fps);
GDVIRTUAL0RC(int, _get_import_flags)
GDVIRTUAL0RC(Vector<String>, _get_extensions)
- GDVIRTUAL3R(Object *, _import_scene, String, uint32_t, uint32_t)
- GDVIRTUAL3R(Ref<Animation>, _import_animation, String, uint32_t, uint32_t)
+ GDVIRTUAL4R(Object *, _import_scene, String, uint32_t, Dictionary, uint32_t)
+ GDVIRTUAL4R(Ref<Animation>, _import_animation, String, uint32_t, Dictionary, uint32_t)
GDVIRTUAL1(_get_import_options, String)
GDVIRTUAL2RC(Variant, _get_option_visibility, String, String)
@@ -69,8 +71,8 @@ public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps);
virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options);
virtual Variant get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options);
@@ -270,9 +272,6 @@ public:
Node *pre_import(const String &p_source_file);
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
- Node *import_scene_from_other_importer(EditorSceneFormatImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
- Ref<Animation> import_animation_from_other_importer(EditorSceneFormatImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
-
virtual bool has_advanced_options() const override;
virtual void show_advanced_options(const String &p_path) override;
@@ -293,8 +292,8 @@ class EditorSceneFormatImporterESCN : public EditorSceneFormatImporter {
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override;
};
#include "scene/resources/box_shape_3d.h"
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index d6fd153665..089c37d7a6 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2097,8 +2097,16 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
if (k.is_valid() && k->is_pressed() && (tool == TOOL_SELECT || tool == TOOL_MOVE) &&
(k->get_keycode() == Key::UP || k->get_keycode() == Key::DOWN || k->get_keycode() == Key::LEFT || k->get_keycode() == Key::RIGHT)) {
if (!k->is_echo()) {
- // Start moving the canvas items with the keyboard
- drag_selection = _get_edited_canvas_items();
+ // Start moving the canvas items with the keyboard, if they are movable
+ List<CanvasItem *> selection = _get_edited_canvas_items();
+
+ drag_selection.clear();
+ for (CanvasItem *item : selection) {
+ if (_is_node_movable(item, true)) {
+ drag_selection.push_back(item);
+ }
+ }
+
drag_type = DRAG_KEY_MOVE;
drag_from = Vector2();
drag_to = Vector2();
@@ -5852,7 +5860,7 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path));
- editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene);
+ editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene, true);
editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_owner", editor->get_edited_scene());
editor_data->get_undo_redo().add_do_reference(instantiated_scene);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instantiated_scene);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index c86f6c02cb..957d1483bc 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -954,7 +954,7 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
real_t col_d = 1e20;
for (int i = 0; i < 3; i++) {
- const Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gizmo_scale * (GIZMO_ARROW_OFFSET + (GIZMO_ARROW_SIZE * 0.5));
+ const Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i).normalized() * gizmo_scale * (GIZMO_ARROW_OFFSET + (GIZMO_ARROW_SIZE * 0.5));
const real_t grabber_radius = gizmo_scale * GIZMO_ARROW_SIZE;
Vector3 r;
@@ -1058,7 +1058,7 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
float col_d = 1e20;
for (int i = 0; i < 3; i++) {
- const Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gizmo_scale * GIZMO_SCALE_OFFSET;
+ const Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i).normalized() * gizmo_scale * GIZMO_SCALE_OFFSET;
const real_t grabber_radius = gizmo_scale * GIZMO_ARROW_SIZE;
Vector3 r;
@@ -1138,68 +1138,62 @@ void Node3DEditorViewport::_transform_gizmo_apply(Node3D *p_node, const Transfor
}
}
-Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local) {
+Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local, bool p_orthogonal) {
switch (p_mode) {
case TRANSFORM_SCALE: {
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ p_motion.snap(Vector3(p_extra, p_extra, p_extra));
+ }
+ Transform3D s;
if (p_local) {
- Basis g = p_original.basis.orthonormalized();
- Vector3 local_motion = g.inverse().xform(p_motion);
-
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
- local_motion.snap(Vector3(p_extra, p_extra, p_extra));
- }
-
- Transform3D local_t;
- local_t.basis = p_original_local.basis.scaled_local(local_motion + Vector3(1, 1, 1));
- local_t.origin = p_original_local.origin;
- return local_t;
+ s.basis = p_original_local.basis.scaled_local(p_motion + Vector3(1, 1, 1));
+ s.origin = p_original_local.origin;
} else {
+ s.basis.scale(p_motion + Vector3(1, 1, 1));
Transform3D base = Transform3D(Basis(), _edit.center);
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
- p_motion.snap(Vector3(p_extra, p_extra, p_extra));
+ s = base * (s * (base.inverse() * p_original));
+
+ // Recalculate orthogonalized scale without moving origin.
+ if (p_orthogonal) {
+ s.basis = p_original_local.basis.scaled_orthogonal(p_motion + Vector3(1, 1, 1));
+ // The scaled_orthogonal() does not require orthogonal Basis,
+ // but it may make a bit skew by precision problems.
+ s.basis.orthogonalize();
}
-
- Transform3D global_t;
- global_t.basis.scale(p_motion + Vector3(1, 1, 1));
- return base * (global_t * (base.inverse() * p_original));
}
+
+ return s;
}
case TRANSFORM_TRANSLATE: {
- if (p_local) {
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
- Basis g = p_original.basis.orthonormalized();
- Vector3 local_motion = g.inverse().xform(p_motion);
- local_motion.snap(Vector3(p_extra, p_extra, p_extra));
-
- p_motion = g.xform(local_motion);
- }
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ p_motion.snap(Vector3(p_extra, p_extra, p_extra));
+ }
- } else {
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
- p_motion.snap(Vector3(p_extra, p_extra, p_extra));
- }
+ if (p_local) {
+ p_motion = p_original.basis.xform(p_motion);
}
// Apply translation
Transform3D t = p_original;
t.origin += p_motion;
+
return t;
}
case TRANSFORM_ROTATE: {
+ Transform3D r;
+
if (p_local) {
- Transform3D r;
Vector3 axis = p_original_local.basis.xform(p_motion);
r.basis = Basis(axis.normalized(), p_extra) * p_original_local.basis;
r.origin = p_original_local.origin;
- return r;
} else {
- Transform3D r;
Basis local = p_original.basis * p_original_local.basis.inverse();
Vector3 axis = local.xform_inv(p_motion);
r.basis = local * Basis(axis.normalized(), p_extra) * p_original_local.basis;
r.origin = Basis(p_motion, p_extra).xform(p_original.origin - _edit.center) + _edit.center;
- return r;
}
+
+ return r;
}
default: {
ERR_FAIL_V_MSG(Transform3D(), "Invalid mode in '_compute_transform'");
@@ -1480,6 +1474,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
_edit.original_mouse_pos = b->get_position();
_edit.snap = spatial_editor->is_snap_enabled();
_edit.mode = TRANSFORM_NONE;
+ _edit.original = spatial_editor->get_gizmo_transform(); // To prevent to break when flipping with scale.
bool can_select_gizmos = spatial_editor->get_single_selected_node();
@@ -1783,30 +1778,30 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
plane = Plane(_get_camera_normal(), _edit.center);
break;
case TRANSFORM_X_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
break;
case TRANSFORM_Y_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
break;
case TRANSFORM_Z_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized();
plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
break;
case TRANSFORM_YZ:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2) + spatial_editor->get_gizmo_transform().basis.get_axis(1);
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0), _edit.center);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
plane_mv = true;
break;
case TRANSFORM_XZ:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2) + spatial_editor->get_gizmo_transform().basis.get_axis(0);
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1), _edit.center);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
plane_mv = true;
break;
case TRANSFORM_XY:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0) + spatial_editor->get_gizmo_transform().basis.get_axis(1);
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2), _edit.center);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
plane_mv = true;
break;
}
@@ -1857,6 +1852,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
// This might not be necessary anymore after issue #288 is solved (in 4.0?).
set_message(TTR("Scaling: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
+ motion = _edit.original.basis.inverse().xform(motion);
List<Node *> &selection = editor_selection->get_selected_node_list();
for (Node *E : selection) {
@@ -1877,14 +1873,14 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (se->gizmo.is_valid()) {
for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
Transform3D xform = GE.value;
- Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords);
+ Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo.
if (!local_coords) {
new_xform = se->original.affine_inverse() * new_xform;
}
se->gizmo->set_subgizmo_transform(GE.key, new_xform);
}
} else {
- Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords);
+ Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
_transform_gizmo_apply(se->sp, new_xform, local_coords);
}
}
@@ -1904,27 +1900,27 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
plane = Plane(_get_camera_normal(), _edit.center);
break;
case TRANSFORM_X_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
break;
case TRANSFORM_Y_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
break;
case TRANSFORM_Z_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2);
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized();
plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
break;
case TRANSFORM_YZ:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0), _edit.center);
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
plane_mv = true;
break;
case TRANSFORM_XZ:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1), _edit.center);
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
plane_mv = true;
break;
case TRANSFORM_XY:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2), _edit.center);
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
plane_mv = true;
break;
}
@@ -1956,6 +1952,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
motion_snapped.snap(Vector3(snap, snap, snap));
set_message(TTR("Translating: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
+ motion = spatial_editor->get_gizmo_transform().basis.inverse().xform(motion);
List<Node *> &selection = editor_selection->get_selected_node_list();
for (Node *E : selection) {
@@ -1976,12 +1973,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (se->gizmo.is_valid()) {
for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
Transform3D xform = GE.value;
- Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords);
+ Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo.
new_xform = se->original.affine_inverse() * new_xform;
se->gizmo->set_subgizmo_transform(GE.key, new_xform);
}
} else {
- Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords);
+ Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
_transform_gizmo_apply(se->sp, new_xform, false);
}
}
@@ -2000,15 +1997,15 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
plane = Plane(_get_camera_normal(), _edit.center);
break;
case TRANSFORM_X_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0), _edit.center);
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
axis = Vector3(1, 0, 0);
break;
case TRANSFORM_Y_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1), _edit.center);
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
axis = Vector3(0, 1, 0);
break;
case TRANSFORM_Z_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2), _edit.center);
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
axis = Vector3(0, 0, 1);
break;
case TRANSFORM_YZ:
@@ -2063,14 +2060,14 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
Transform3D xform = GE.value;
- Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords);
+ Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords, true); // Force orthogonal with subgizmo.
if (!local_coords) {
new_xform = se->original.affine_inverse() * new_xform;
}
se->gizmo->set_subgizmo_transform(GE.key, new_xform);
}
} else {
- Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords);
+ Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
_transform_gizmo_apply(se->sp, new_xform, local_coords);
}
}
@@ -3676,8 +3673,6 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
subviewport_container->get_stretch_shrink();
Vector3 scale = Vector3(1, 1, 1) * gizmo_scale;
- xform.basis.scale(scale);
-
// if the determinant is zero, we should disable the gizmo from being rendered
// this prevents supplying bad values to the renderer and then having to filter it out again
if (xform.basis.determinant() == 0) {
@@ -3694,18 +3689,26 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
}
for (int i = 0; i < 3; i++) {
- RenderingServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform);
+ Transform3D axis_angle = Transform3D();
+ if (xform.basis.get_axis(i).normalized().dot(xform.basis.get_axis((i + 1) % 3).normalized()) < 1.0) {
+ axis_angle = axis_angle.looking_at(xform.basis.get_axis(i).normalized(), xform.basis.get_axis((i + 1) % 3).normalized());
+ }
+ axis_angle.basis.scale(scale);
+ axis_angle.origin = xform.origin;
+ RenderingServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], axis_angle);
RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE));
- RenderingServer::get_singleton()->instance_set_transform(move_plane_gizmo_instance[i], xform);
+ RenderingServer::get_singleton()->instance_set_transform(move_plane_gizmo_instance[i], axis_angle);
RenderingServer::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE));
- RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], xform);
+ RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], axis_angle);
RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE));
- RenderingServer::get_singleton()->instance_set_transform(scale_gizmo_instance[i], xform);
+ RenderingServer::get_singleton()->instance_set_transform(scale_gizmo_instance[i], axis_angle);
RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE));
- RenderingServer::get_singleton()->instance_set_transform(scale_plane_gizmo_instance[i], xform);
+ RenderingServer::get_singleton()->instance_set_transform(scale_plane_gizmo_instance[i], axis_angle);
RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE));
}
// Rotation white outline
+ xform.orthonormalize();
+ xform.basis.scale(scale);
RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[3], xform);
RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE));
}
@@ -4127,7 +4130,7 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path));
}
- editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene);
+ editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene, true);
editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_owner", editor->get_edited_scene());
editor_data->get_undo_redo().add_do_reference(instantiated_scene);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instantiated_scene);
@@ -4915,7 +4918,6 @@ void Node3DEditor::update_transform_gizmo() {
gizmo_center += xf.origin;
if (count == 0 && local_gizmo_coords) {
gizmo_basis = xf.basis;
- gizmo_basis.orthonormalize();
}
count++;
}
@@ -4940,7 +4942,6 @@ void Node3DEditor::update_transform_gizmo() {
gizmo_center += xf.origin;
if (count == 0 && local_gizmo_coords) {
gizmo_basis = xf.basis;
- gizmo_basis.orthonormalize();
}
count++;
}
@@ -5815,6 +5816,12 @@ void fragment() {
{
//move gizmo
+ // Inverted zxy.
+ Vector3 ivec = Vector3(0, 0, -1);
+ Vector3 nivec = Vector3(-1, -1, 0);
+ Vector3 ivec2 = Vector3(-1, 0, 0);
+ Vector3 ivec3 = Vector3(0, -1, 0);
+
for (int i = 0; i < 3; i++) {
Color col;
switch (i) {
@@ -5852,16 +5859,6 @@ void fragment() {
mat_hl->set_albedo(albedo);
gizmo_color_hl[i] = mat_hl;
- Vector3 ivec;
- ivec[i] = 1;
- Vector3 nivec;
- nivec[(i + 1) % 3] = 1;
- nivec[(i + 2) % 3] = 1;
- Vector3 ivec2;
- ivec2[(i + 1) % 3] = 1;
- Vector3 ivec3;
- ivec3[(i + 2) % 3] = 1;
-
//translate
{
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index eba3989f9d..8d42e88b53 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -399,7 +399,7 @@ private:
void _project_settings_changed();
- Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local);
+ Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local, bool p_orthogonal);
protected:
void _notification(int p_what);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 4b7380c83f..08e0f7ae30 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -204,7 +204,7 @@ private:
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- if (String(fname).ends_with("project.godot")) {
+ if (String::utf8(fname).ends_with("project.godot")) {
break;
}
@@ -524,7 +524,7 @@ private:
char fname[16384];
unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String name = fname;
+ String name = String::utf8(fname);
if (name.ends_with("project.godot")) {
zip_root = name.substr(0, name.rfind("project.godot"));
break;
@@ -544,7 +544,7 @@ private:
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String path = fname;
+ String path = String::utf8(fname);
if (path.is_empty() || path == zip_root || !zip_root.is_subsequence_of(path)) {
//
diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh
index b241f3da70..e66bc88bc0 100755
--- a/misc/scripts/file_format.sh
+++ b/misc/scripts/file_format.sh
@@ -20,6 +20,8 @@ while IFS= read -rd '' f; do
continue
elif [[ "$f" == *"sln" ]]; then
continue
+ elif [[ "$f" == *".bat" ]]; then
+ continue
elif [[ "$f" == *".out" ]]; then
# GDScript integration testing files.
continue
diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm
index 626cc3f285..391006bfc2 100644
--- a/modules/camera/camera_osx.mm
+++ b/modules/camera/camera_osx.mm
@@ -231,7 +231,7 @@ void CameraFeedOSX::set_device(AVCaptureDevice *p_device) {
// get some info
NSString *device_name = p_device.localizedName;
- name = device_name.UTF8String;
+ name = String::utf8(device_name.UTF8String);
position = CameraFeed::FEED_UNSPECIFIED;
if ([p_device position] == AVCaptureDevicePositionBack) {
position = CameraFeed::FEED_BACK;
diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp
index e03680010b..4cca907bf2 100644
--- a/modules/fbx/editor_scene_importer_fbx.cpp
+++ b/modules/fbx/editor_scene_importer_fbx.cpp
@@ -83,7 +83,7 @@ uint32_t EditorSceneFormatImporterFBX::get_import_flags() const {
return IMPORT_SCENE;
}
-Node3D *EditorSceneFormatImporterFBX::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps,
+Node3D *EditorSceneFormatImporterFBX::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps,
List<String> *r_missing_deps, Error *r_err) {
// done for performance when re-importing lots of files when testing importer in verbose only!
if (OS::get_singleton()->is_stdout_verbose()) {
@@ -1468,3 +1468,8 @@ void EditorSceneFormatImporterFBX::BuildDocumentNodes(
}
}
}
+Ref<Animation> EditorSceneFormatImporterFBX::import_animation(const String &p_path,
+ uint32_t p_flags, const Map<StringName, Variant> &p_options,
+ int p_bake_fps) {
+ return Ref<Animation>();
+}
diff --git a/modules/fbx/editor_scene_importer_fbx.h b/modules/fbx/editor_scene_importer_fbx.h
index a6ea8058a7..eebcb86409 100644
--- a/modules/fbx/editor_scene_importer_fbx.h
+++ b/modules/fbx/editor_scene_importer_fbx.h
@@ -127,7 +127,10 @@ public:
virtual void get_extensions(List<String> *r_extensions) const override;
virtual uint32_t get_import_flags() const override;
- virtual Node3D *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
+ virtual Node3D *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
+ virtual Ref<Animation> import_animation(const String &p_path,
+ uint32_t p_flags, const Map<StringName, Variant> &p_options,
+ int p_bake_fps) override;
};
#endif // TOOLS_ENABLED
diff --git a/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd
new file mode 100644
index 0000000000..27383b878d
--- /dev/null
+++ b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd
@@ -0,0 +1,41 @@
+# meta-description: Visual shader's node plugin template
+
+@tool
+extends _BASE_
+class_name VisualShaderNode_CLASS_
+
+func _get_name() -> String:
+ return "_CLASS_"
+
+func _get_category() -> String:
+ return ""
+
+func _get_description() -> String:
+ return ""
+
+func _get_return_icon_type() -> int:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_count() -> int:
+ return 0
+
+func _get_input_port_name(port: int) -> String:
+ return ""
+
+func _get_input_port_type(port: int) -> int:
+ return PORT_TYPE_SCALAR
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "result"
+
+func _get_output_port_type(port: int) -> int:
+ return PORT_TYPE_SCALAR
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ return ""
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ return output_vars[0] + " = 0.0;"
diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp
index 5845f84605..47772b8039 100644
--- a/modules/gdscript/tests/gdscript_test_runner.cpp
+++ b/modules/gdscript/tests/gdscript_test_runner.cpp
@@ -362,16 +362,16 @@ void GDScriptTest::error_handler(void *p_this, const char *p_function, const cha
}
builder.append("\n>> on function: ");
- builder.append(p_function);
+ builder.append(String::utf8(p_function));
builder.append("()\n>> ");
- builder.append(String(p_file).trim_prefix(self->base_dir));
+ builder.append(String::utf8(p_file).trim_prefix(self->base_dir));
builder.append("\n>> ");
builder.append(itos(p_line));
builder.append("\n>> ");
- builder.append(p_error);
+ builder.append(String::utf8(p_error));
if (strlen(p_explanation) > 0) {
builder.append("\n>> ");
- builder.append(p_explanation);
+ builder.append(String::utf8(p_explanation));
}
builder.append("\n");
diff --git a/modules/gltf/editor_scene_importer_gltf.cpp b/modules/gltf/editor_scene_importer_gltf.cpp
index b4d39041da..f063cc1e2b 100644
--- a/modules/gltf/editor_scene_importer_gltf.cpp
+++ b/modules/gltf/editor_scene_importer_gltf.cpp
@@ -48,7 +48,7 @@ void EditorSceneFormatImporterGLTF::get_extensions(List<String> *r_extensions) c
}
Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path,
- uint32_t p_flags, int p_bake_fps,
+ uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps,
List<String> *r_missing_deps,
Error *r_err) {
Ref<GLTFDocument> doc;
@@ -65,7 +65,7 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path,
}
Ref<Animation> EditorSceneFormatImporterGLTF::import_animation(const String &p_path,
- uint32_t p_flags,
+ uint32_t p_flags, const Map<StringName, Variant> &p_options,
int p_bake_fps) {
return Ref<Animation>();
}
diff --git a/modules/gltf/editor_scene_importer_gltf.h b/modules/gltf/editor_scene_importer_gltf.h
index dafd278f24..4410559b3d 100644
--- a/modules/gltf/editor_scene_importer_gltf.h
+++ b/modules/gltf/editor_scene_importer_gltf.h
@@ -47,9 +47,9 @@ class EditorSceneFormatImporterGLTF : public EditorSceneFormatImporter {
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
virtual Ref<Animation> import_animation(const String &p_path,
- uint32_t p_flags, int p_bake_fps) override;
+ uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override;
};
#endif // TOOLS_ENABLED
#endif // EDITOR_SCENE_IMPORTER_GLTF_H
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index 73315350ff..885817caf1 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -181,6 +181,9 @@
<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
The navigation layers the GridMap generates its navigable regions in.
</member>
+ <member name="physics_material" type="PhysicsMaterial" setter="set_physics_material" getter="get_physics_material">
+ Overrides the default friction and bounce physics properties for the whole [GridMap].
+ </member>
</members>
<signals>
<signal name="cell_size_changed">
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 3383daefea..a861efcbf4 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -34,6 +34,7 @@
#include "core/object/message_queue.h"
#include "scene/3d/light_3d.h"
#include "scene/resources/mesh_library.h"
+#include "scene/resources/physics_material.h"
#include "scene/resources/surface_tool.h"
#include "scene/scene_string_names.h"
#include "servers/navigation_server_3d.h"
@@ -181,6 +182,15 @@ void GridMap::set_collision_mask_value(int p_layer_number, bool p_value) {
set_collision_mask(mask);
}
+void GridMap::set_physics_material(Ref<PhysicsMaterial> p_material) {
+ physics_material = p_material;
+ _recreate_octant_data();
+}
+
+Ref<PhysicsMaterial> GridMap::get_physics_material() const {
+ return physics_material;
+}
+
bool GridMap::get_collision_mask_value(int p_layer_number) const {
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");
@@ -316,6 +326,10 @@ void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) {
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id());
PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer);
PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask);
+ if (physics_material.is_valid()) {
+ PhysicsServer3D::get_singleton()->body_set_param(g->static_body, PhysicsServer3D::BODY_PARAM_FRICTION, physics_material->get_friction());
+ PhysicsServer3D::get_singleton()->body_set_param(g->static_body, PhysicsServer3D::BODY_PARAM_BOUNCE, physics_material->get_bounce());
+ }
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_debugging_collisions_hint()) {
@@ -801,6 +815,9 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &GridMap::set_collision_layer_value);
ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &GridMap::get_collision_layer_value);
+ ClassDB::bind_method(D_METHOD("set_physics_material", "material"), &GridMap::set_physics_material);
+ ClassDB::bind_method(D_METHOD("get_physics_material"), &GridMap::get_physics_material);
+
ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation);
ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation);
@@ -850,6 +867,7 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_baked_meshes", "gen_lightmap_uv", "lightmap_uv_texel_size"), &GridMap::make_baked_meshes, DEFVAL(false), DEFVAL(0.1));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh_library", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"), "set_mesh_library", "get_mesh_library");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material", "get_physics_material");
ADD_GROUP("Cell", "cell_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cell_size"), "set_cell_size", "get_cell_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_octant_size", "get_octant_size");
diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h
index db3395b6fe..546b530148 100644
--- a/modules/gridmap/grid_map.h
+++ b/modules/gridmap/grid_map.h
@@ -38,6 +38,8 @@
//heh heh, godotsphir!! this shares no code and the design is completely different with previous projects i've done..
//should scale better with hardware that supports instancing
+class PhysicsMaterial;
+
class GridMap : public Node3D {
GDCLASS(GridMap, Node3D);
@@ -134,6 +136,7 @@ class GridMap : public Node3D {
uint32_t collision_layer = 1;
uint32_t collision_mask = 1;
+ Ref<PhysicsMaterial> physics_material;
bool bake_navigation = false;
uint32_t navigation_layers = 1;
@@ -223,6 +226,9 @@ public:
void set_collision_mask_value(int p_layer_number, bool p_value);
bool get_collision_mask_value(int p_layer_number) const;
+ void set_physics_material(Ref<PhysicsMaterial> p_material);
+ Ref<PhysicsMaterial> get_physics_material() const;
+
void set_bake_navigation(bool p_bake_navigation);
bool is_baking_navigation();
diff --git a/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs
new file mode 100644
index 0000000000..00fdc9968e
--- /dev/null
+++ b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs
@@ -0,0 +1,67 @@
+// meta-description: Visual shader's node plugin template
+
+using _BINDINGS_NAMESPACE_;
+using System;
+
+public partial class VisualShaderNode_CLASS_ : _BASE_
+{
+ public override string _GetName()
+ {
+ return "_CLASS_";
+ }
+
+ public override string _GetCategory()
+ {
+ return "";
+ }
+
+ public override string _GetDescription()
+ {
+ return "";
+ }
+
+ public override int _GetReturnIconType()
+ {
+ return 0;
+ }
+
+ public override int _GetInputPortCount()
+ {
+ return 0;
+ }
+
+ public override string _GetInputPortName(int port)
+ {
+ return "";
+ }
+
+ public override int _GetInputPortType(int port)
+ {
+ return 0;
+ }
+
+ public override int _GetOutputPortCount()
+ {
+ return 1;
+ }
+
+ public override string _GetOutputPortName(int port)
+ {
+ return "result";
+ }
+
+ public override int _GetOutputPortType(int port)
+ {
+ return 0;
+ }
+
+ public override string _GetGlobalCode(Shader.Mode mode)
+ {
+ return "";
+ }
+
+ public override string _GetCode(Godot.Collections.Array inputVars, Godot.Collections.Array outputVars, Shader.Mode mode, VisualShader.Type type)
+ {
+ return "";
+ }
+}
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 8997d31e1f..cbecde787f 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -2794,7 +2794,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
bool skip = false;
- String file = fname;
+ String file = String::utf8(fname);
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -2976,7 +2976,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
char extra[16384];
ret = unzGetCurrentFileInfo(tmp_unaligned, &info, fname, 16384, extra, 16384 - ZIP_ALIGNMENT, nullptr, 0);
- String file = fname;
+ String file = String::utf8(fname);
Vector<uint8_t> data;
data.resize(info.compressed_size);
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index 4a55ca1cbf..0ad68086a7 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -1484,7 +1484,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
char fname[16384];
ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String file = fname;
+ String file = String::utf8(fname);
print_line("READ: " + file);
Vector<uint8_t> data;
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index 91a2e6c228..da21ad0ace 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -65,7 +65,7 @@ String iOS::get_model() const {
NSString *platform = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
free(model);
const char *str = [platform UTF8String];
- return String(str != nullptr ? str : "");
+ return String::utf8(str != nullptr ? str : "");
}
String iOS::get_rate_url(int p_app_id) const {
diff --git a/platform/iphone/joypad_iphone.mm b/platform/iphone/joypad_iphone.mm
index 8c6e546515..2630b42da0 100644
--- a/platform/iphone/joypad_iphone.mm
+++ b/platform/iphone/joypad_iphone.mm
@@ -159,7 +159,7 @@ void JoypadIPhone::start_processing() {
};
// tell Godot about our new controller
- Input::get_singleton()->joy_connection_changed(joy_id, true, [controller.vendorName UTF8String]);
+ Input::get_singleton()->joy_connection_changed(joy_id, true, String::utf8([controller.vendorName UTF8String]));
// add it to our dictionary, this will retain our controllers
[self.connectedJoypads setObject:controller forKey:[NSNumber numberWithInt:joy_id]];
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index f0b06d841e..5d960ef80c 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -500,7 +500,7 @@ void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_c
return;
}
// Call input_text
- Variant event = String(p_text);
+ Variant event = String::utf8(p_text);
Variant *eventp = &event;
Variant ret;
Callable::CallError ce;
@@ -590,7 +590,7 @@ Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() {
// Clipboard
void DisplayServerJavaScript::update_clipboard_callback(const char *p_text) {
- get_singleton()->clipboard = p_text;
+ get_singleton()->clipboard = String::utf8(p_text);
}
void DisplayServerJavaScript::clipboard_set(const String &p_text) {
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index 2134deebcb..81ffae82bf 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -52,7 +52,7 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
char fname[16384];
unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String file = fname;
+ String file = String::utf8(fname);
// Skip service worker and offline page if not exporting pwa.
if (!pwa && (file == "godot.service.worker.js" || file == "godot.offline.html")) {
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index fe891e1c6a..b5f127bb16 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -431,7 +431,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
if (trash_path.is_empty()) {
char *dhome = getenv("XDG_DATA_HOME");
if (dhome) {
- trash_path = String(dhome) + "/Trash";
+ trash_path = String::utf8(dhome) + "/Trash";
}
}
@@ -439,7 +439,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
if (trash_path.is_empty()) {
char *home = getenv("HOME");
if (home) {
- trash_path = String(home) + "/.local/share/Trash";
+ trash_path = String::utf8(home) + "/.local/share/Trash";
}
}
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index 786a8f38d8..ab50144303 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -435,6 +435,101 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
return OK;
}
+Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path,
+ const String &p_ent_path, bool p_should_error_on_non_code) {
+#ifdef OSX_ENABLED
+ static Vector<String> extensions_to_sign;
+
+ if (extensions_to_sign.is_empty()) {
+ extensions_to_sign.push_back("dylib");
+ extensions_to_sign.push_back("framework");
+ }
+
+ Error dir_access_error;
+ DirAccessRef dir_access{ DirAccess::open(p_path, &dir_access_error) };
+
+ if (dir_access_error != OK) {
+ return dir_access_error;
+ }
+
+ dir_access->list_dir_begin();
+ String current_file{ dir_access->get_next() };
+ while (!current_file.is_empty()) {
+ String current_file_path{ p_path.plus_file(current_file) };
+
+ if (current_file == ".." || current_file == ".") {
+ current_file = dir_access->get_next();
+ continue;
+ }
+
+ if (extensions_to_sign.find(current_file.get_extension()) > -1) {
+ Error code_sign_error{ _code_sign(p_preset, current_file_path, p_ent_path) };
+ if (code_sign_error != OK) {
+ return code_sign_error;
+ }
+ } else if (dir_access->current_is_dir()) {
+ Error code_sign_error{ _code_sign_directory(p_preset, current_file_path, p_ent_path, p_should_error_on_non_code) };
+ if (code_sign_error != OK) {
+ return code_sign_error;
+ }
+ } else if (p_should_error_on_non_code) {
+ ERR_PRINT(vformat("Cannot sign file %s.", current_file));
+ return Error::FAILED;
+ }
+
+ current_file = dir_access->get_next();
+ }
+#endif
+
+ return OK;
+}
+
+Error EditorExportPlatformOSX::_copy_and_sign_files(DirAccessRef &dir_access, const String &p_src_path,
+ const String &p_in_app_path, bool p_sign_enabled,
+ const Ref<EditorExportPreset> &p_preset, const String &p_ent_path,
+ bool p_should_error_on_non_code_sign) {
+ Error err{ OK };
+ if (dir_access->dir_exists(p_src_path)) {
+#ifndef UNIX_ENABLED
+ WARN_PRINT("Relative symlinks are not supported, exported " + p_src_path.get_file() + " might be broken!");
+#endif
+ print_verbose("export framework: " + p_src_path + " -> " + p_in_app_path);
+ err = dir_access->make_dir_recursive(p_in_app_path);
+ if (err == OK) {
+ err = dir_access->copy_dir(p_src_path, p_in_app_path, -1, true);
+ }
+ } else {
+ print_verbose("export dylib: " + p_src_path + " -> " + p_in_app_path);
+ err = dir_access->copy(p_src_path, p_in_app_path);
+ }
+ if (err == OK && p_sign_enabled) {
+ if (dir_access->dir_exists(p_src_path) && p_src_path.get_extension().is_empty()) {
+ // If it is a directory, find and sign all dynamic libraries.
+ err = _code_sign_directory(p_preset, p_in_app_path, p_ent_path, p_should_error_on_non_code_sign);
+ } else {
+ err = _code_sign(p_preset, p_in_app_path, p_ent_path);
+ }
+ }
+ return err;
+}
+
+Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin,
+ const String &p_app_path_name, DirAccessRef &dir_access,
+ bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
+ const String &p_ent_path) {
+ Error error{ OK };
+ const Vector<String> &osx_plugins{ p_editor_export_plugin->get_osx_plugin_files() };
+ for (int i = 0; i < osx_plugins.size(); ++i) {
+ String src_path{ ProjectSettings::get_singleton()->globalize_path(osx_plugins[i]) };
+ String path_in_app{ p_app_path_name + "/Contents/PlugIns/" + src_path.get_file() };
+ error = _copy_and_sign_files(dir_access, src_path, path_in_app, p_sign_enabled, p_preset, p_ent_path, false);
+ if (error != OK) {
+ break;
+ }
+ }
+ return error;
+}
+
Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) {
List<String> args;
@@ -571,7 +666,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
char fname[16384];
ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, nullptr, 0, nullptr, 0);
- String file = fname;
+ String file = String::utf8(fname);
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -860,26 +955,22 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
FileAccess::set_unix_permissions(tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file(), 0755);
}
}
-
if (err == OK) {
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < shared_objects.size(); i++) {
String src_path = ProjectSettings::get_singleton()->globalize_path(shared_objects[i].path);
- if (da->dir_exists(src_path)) {
-#ifndef UNIX_ENABLED
- WARN_PRINT("Relative symlinks are not supported, exported " + src_path.get_file() + " might be broken!");
-#endif
- print_verbose("export framework: " + src_path + " -> " + tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
- err = da->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
- if (err == OK) {
- err = da->copy_dir(src_path, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(), -1, true);
- }
- } else {
- print_verbose("export dylib: " + src_path + " -> " + tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
- err = da->copy(src_path, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
+ String path_in_app{ tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file() };
+ err = _copy_and_sign_files(da, src_path, path_in_app, sign_enabled, p_preset, ent_path, true);
+ if (err != OK) {
+ break;
}
- if (err == OK && sign_enabled) {
- err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(), ent_path);
+ }
+
+ Vector<Ref<EditorExportPlugin>> export_plugins{ EditorExport::get_singleton()->get_export_plugins() };
+ for (int i = 0; i < export_plugins.size(); ++i) {
+ err = _export_osx_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path);
+ if (err != OK) {
+ break;
}
}
}
diff --git a/platform/osx/export/export_plugin.h b/platform/osx/export/export_plugin.h
index 036fa006ec..aa22ad6384 100644
--- a/platform/osx/export/export_plugin.h
+++ b/platform/osx/export/export_plugin.h
@@ -58,6 +58,13 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
Error _notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path);
+ Error _code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_should_error_on_non_code = true);
+ Error _copy_and_sign_files(DirAccessRef &dir_access, const String &p_src_path, const String &p_in_app_path,
+ bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path,
+ bool p_should_error_on_non_code_sign);
+ Error _export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name,
+ DirAccessRef &dir_access, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
+ const String &p_ent_path);
Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name);
void _zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index e57b503ddc..7d07b0076b 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -586,7 +586,7 @@ void OS_OSX::run() {
quit = true;
}
} @catch (NSException *exception) {
- ERR_PRINT("NSException: " + String([exception reason].UTF8String));
+ ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
}
};
@@ -602,7 +602,7 @@ Error OS_OSX::move_to_trash(const String &p_path) {
NSError *err;
if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) {
- ERR_PRINT("trashItemAtURL error: " + String(err.localizedDescription.UTF8String));
+ ERR_PRINT("trashItemAtURL error: " + String::utf8(err.localizedDescription.UTF8String));
return FAILED;
}
diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp
index f1f100bdd3..594495375a 100644
--- a/platform/uwp/export/export_plugin.cpp
+++ b/platform/uwp/export/export_plugin.cpp
@@ -325,7 +325,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
char fname[16834];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16834, nullptr, 0, nullptr, 0);
- String path = fname;
+ String path = String::utf8(fname);
if (path.ends_with("/")) {
// Ignore directories
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index cf966573ee..34f5830d8d 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -363,10 +363,10 @@ void NavigationRegion2D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
- NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
} else {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
- NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
@@ -402,7 +402,7 @@ void NavigationRegion2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
if (enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
- NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -411,7 +411,7 @@ void NavigationRegion2D::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
if (enabled) {
- NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
case NOTIFICATION_DRAW: {
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index e189b705d8..4426a646f4 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -84,6 +84,9 @@ void Node3D::_notify_dirty() {
}
void Node3D::_update_local_transform() const {
+ if (this->get_rotation_edit_mode() != ROTATION_EDIT_MODE_BASIS) {
+ data.local_transform = data.local_transform.orthogonalized();
+ }
data.local_transform.basis.set_euler_scale(data.rotation, data.scale);
data.dirty &= ~DIRTY_LOCAL;
@@ -321,6 +324,14 @@ void Node3D::set_rotation_edit_mode(RotationEditMode p_mode) {
return;
}
data.rotation_edit_mode = p_mode;
+
+ // Shearing is not allowed except in ROTATION_EDIT_MODE_BASIS.
+ data.dirty |= DIRTY_LOCAL;
+ _propagate_transform_changed(this);
+ if (data.notify_local_transform) {
+ notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ }
+
notify_property_list_changed();
}
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index eb3dafa2b1..398b909195 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -143,7 +143,6 @@ void CodeEdit::_notification(int p_what) {
code_completion_line_ofs = CLAMP(code_completion_current_selected - lines / 2, 0, code_completion_options_count - lines);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, code_completion_rect.position.y + (code_completion_current_selected - code_completion_line_ofs) * row_height), Size2(code_completion_rect.size.width, row_height)), code_completion_selected_color);
- draw_rect(Rect2(code_completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(code_completion_base_width, code_completion_rect.size.width - (icon_area_size.x + icon_hsep)), code_completion_rect.size.height)), code_completion_existing_color);
for (int i = 0; i < lines; i++) {
int l = code_completion_line_ofs + i;
@@ -177,6 +176,17 @@ void CodeEdit::_notification(int p_what) {
}
tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
}
+
+ Point2 match_pos = Point2(code_completion_rect.position.x + icon_area_size.x + icon_hsep, code_completion_rect.position.y + i * row_height);
+
+ for (int j = 0; j < code_completion_options[l].matches.size(); j++) {
+ Pair<int, int> match = code_completion_options[l].matches[j];
+ int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), font_size).width;
+ int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), font_size).width;
+
+ draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), code_completion_existing_color);
+ }
+
tl->draw(ci, title_pos, code_completion_options[l].font_color);
}
@@ -2808,6 +2818,8 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
code_completion_base = string_to_complete;
Vector<ScriptCodeCompletionOption> completion_options_casei;
+ Vector<ScriptCodeCompletionOption> completion_options_substr;
+ Vector<ScriptCodeCompletionOption> completion_options_substr_casei;
Vector<ScriptCodeCompletionOption> completion_options_subseq;
Vector<ScriptCodeCompletionOption> completion_options_subseq_casei;
@@ -2862,35 +2874,100 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
const char32_t *tgt = &option.display[0];
const char32_t *tgt_lower = &display_lower[0];
- const char32_t *ssq_last_tgt = nullptr;
- const char32_t *ssq_lower_last_tgt = nullptr;
+ const char32_t *sst = &string_to_complete[0];
+ const char32_t *sst_lower = &display_lower[0];
+
+ Vector<Pair<int, int>> ssq_matches;
+ int ssq_match_start = 0;
+ int ssq_match_len = 0;
+
+ Vector<Pair<int, int>> ssq_lower_matches;
+ int ssq_lower_match_start = 0;
+ int ssq_lower_match_len = 0;
+
+ int sst_start = -1;
+ int sst_lower_start = -1;
+
+ for (int i = 0; *tgt; tgt++, tgt_lower++, i++) {
+ // Check substring.
+ if (*sst == *tgt) {
+ sst++;
+ if (sst_start == -1) {
+ sst_start = i;
+ }
+ } else if (sst_start != -1 && *sst) {
+ sst = &string_to_complete[0];
+ sst_start = -1;
+ }
- for (; *tgt; tgt++, tgt_lower++) {
+ // Check subsequence.
if (*ssq == *tgt) {
ssq++;
- ssq_last_tgt = tgt;
+ if (ssq_match_len == 0) {
+ ssq_match_start = i;
+ }
+ ssq_match_len++;
+ } else if (ssq_match_len > 0) {
+ ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len));
+ ssq_match_len = 0;
}
+
+ // Check lower substring.
+ if (*sst_lower == *tgt) {
+ sst_lower++;
+ if (sst_lower_start == -1) {
+ sst_lower_start = i;
+ }
+ } else if (sst_lower_start != -1 && *sst_lower) {
+ sst_lower = &string_to_complete[0];
+ sst_lower_start = -1;
+ }
+
+ // Check lower subsequence.
if (*ssq_lower == *tgt_lower) {
ssq_lower++;
- ssq_lower_last_tgt = tgt;
+ if (ssq_lower_match_len == 0) {
+ ssq_lower_match_start = i;
+ }
+ ssq_lower_match_len++;
+ } else if (ssq_lower_match_len > 0) {
+ ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len));
+ ssq_lower_match_len = 0;
}
}
/* Matched the whole subsequence in s. */
- if (!*ssq) {
- /* Finished matching in the first s.length() characters. */
- if (ssq_last_tgt == &option.display[string_to_complete.length() - 1]) {
+ if (!*ssq) { // Matched the whole subsequence in s.
+ option.matches.clear();
+
+ if (sst_start == 0) { // Matched substring in beginning of s.
+ option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length()));
code_completion_options.push_back(option);
+ } else if (sst_start > 0) { // Matched substring in s.
+ option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length()));
+ completion_options_substr.push_back(option);
} else {
+ if (ssq_match_len > 0) {
+ ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len));
+ }
+ option.matches.append_array(ssq_matches);
completion_options_subseq.push_back(option);
}
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
- /* Matched the whole subsequence in s_lower. */
- } else if (!*ssq_lower) {
- /* Finished matching in the first s.length() characters. */
- if (ssq_lower_last_tgt == &option.display[string_to_complete.length() - 1]) {
+ } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower.
+ option.matches.clear();
+
+ if (sst_lower_start == 0) { // Matched substring in beginning of s_lower.
+ option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length()));
completion_options_casei.push_back(option);
+ } else if (sst_lower_start > 0) { // Matched substring in s_lower.
+ option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length()));
+ completion_options_substr_casei.push_back(option);
} else {
+ if (ssq_lower_match_len > 0) {
+ ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len));
+ }
+ option.matches.append_array(ssq_lower_matches);
completion_options_subseq_casei.push_back(option);
}
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index e4a5b265e3..69e6d74292 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1149,12 +1149,12 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- if (theme_owner && theme_owner->data.theme->has_default_theme_base_scale()) {
- return theme_owner->data.theme->get_default_theme_base_scale();
+ if (theme_owner && theme_owner->data.theme->has_default_base_scale()) {
+ return theme_owner->data.theme->get_default_base_scale();
}
- if (theme_owner_window && theme_owner_window->theme->has_default_theme_base_scale()) {
- return theme_owner_window->theme->get_default_theme_base_scale();
+ if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) {
+ return theme_owner_window->theme->get_default_base_scale();
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
@@ -1176,13 +1176,16 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_
// Secondly, check the project-defined Theme resource.
if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_theme_base_scale()) {
- return Theme::get_project_default()->get_default_theme_base_scale();
+ if (Theme::get_project_default()->has_default_base_scale()) {
+ return Theme::get_project_default()->get_default_base_scale();
}
}
// Lastly, fall back on the default Theme.
- return Theme::get_default()->get_default_theme_base_scale();
+ if (Theme::get_default()->has_default_base_scale()) {
+ return Theme::get_default()->get_default_base_scale();
+ }
+ return Theme::get_fallback_base_scale();
}
float Control::get_theme_default_base_scale() const {
@@ -1197,12 +1200,12 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- if (theme_owner && theme_owner->data.theme->has_default_theme_font()) {
- return theme_owner->data.theme->get_default_theme_font();
+ if (theme_owner && theme_owner->data.theme->has_default_font()) {
+ return theme_owner->data.theme->get_default_font();
}
- if (theme_owner_window && theme_owner_window->theme->has_default_theme_font()) {
- return theme_owner_window->theme->get_default_theme_font();
+ if (theme_owner_window && theme_owner_window->theme->has_default_font()) {
+ return theme_owner_window->theme->get_default_font();
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
@@ -1224,13 +1227,16 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th
// Secondly, check the project-defined Theme resource.
if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_theme_font()) {
- return Theme::get_project_default()->get_default_theme_font();
+ if (Theme::get_project_default()->has_default_font()) {
+ return Theme::get_project_default()->get_default_font();
}
}
// Lastly, fall back on the default Theme.
- return Theme::get_default()->get_default_theme_font();
+ if (Theme::get_default()->has_default_font()) {
+ return Theme::get_default()->get_default_font();
+ }
+ return Theme::get_fallback_font();
}
Ref<Font> Control::get_theme_default_font() const {
@@ -1245,12 +1251,12 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- if (theme_owner && theme_owner->data.theme->has_default_theme_font_size()) {
- return theme_owner->data.theme->get_default_theme_font_size();
+ if (theme_owner && theme_owner->data.theme->has_default_font_size()) {
+ return theme_owner->data.theme->get_default_font_size();
}
- if (theme_owner_window && theme_owner_window->theme->has_default_theme_font_size()) {
- return theme_owner_window->theme->get_default_theme_font_size();
+ if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) {
+ return theme_owner_window->theme->get_default_font_size();
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
@@ -1272,13 +1278,16 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the
// Secondly, check the project-defined Theme resource.
if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_theme_font_size()) {
- return Theme::get_project_default()->get_default_theme_font_size();
+ if (Theme::get_project_default()->has_default_font_size()) {
+ return Theme::get_project_default()->get_default_font_size();
}
}
// Lastly, fall back on the default Theme.
- return Theme::get_default()->get_default_theme_font_size();
+ if (Theme::get_default()->has_default_font_size()) {
+ return Theme::get_default()->get_default_font_size();
+ }
+ return Theme::get_fallback_font_size();
}
int Control::get_theme_default_font_size() const {
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index 6cc64e7ada..760144591e 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -54,6 +54,7 @@ Size2 SubViewportContainer::get_minimum_size() const {
void SubViewportContainer::set_stretch(bool p_enable) {
stretch = p_enable;
+ update_minimum_size();
queue_sort();
update();
}
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index bec01762d8..8b5883a742 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -229,15 +229,32 @@ void Node::_propagate_enter_tree() {
}
void Node::_propagate_after_exit_tree() {
+ // Clear owner if it was not part of the pruned branch
if (data.owner) {
- data.owner->data.owned.erase(data.OW);
- data.owner = nullptr;
+ bool found = false;
+ Node *parent = data.parent;
+
+ while (parent) {
+ if (parent == data.owner) {
+ found = true;
+ break;
+ }
+
+ parent = parent->data.parent;
+ }
+
+ if (!found) {
+ data.owner->data.owned.erase(data.OW);
+ data.owner = nullptr;
+ }
}
+
data.blocked++;
for (int i = data.children.size() - 1; i >= 0; i--) {
data.children[i]->_propagate_after_exit_tree();
}
data.blocked--;
+
emit_signal(SceneStringNames::get_singleton()->tree_exited);
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 0a9f98bb2f..3e63ba7869 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -48,6 +48,7 @@
#include "scene/gui/label.h"
#include "scene/gui/popup.h"
#include "scene/gui/popup_menu.h"
+#include "scene/gui/subviewport_container.h"
#include "scene/main/canvas_layer.h"
#include "scene/main/window.h"
#include "scene/resources/mesh.h"
@@ -3865,6 +3866,11 @@ Viewport::~Viewport() {
void SubViewport::set_size(const Size2i &p_size) {
_set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
+
+ SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
+ if (c) {
+ c->update_minimum_size();
+ }
}
Size2i SubViewport::get_size() const {
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 933021db75..e6b73b7780 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -1071,7 +1071,7 @@ void initialize_theme() {
if (theme.is_valid()) {
Theme::set_project_default(theme);
if (font.is_valid()) {
- Theme::set_default_font(font);
+ Theme::set_fallback_font(font);
}
} else {
ERR_PRINT("Error loading custom theme '" + theme_path + "'");
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 48d36ff2f7..549bd3ba12 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -1053,17 +1053,17 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
fill_default_theme(t, default_font, large_font, default_icon, default_style, default_scale);
Theme::set_default(t);
- Theme::set_default_base_scale(default_scale);
- Theme::set_default_icon(default_icon);
- Theme::set_default_style(default_style);
- Theme::set_default_font(default_font);
- Theme::set_default_font_size(default_font_size);
+ Theme::set_fallback_base_scale(default_scale);
+ Theme::set_fallback_icon(default_icon);
+ Theme::set_fallback_style(default_style);
+ Theme::set_fallback_font(default_font);
+ Theme::set_fallback_font_size(default_font_size);
}
void clear_default_theme() {
Theme::set_project_default(nullptr);
Theme::set_default(nullptr);
- Theme::set_default_icon(nullptr);
- Theme::set_default_style(nullptr);
- Theme::set_default_font(nullptr);
+ Theme::set_fallback_icon(nullptr);
+ Theme::set_fallback_style(nullptr);
+ Theme::set_fallback_font(nullptr);
}
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 186bbab689..8da287042e 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -36,11 +36,11 @@ Ref<Theme> Theme::default_theme;
Ref<Theme> Theme::project_default_theme;
// Universal default values, final fallback for every theme.
-float Theme::default_base_scale = 1.0;
-Ref<Texture2D> Theme::default_icon;
-Ref<StyleBox> Theme::default_style;
-Ref<Font> Theme::default_font;
-int Theme::default_font_size = 16;
+float Theme::fallback_base_scale = 1.0;
+Ref<Texture2D> Theme::fallback_icon;
+Ref<StyleBox> Theme::fallback_style;
+Ref<Font> Theme::fallback_font;
+int Theme::fallback_font_size = 16;
// Dynamic properties.
bool Theme::_set(const StringName &p_name, const Variant &p_value) {
@@ -220,87 +220,107 @@ void Theme::set_project_default(const Ref<Theme> &p_project_default) {
}
// Universal fallback values for theme item types.
-void Theme::set_default_base_scale(float p_base_scale) {
- default_base_scale = p_base_scale;
+void Theme::set_fallback_base_scale(float p_base_scale) {
+ fallback_base_scale = p_base_scale;
}
-void Theme::set_default_icon(const Ref<Texture2D> &p_icon) {
- default_icon = p_icon;
+void Theme::set_fallback_icon(const Ref<Texture2D> &p_icon) {
+ fallback_icon = p_icon;
}
-void Theme::set_default_style(const Ref<StyleBox> &p_style) {
- default_style = p_style;
+void Theme::set_fallback_style(const Ref<StyleBox> &p_style) {
+ fallback_style = p_style;
}
-void Theme::set_default_font(const Ref<Font> &p_font) {
- default_font = p_font;
+void Theme::set_fallback_font(const Ref<Font> &p_font) {
+ fallback_font = p_font;
}
-void Theme::set_default_font_size(int p_font_size) {
- default_font_size = p_font_size;
+void Theme::set_fallback_font_size(int p_font_size) {
+ fallback_font_size = p_font_size;
+}
+
+float Theme::get_fallback_base_scale() {
+ return fallback_base_scale;
+}
+
+Ref<Texture2D> Theme::get_fallback_icon() {
+ return fallback_icon;
+}
+
+Ref<StyleBox> Theme::get_fallback_style() {
+ return fallback_style;
+}
+
+Ref<Font> Theme::get_fallback_font() {
+ return fallback_font;
+}
+
+int Theme::get_fallback_font_size() {
+ return fallback_font_size;
}
// Fallback values for theme item types, configurable per theme.
-void Theme::set_default_theme_base_scale(float p_base_scale) {
- if (default_theme_base_scale == p_base_scale) {
+void Theme::set_default_base_scale(float p_base_scale) {
+ if (default_base_scale == p_base_scale) {
return;
}
- default_theme_base_scale = p_base_scale;
+ default_base_scale = p_base_scale;
_emit_theme_changed();
}
-float Theme::get_default_theme_base_scale() const {
- return default_theme_base_scale;
+float Theme::get_default_base_scale() const {
+ return default_base_scale;
}
-bool Theme::has_default_theme_base_scale() const {
- return default_theme_base_scale > 0.0;
+bool Theme::has_default_base_scale() const {
+ return default_base_scale > 0.0;
}
-void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
- if (default_theme_font == p_default_font) {
+void Theme::set_default_font(const Ref<Font> &p_default_font) {
+ if (default_font == p_default_font) {
return;
}
- if (default_theme_font.is_valid()) {
- default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
+ if (default_font.is_valid()) {
+ default_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
- default_theme_font = p_default_font;
+ default_font = p_default_font;
- if (default_theme_font.is_valid()) {
- default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED);
+ if (default_font.is_valid()) {
+ default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED);
}
_emit_theme_changed();
}
-Ref<Font> Theme::get_default_theme_font() const {
- return default_theme_font;
+Ref<Font> Theme::get_default_font() const {
+ return default_font;
}
-bool Theme::has_default_theme_font() const {
- return default_theme_font.is_valid();
+bool Theme::has_default_font() const {
+ return default_font.is_valid();
}
-void Theme::set_default_theme_font_size(int p_font_size) {
- if (default_theme_font_size == p_font_size) {
+void Theme::set_default_font_size(int p_font_size) {
+ if (default_font_size == p_font_size) {
return;
}
- default_theme_font_size = p_font_size;
+ default_font_size = p_font_size;
_emit_theme_changed();
}
-int Theme::get_default_theme_font_size() const {
- return default_theme_font_size;
+int Theme::get_default_font_size() const {
+ return default_font_size;
}
-bool Theme::has_default_theme_font_size() const {
- return default_theme_font_size > 0;
+bool Theme::has_default_font_size() const {
+ return default_font_size > 0;
}
// Icons.
@@ -324,7 +344,7 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_the
if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) {
return icon_map[p_theme_type][p_name];
} else {
- return default_icon;
+ return fallback_icon;
}
}
@@ -411,7 +431,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_
if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) {
return style_map[p_theme_type][p_name];
} else {
- return default_style;
+ return fallback_style;
}
}
@@ -497,15 +517,15 @@ void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, c
Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_type) const {
if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) {
return font_map[p_theme_type][p_name];
- } else if (has_default_theme_font()) {
- return default_theme_font;
- } else {
+ } else if (has_default_font()) {
return default_font;
+ } else {
+ return fallback_font;
}
}
bool Theme::has_font(const StringName &p_name, const StringName &p_theme_type) const {
- return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_theme_font());
+ return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_font());
}
bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const {
@@ -577,15 +597,15 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_ty
int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const {
if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) {
return font_size_map[p_theme_type][p_name];
- } else if (has_default_theme_font_size()) {
- return default_theme_font_size;
- } else {
+ } else if (has_default_font_size()) {
return default_font_size;
+ } else {
+ return fallback_font_size;
}
}
bool Theme::has_font_size(const StringName &p_name, const StringName &p_theme_type) const {
- return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_theme_font_size());
+ return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_font_size());
}
bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const {
@@ -1622,17 +1642,17 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_constant_list", "theme_type"), &Theme::_get_constant_list);
ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list);
- ClassDB::bind_method(D_METHOD("set_default_base_scale", "font_size"), &Theme::set_default_theme_base_scale);
- ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_theme_base_scale);
- ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_theme_base_scale);
+ ClassDB::bind_method(D_METHOD("set_default_base_scale", "base_scale"), &Theme::set_default_base_scale);
+ ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_base_scale);
+ ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_base_scale);
- ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_theme_font);
- ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_theme_font);
- ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_theme_font);
+ ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_font);
+ ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_font);
+ ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_font);
- ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_theme_font_size);
- ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_theme_font_size);
- ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_theme_font_size);
+ ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_font_size);
+ ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_font_size);
+ ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_font_size);
ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "theme_type", "value"), &Theme::set_theme_item);
ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "theme_type"), &Theme::get_theme_item);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 2e0a645005..822743a1fe 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -101,16 +101,16 @@ protected:
static Ref<Theme> project_default_theme;
// Universal default values, final fallback for every theme.
- static float default_base_scale;
- static Ref<Texture2D> default_icon;
- static Ref<StyleBox> default_style;
- static Ref<Font> default_font;
- static int default_font_size;
+ static float fallback_base_scale;
+ static Ref<Texture2D> fallback_icon;
+ static Ref<StyleBox> fallback_style;
+ static Ref<Font> fallback_font;
+ static int fallback_font_size;
// Default values configurable for each individual theme.
- float default_theme_base_scale = 0.0;
- Ref<Font> default_theme_font;
- int default_theme_font_size = -1;
+ float default_base_scale = 0.0;
+ Ref<Font> default_font;
+ int default_font_size = -1;
static void _bind_methods();
@@ -126,23 +126,29 @@ public:
static Ref<Theme> get_project_default();
static void set_project_default(const Ref<Theme> &p_project_default);
- static void set_default_base_scale(float p_base_scale);
- static void set_default_icon(const Ref<Texture2D> &p_icon);
- static void set_default_style(const Ref<StyleBox> &p_style);
- static void set_default_font(const Ref<Font> &p_font);
- static void set_default_font_size(int p_font_size);
-
- void set_default_theme_base_scale(float p_base_scale);
- float get_default_theme_base_scale() const;
- bool has_default_theme_base_scale() const;
-
- void set_default_theme_font(const Ref<Font> &p_default_font);
- Ref<Font> get_default_theme_font() const;
- bool has_default_theme_font() const;
-
- void set_default_theme_font_size(int p_font_size);
- int get_default_theme_font_size() const;
- bool has_default_theme_font_size() const;
+ static void set_fallback_base_scale(float p_base_scale);
+ static void set_fallback_icon(const Ref<Texture2D> &p_icon);
+ static void set_fallback_style(const Ref<StyleBox> &p_style);
+ static void set_fallback_font(const Ref<Font> &p_font);
+ static void set_fallback_font_size(int p_font_size);
+
+ static float get_fallback_base_scale();
+ static Ref<Texture2D> get_fallback_icon();
+ static Ref<StyleBox> get_fallback_style();
+ static Ref<Font> get_fallback_font();
+ static int get_fallback_font_size();
+
+ void set_default_base_scale(float p_base_scale);
+ float get_default_base_scale() const;
+ bool has_default_base_scale() const;
+
+ void set_default_font(const Ref<Font> &p_default_font);
+ Ref<Font> get_default_font() const;
+ bool has_default_font() const;
+
+ void set_default_font_size(int p_font_size);
+ int get_default_font_size() const;
+ bool has_default_font_size() const;
void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon);
Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index ed34c906a1..57b73c1234 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -349,11 +349,11 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
ERR_FAIL_COND_V(!GDVIRTUAL_IS_OVERRIDDEN(_get_code), "");
- Vector<String> input_vars;
+ TypedArray<String> input_vars;
for (int i = 0; i < get_input_port_count(); i++) {
input_vars.push_back(p_input_vars[i]);
}
- Array output_vars;
+ TypedArray<String> output_vars;
for (int i = 0; i < get_output_port_count(); i++) {
output_vars.push_back(p_output_vars[i]);
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index c8b577088d..066c18e3bc 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -326,7 +326,7 @@ protected:
GDVIRTUAL0RC(int, _get_output_port_count)
GDVIRTUAL1RC(int, _get_output_port_type, int)
GDVIRTUAL1RC(String, _get_output_port_name, int)
- GDVIRTUAL4RC(String, _get_code, Vector<String>, TypedArray<String>, Shader::Mode, VisualShader::Type)
+ GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type)
GDVIRTUAL1RC(String, _get_global_code, Shader::Mode)
GDVIRTUAL0RC(bool, _is_highend)
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index c4c10ebf3b..53190d7681 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -204,7 +204,7 @@ void NavigationServer2D::_bind_methods() {
NavigationServer2D::NavigationServer2D() {
singleton = this;
ERR_FAIL_COND_MSG(!NavigationServer3D::get_singleton(), "The Navigation3D singleton should be initialized before the 2D one.");
- NavigationServer3D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationServer2D::_emit_map_changed));
+ NavigationServer3D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationServer2D::_emit_map_changed));
}
NavigationServer2D::~NavigationServer2D() {
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index 8ab479b8fd..2dd718e09c 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -52,7 +52,7 @@ protected:
public:
/// Thread safe, can be used across many threads.
- static NavigationServer2D *get_singleton() { return singleton; }
+ static const NavigationServer2D *get_singleton() { return singleton; }
/// MUST be used in single thread!
static NavigationServer2D *get_singleton_mut() { return singleton; }
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index 03c75369a6..d78e58bea0 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -84,7 +84,7 @@ void NavigationServer3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map")));
}
-NavigationServer3D *NavigationServer3D::get_singleton() {
+const NavigationServer3D *NavigationServer3D::get_singleton() {
return singleton;
}
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index c70d87ec16..f711e4e0e5 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -55,7 +55,7 @@ protected:
public:
/// Thread safe, can be used across many threads.
- static NavigationServer3D *get_singleton();
+ static const NavigationServer3D *get_singleton();
/// MUST be used in single thread!
static NavigationServer3D *get_singleton_mut();