summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/extension/extension_api_dump.cpp7
-rw-r--r--core/math/quaternion.cpp5
-rw-r--r--core/object/script_language_extension.cpp1
-rw-r--r--core/os/keyboard.h44
-rw-r--r--doc/classes/ImageTexture.xml6
-rw-r--r--doc/classes/ScriptExtension.xml6
-rw-r--r--editor/animation_track_editor.cpp276
-rw-r--r--editor/animation_track_editor.h16
-rw-r--r--editor/editor_themes.cpp12
-rw-r--r--editor/editor_themes.h2
-rw-r--r--editor/icons/CurveIn.svg2
-rw-r--r--editor/icons/CurveInOut.svg2
-rw-r--r--editor/icons/CurveLinear.svg2
-rw-r--r--editor/icons/CurveOut.svg2
-rw-r--r--editor/icons/CurveOutIn.svg2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp21
-rw-r--r--editor/project_manager.cpp12
-rw-r--r--modules/gltf/register_types.cpp25
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs6
-rw-r--r--modules/mono/glue/callable_glue.cpp79
-rw-r--r--platform/android/dir_access_jandroid.cpp14
-rw-r--r--platform/android/dir_access_jandroid.h1
-rw-r--r--scene/animation/tween.cpp8
-rw-r--r--scene/gui/rich_text_label.cpp30
-rw-r--r--scene/gui/rich_text_label.h4
-rw-r--r--scene/gui/split_container.cpp5
-rw-r--r--scene/resources/skeleton_modification_3d_ccdik.h6
-rw-r--r--scene/resources/skeleton_modification_3d_fabrik.h6
-rw-r--r--scene/resources/skeleton_modification_3d_jiggle.h6
-rw-r--r--scene/resources/skeleton_modification_3d_lookat.h6
-rw-r--r--scene/resources/skeleton_modification_3d_stackholder.h6
-rw-r--r--scene/resources/skeleton_modification_3d_twoboneik.h6
-rw-r--r--servers/rendering/renderer_viewport.cpp52
-rw-r--r--servers/rendering/renderer_viewport.h15
-rw-r--r--thirdparty/README.md1
-rw-r--r--thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp37
-rw-r--r--thirdparty/glslang/glslang/OSDependent/osinclude.h2
-rw-r--r--thirdparty/glslang/patches/unused_cleanup.diff61
38 files changed, 561 insertions, 233 deletions
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 7023d4aa9b..5cf951a93c 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -91,6 +91,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
}
const uint32_t vec3_elems = 3;
+ const uint32_t vec4_elems = 4;
const uint32_t ptrsize_32 = 4;
const uint32_t ptrsize_64 = 8;
static const char *build_config_name[4] = { "float_32", "float_64", "double_32", "double_64" };
@@ -141,7 +142,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
{ Variant::AABB, (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(double), (vec3_elems * 2) * sizeof(double) },
{ Variant::BASIS, (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(double), (vec3_elems * 3) * sizeof(double) },
{ Variant::TRANSFORM3D, (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(double), (vec3_elems * 4) * sizeof(double) },
- { Variant::PROJECTION, 4 * 4 * sizeof(float), 4 * 4 * sizeof(float), 4 * 4 * sizeof(double), 4 * 4 * sizeof(double) },
+ { Variant::PROJECTION, (vec4_elems * 4) * sizeof(float), (vec4_elems * 4) * sizeof(float), (vec4_elems * 4) * sizeof(double), (vec4_elems * 4) * sizeof(double) },
{ Variant::COLOR, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float) },
{ Variant::STRING_NAME, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
{ Variant::NODE_PATH, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
@@ -287,6 +288,10 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
{ Variant::BASIS, "z", vec3_elems * 2 * sizeof(float), vec3_elems * 2 * sizeof(float), vec3_elems * 2 * sizeof(double), vec3_elems * 2 * sizeof(double) },
{ Variant::TRANSFORM3D, "basis", 0, 0, 0, 0 },
{ Variant::TRANSFORM3D, "origin", (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(double), (vec3_elems * 3) * sizeof(double) },
+ { Variant::PROJECTION, "x", 0, 0, 0, 0 },
+ { Variant::PROJECTION, "y", vec4_elems * sizeof(float), vec4_elems * sizeof(float), vec4_elems * sizeof(double), vec4_elems * sizeof(double) },
+ { Variant::PROJECTION, "z", vec4_elems * 2 * sizeof(float), vec4_elems * 2 * sizeof(float), vec4_elems * 2 * sizeof(double), vec4_elems * 2 * sizeof(double) },
+ { Variant::PROJECTION, "w", vec4_elems * 3 * sizeof(float), vec4_elems * 3 * sizeof(float), vec4_elems * 3 * sizeof(double), vec4_elems * 3 * sizeof(double) },
{ Variant::COLOR, "r", 0, 0, 0, 0 },
{ Variant::COLOR, "g", sizeof(float), sizeof(float), sizeof(float), sizeof(float) },
{ Variant::COLOR, "b", 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(float) },
diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp
index 36358f6feb..c836a82e37 100644
--- a/core/math/quaternion.cpp
+++ b/core/math/quaternion.cpp
@@ -112,10 +112,11 @@ Quaternion Quaternion::exp() const {
Quaternion src = *this;
Vector3 src_v = Vector3(src.x, src.y, src.z);
real_t theta = src_v.length();
- if (theta < CMP_EPSILON) {
+ src_v = src_v.normalized();
+ if (theta < CMP_EPSILON || !src_v.is_normalized()) {
return Quaternion(0, 0, 0, 1);
}
- return Quaternion(src_v.normalized(), theta);
+ return Quaternion(src_v, theta);
}
Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) const {
diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp
index 9de784ea7f..78e9038b66 100644
--- a/core/object/script_language_extension.cpp
+++ b/core/object/script_language_extension.cpp
@@ -62,6 +62,7 @@ void ScriptExtension::_bind_methods() {
GDVIRTUAL_BIND(_has_script_signal, "signal");
GDVIRTUAL_BIND(_get_script_signal_list);
+ GDVIRTUAL_BIND(_has_property_default_value, "property");
GDVIRTUAL_BIND(_get_property_default_value, "property");
GDVIRTUAL_BIND(_update_exports);
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 517a53e505..29418049cb 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -329,67 +329,71 @@ enum class KeyModifierMask {
// To avoid having unnecessary operators, only define the ones that are needed.
-inline Key operator-(uint32_t a, Key b) {
+constexpr Key operator-(uint32_t a, Key b) {
return (Key)(a - (uint32_t)b);
}
-inline Key &operator-=(Key &a, int b) {
- return (Key &)((int &)a -= b);
+constexpr Key &operator-=(Key &a, int b) {
+ a = static_cast<Key>(static_cast<int>(a) - static_cast<int>(b));
+ return a;
}
-inline Key operator+(Key a, int b) {
+constexpr Key operator+(Key a, int b) {
return (Key)((int)a + (int)b);
}
-inline Key operator+(Key a, Key b) {
+constexpr Key operator+(Key a, Key b) {
return (Key)((int)a + (int)b);
}
-inline Key operator-(Key a, Key b) {
+constexpr Key operator-(Key a, Key b) {
return (Key)((int)a - (int)b);
}
-inline Key operator&(Key a, Key b) {
+constexpr Key operator&(Key a, Key b) {
return (Key)((int)a & (int)b);
}
-inline Key operator|(Key a, Key b) {
+constexpr Key operator|(Key a, Key b) {
return (Key)((int)a | (int)b);
}
-inline Key &operator|=(Key &a, Key b) {
- return (Key &)((int &)a |= (int)b);
+constexpr Key &operator|=(Key &a, Key b) {
+ a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b));
+ return a;
}
-inline Key &operator|=(Key &a, KeyModifierMask b) {
- return (Key &)((int &)a |= (int)b);
+constexpr Key &operator|=(Key &a, KeyModifierMask b) {
+ a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b));
+ return a;
}
-inline Key &operator&=(Key &a, KeyModifierMask b) {
- return (Key &)((int &)a &= (int)b);
+constexpr Key &operator&=(Key &a, KeyModifierMask b) {
+ a = static_cast<Key>(static_cast<int>(a) & static_cast<int>(b));
+ return a;
}
-inline Key operator|(Key a, KeyModifierMask b) {
+constexpr Key operator|(Key a, KeyModifierMask b) {
return (Key)((int)a | (int)b);
}
-inline Key operator&(Key a, KeyModifierMask b) {
+constexpr Key operator&(Key a, KeyModifierMask b) {
return (Key)((int)a & (int)b);
}
-inline Key operator+(KeyModifierMask a, Key b) {
+constexpr Key operator+(KeyModifierMask a, Key b) {
return (Key)((int)a + (int)b);
}
-inline Key operator|(KeyModifierMask a, Key b) {
+constexpr Key operator|(KeyModifierMask a, Key b) {
return (Key)((int)a | (int)b);
}
-inline KeyModifierMask operator+(KeyModifierMask a, KeyModifierMask b) {
+constexpr KeyModifierMask operator+(KeyModifierMask a, KeyModifierMask b) {
return (KeyModifierMask)((int)a + (int)b);
}
-inline KeyModifierMask operator|(KeyModifierMask a, KeyModifierMask b) {
+constexpr KeyModifierMask operator|(KeyModifierMask a, KeyModifierMask b) {
return (KeyModifierMask)((int)a | (int)b);
}
diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml
index c750b540a4..45cbd7ac87 100644
--- a/doc/classes/ImageTexture.xml
+++ b/doc/classes/ImageTexture.xml
@@ -6,20 +6,20 @@
<description>
A [Texture2D] based on an [Image]. For an image to be displayed, an [ImageTexture] has to be created from it using the [method create_from_image] method:
[codeblock]
- var image = Image.load_from_file("res://icon.png")
+ var image = Image.load_from_file("res://icon.svg")
var texture = ImageTexture.create_from_image(image)
$Sprite2D.texture = texture
[/codeblock]
This way, textures can be created at run-time by loading images both from within the editor and externally.
[b]Warning:[/b] Prefer to load imported textures with [method @GDScript.load] over loading them from within the filesystem dynamically with [method Image.load], as it may not work in exported projects:
[codeblock]
- var texture = load("res://icon.png")
+ var texture = load("res://icon.svg")
$Sprite2D.texture = texture
[/codeblock]
This is because images have to be imported as a [CompressedTexture2D] first to be loaded with [method @GDScript.load]. If you'd still like to load an image file just like any other [Resource], import it as an [Image] resource instead, and then load it normally using the [method @GDScript.load] method.
[b]Note:[/b] The image can be retrieved from an imported texture using the [method Texture2D.get_image] method, which returns a copy of the image:
[codeblock]
- var texture = load("res://icon.png")
+ var texture = load("res://icon.svg")
var image : Image = texture.get_image()
[/codeblock]
An [ImageTexture] is not meant to be operated from within the editor interface directly, and is mostly useful for rendering images on screen dynamically via code. If you need to generate images procedurally from within the editor, consider saving and importing images as custom texture resources implementing a new [EditorImportPlugin].
diff --git a/doc/classes/ScriptExtension.xml b/doc/classes/ScriptExtension.xml
index b59c49d785..045eadda41 100644
--- a/doc/classes/ScriptExtension.xml
+++ b/doc/classes/ScriptExtension.xml
@@ -96,6 +96,12 @@
<description>
</description>
</method>
+ <method name="_has_property_default_value" qualifiers="virtual const">
+ <return type="bool" />
+ <param index="0" name="property" type="StringName" />
+ <description>
+ </description>
+ </method>
<method name="_has_script_signal" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="signal" type="StringName" />
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 3df3a3b76a..d95fe64a09 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "scene/animation/animation_player.h"
+#include "scene/animation/tween.h"
#include "scene/gui/separator.h"
#include "scene/gui/view_panner.h"
#include "scene/main/window.h"
@@ -5970,6 +5971,89 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
#undef NEW_POS
undo_redo->commit_action();
} break;
+
+ case EDIT_EASE_SELECTION: {
+ ease_dialog->popup_centered(Size2(200, 100) * EDSCALE);
+ } break;
+ case EDIT_EASE_CONFIRM: {
+ undo_redo->create_action(TTR("Make Easing Keys"));
+
+ Tween::TransitionType transition_type = static_cast<Tween::TransitionType>(transition_selection->get_selected_id());
+ Tween::EaseType ease_type = static_cast<Tween::EaseType>(ease_selection->get_selected_id());
+ float fps = ease_fps->get_value();
+ double dur_step = 1.0 / fps;
+
+ // Organize track and key.
+ HashMap<int, Vector<int>> keymap;
+ Vector<int> tracks;
+ for (const KeyValue<SelectedKey, KeyInfo> &E : selection) {
+ if (!tracks.has(E.key.track)) {
+ tracks.append(E.key.track);
+ }
+ }
+ for (int i = 0; i < tracks.size(); i++) {
+ switch (animation->track_get_type(tracks[i])) {
+ case Animation::TYPE_VALUE:
+ case Animation::TYPE_POSITION_3D:
+ case Animation::TYPE_ROTATION_3D:
+ case Animation::TYPE_SCALE_3D:
+ case Animation::TYPE_BLEND_SHAPE: {
+ Vector<int> keys;
+ for (const KeyValue<SelectedKey, KeyInfo> &E : selection) {
+ if (E.key.track == tracks[i]) {
+ keys.append(E.key.key);
+ }
+ }
+ keys.sort();
+ keymap.insert(tracks[i], keys);
+ } break;
+ default: {
+ } break;
+ }
+ }
+
+ // Make easing.
+ HashMap<int, Vector<int>>::Iterator E = keymap.begin();
+ while (E) {
+ int track = E->key;
+ Vector<int> keys = E->value;
+ int len = keys.size() - 1;
+
+ // Make insert queue.
+ Vector<Pair<double, Variant>> insert_queue;
+ for (int i = 0; i < len; i++) {
+ // Check neighboring keys.
+ if (keys[i] + 1 == keys[i + 1]) {
+ double from_t = animation->track_get_key_time(track, keys[i]);
+ double to_t = animation->track_get_key_time(track, keys[i + 1]);
+ Variant from_v = animation->track_get_key_value(track, keys[i]);
+ Variant to_v = animation->track_get_key_value(track, keys[i + 1]);
+ Variant delta_v;
+ Variant::sub(to_v, from_v, delta_v);
+ double duration = to_t - from_t;
+ double fixed_duration = duration - 0.01; // Prevent to overwrap keys...
+ for (double delta_t = dur_step; delta_t < fixed_duration; delta_t += dur_step) {
+ Pair<double, Variant> keydata;
+ keydata.first = from_t + delta_t;
+ keydata.second = Tween::interpolate_variant(from_v, delta_v, delta_t, duration, transition_type, ease_type);
+ insert_queue.append(keydata);
+ }
+ }
+ }
+
+ // Do insertion.
+ for (int i = 0; i < insert_queue.size(); i++) {
+ undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, insert_queue[i].first, insert_queue[i].second);
+ undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", track, insert_queue[i].first);
+ }
+
+ ++E;
+ }
+
+ undo_redo->commit_action();
+
+ } break;
+
case EDIT_DUPLICATE_SELECTION: {
if (bezier_edit->is_visible()) {
bezier_edit->duplicate_selection();
@@ -6061,8 +6145,115 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
} break;
case EDIT_APPLY_RESET: {
AnimationPlayerEditor::get_singleton()->get_player()->apply_reset(true);
+ } break;
+ case EDIT_BAKE_ANIMATION: {
+ bake_dialog->popup_centered(Size2(200, 100) * EDSCALE);
} break;
+ case EDIT_BAKE_ANIMATION_CONFIRM: {
+ undo_redo->create_action(TTR("Bake Animation as Linear keys."));
+
+ int track_len = animation->get_track_count();
+ bool b_trs = bake_trs->is_pressed();
+ bool b_bs = bake_blendshape->is_pressed();
+ bool b_v = bake_value->is_pressed();
+
+ double anim_len = animation->get_length() + CMP_EPSILON; // For end key.
+ float fps = bake_fps->get_value();
+ double dur_step = 1.0 / fps;
+
+ for (int i = 0; i < track_len; i++) {
+ bool do_bake = false;
+ Animation::TrackType type = animation->track_get_type(i);
+ do_bake |= b_trs && (type == Animation::TYPE_POSITION_3D || type == Animation::TYPE_ROTATION_3D || type == Animation::TYPE_SCALE_3D);
+ do_bake |= b_bs && type == Animation::TYPE_BLEND_SHAPE;
+ do_bake |= b_v && type == Animation::TYPE_VALUE;
+ if (do_bake && !animation->track_is_compressed(i)) {
+ if (animation->track_get_interpolation_type(i) == Animation::INTERPOLATION_NEAREST) {
+ continue; // Nearest interpolation cannot be baked.
+ }
+
+ // Make insert queue.
+ Vector<Pair<double, Variant>> insert_queue;
+
+ switch (type) {
+ case Animation::TYPE_POSITION_3D: {
+ for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) {
+ Pair<double, Variant> keydata;
+ keydata.first = delta_t;
+ Vector3 v;
+ animation->position_track_interpolate(i, delta_t, &v);
+ keydata.second = v;
+ insert_queue.append(keydata);
+ }
+ } break;
+ case Animation::TYPE_ROTATION_3D: {
+ for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) {
+ Pair<double, Variant> keydata;
+ keydata.first = delta_t;
+ Quaternion v;
+ animation->rotation_track_interpolate(i, delta_t, &v);
+ keydata.second = v;
+ insert_queue.append(keydata);
+ }
+ } break;
+ case Animation::TYPE_SCALE_3D: {
+ for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) {
+ Pair<double, Variant> keydata;
+ keydata.first = delta_t;
+ Vector3 v;
+ animation->scale_track_interpolate(i, delta_t, &v);
+ keydata.second = v;
+ insert_queue.append(keydata);
+ }
+ } break;
+ case Animation::TYPE_BLEND_SHAPE: {
+ for (double delta_t = 0.0; delta_t <= anim_len; delta_t += dur_step) {
+ Pair<double, Variant> keydata;
+ keydata.first = delta_t;
+ float v;
+ animation->blend_shape_track_interpolate(i, delta_t, &v);
+ keydata.second = v;
+ insert_queue.append(keydata);
+ }
+ } break;
+ case Animation::TYPE_VALUE: {
+ for (double delta_t = 0.0; delta_t < anim_len; delta_t += dur_step) {
+ Pair<double, Variant> keydata;
+ keydata.first = delta_t;
+ keydata.second = animation->value_track_interpolate(i, delta_t);
+ insert_queue.append(keydata);
+ }
+ } break;
+ default: {
+ } break;
+ }
+
+ // Cleanup keys.
+ int key_len = animation->track_get_key_count(i);
+ for (int j = key_len - 1; j >= 0; j--) {
+ undo_redo->add_do_method(animation.ptr(), "track_remove_key", i, j);
+ }
+
+ // Insert keys.
+ undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", i, Animation::INTERPOLATION_LINEAR);
+ for (int j = insert_queue.size() - 1; j >= 0; j--) {
+ undo_redo->add_do_method(animation.ptr(), "track_insert_key", i, insert_queue[j].first, insert_queue[j].second);
+ undo_redo->add_undo_method(animation.ptr(), "track_remove_key", i, j);
+ }
+
+ // Undo methods.
+ undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_type", i, animation->track_get_interpolation_type(i));
+ for (int j = key_len - 1; j >= 0; j--) {
+ undo_redo->add_undo_method(animation.ptr(), "track_insert_key", i, animation->track_get_key_time(i, j), animation->track_get_key_value(i, j), animation->track_get_key_transition(i, j));
+ }
+ }
+ }
+
+ undo_redo->commit_action();
+
+ } break;
+
case EDIT_OPTIMIZE_ANIMATION: {
optimize_dialog->popup_centered(Size2(250, 180) * EDSCALE);
@@ -6470,6 +6661,8 @@ AnimationTrackEditor::AnimationTrackEditor() {
edit->get_popup()->add_item(TTR("Scale Selection"), EDIT_SCALE_SELECTION);
edit->get_popup()->add_item(TTR("Scale From Cursor"), EDIT_SCALE_FROM_CURSOR);
edit->get_popup()->add_separator();
+ edit->get_popup()->add_item(TTR("Make Easing Selection"), EDIT_EASE_SELECTION);
+ edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_SELECTION);
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection_transposed", TTR("Duplicate Transposed"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_TRANSPOSED);
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/add_reset_value", TTR("Add RESET Value(s)")));
@@ -6482,6 +6675,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/apply_reset", TTR("Apply Reset")), EDIT_APPLY_RESET);
edit->get_popup()->add_separator();
+ edit->get_popup()->add_item(TTR("Bake Animation"), EDIT_BAKE_ANIMATION);
edit->get_popup()->add_item(TTR("Optimize Animation"), EDIT_OPTIMIZE_ANIMATION);
edit->get_popup()->add_item(TTR("Clean-Up Animation"), EDIT_CLEAN_UP_ANIMATION);
@@ -6604,6 +6798,88 @@ AnimationTrackEditor::AnimationTrackEditor() {
scale_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_SCALE_CONFIRM));
add_child(scale_dialog);
+ //
+ ease_dialog = memnew(ConfirmationDialog);
+ ease_dialog->set_title(TTR("Select Transition and Easing"));
+ ease_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_EASE_CONFIRM));
+ add_child(ease_dialog);
+ GridContainer *ease_grid = memnew(GridContainer);
+ ease_grid->set_columns(2);
+ ease_dialog->add_child(ease_grid);
+ transition_selection = memnew(OptionButton);
+ transition_selection->add_item("Linear", Tween::TRANS_LINEAR);
+ transition_selection->add_item("Sine", Tween::TRANS_SINE);
+ transition_selection->add_item("Quint", Tween::TRANS_QUINT);
+ transition_selection->add_item("Quart", Tween::TRANS_QUART);
+ transition_selection->add_item("Quad", Tween::TRANS_QUAD);
+ transition_selection->add_item("Expo", Tween::TRANS_EXPO);
+ transition_selection->add_item("Elastic", Tween::TRANS_ELASTIC);
+ transition_selection->add_item("Cubic", Tween::TRANS_CUBIC);
+ transition_selection->add_item("Circ", Tween::TRANS_CIRC);
+ transition_selection->add_item("Bounce", Tween::TRANS_BOUNCE);
+ transition_selection->add_item("Back", Tween::TRANS_BACK);
+ transition_selection->select(Tween::TRANS_LINEAR); // Default
+ ease_selection = memnew(OptionButton);
+ ease_selection->add_item("In", Tween::EASE_IN);
+ ease_selection->add_item("Out", Tween::EASE_OUT);
+ ease_selection->add_item("InOut", Tween::EASE_IN_OUT);
+ ease_selection->add_item("OutIn", Tween::EASE_OUT_IN);
+ ease_selection->select(Tween::EASE_IN_OUT); // Default
+ ease_fps = memnew(SpinBox);
+ ease_fps->set_min(1);
+ ease_fps->set_max(999);
+ ease_fps->set_step(1);
+ ease_fps->set_value(30); // Default
+ Label *ease_label1 = memnew(Label);
+ Label *ease_label2 = memnew(Label);
+ Label *ease_label3 = memnew(Label);
+ ease_label1->set_text("Transition Type:");
+ ease_label2->set_text("Ease Type:");
+ ease_label3->set_text("FPS:");
+ ease_grid->add_child(ease_label1);
+ ease_grid->add_child(transition_selection);
+ ease_grid->add_child(ease_label2);
+ ease_grid->add_child(ease_selection);
+ ease_grid->add_child(ease_label3);
+ ease_grid->add_child(ease_fps);
+
+ //
+ bake_dialog = memnew(ConfirmationDialog);
+ bake_dialog->set_title(TTR("Anim. Baker"));
+ bake_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_BAKE_ANIMATION_CONFIRM));
+ add_child(bake_dialog);
+ GridContainer *bake_grid = memnew(GridContainer);
+ bake_grid->set_columns(2);
+ bake_dialog->add_child(bake_grid);
+ bake_trs = memnew(CheckBox);
+ bake_trs->set_pressed(true);
+ bake_blendshape = memnew(CheckBox);
+ bake_blendshape->set_pressed(true);
+ bake_value = memnew(CheckBox);
+ bake_value->set_pressed(true);
+ bake_fps = memnew(SpinBox);
+ bake_fps->set_min(1);
+ bake_fps->set_max(999);
+ bake_fps->set_step(1);
+ bake_fps->set_value(30); // Default
+ Label *bake_label1 = memnew(Label);
+ Label *bake_label2 = memnew(Label);
+ Label *bake_label3 = memnew(Label);
+ Label *bake_label4 = memnew(Label);
+ bake_label1->set_text("Pos/Rot/Scl3D Track:");
+ bake_label2->set_text("Blendshape Track:");
+ bake_label3->set_text("Value Track:");
+ bake_label4->set_text("FPS:");
+ bake_grid->add_child(bake_label1);
+ bake_grid->add_child(bake_trs);
+ bake_grid->add_child(bake_label2);
+ bake_grid->add_child(bake_blendshape);
+ bake_grid->add_child(bake_label3);
+ bake_grid->add_child(bake_value);
+ bake_grid->add_child(bake_label4);
+ bake_grid->add_child(bake_fps);
+
+ //
track_copy_dialog = memnew(ConfirmationDialog);
add_child(track_copy_dialog);
track_copy_dialog->set_title(TTR("Select Tracks to Copy"));
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 806d3ffb14..5ebf25899f 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -32,6 +32,7 @@
#define ANIMATION_TRACK_EDITOR_H
#include "editor/editor_data.h"
+#include "editor/editor_properties.h"
#include "editor/editor_spin_slider.h"
#include "editor/property_selector.h"
@@ -451,6 +452,12 @@ class AnimationTrackEditor : public VBoxContainer {
////////////// edit menu stuff
+ ConfirmationDialog *bake_dialog = nullptr;
+ CheckBox *bake_trs = nullptr;
+ CheckBox *bake_blendshape = nullptr;
+ CheckBox *bake_value = nullptr;
+ SpinBox *bake_fps = nullptr;
+
ConfirmationDialog *optimize_dialog = nullptr;
SpinBox *optimize_velocity_error = nullptr;
SpinBox *optimize_angular_error = nullptr;
@@ -464,6 +471,11 @@ class AnimationTrackEditor : public VBoxContainer {
ConfirmationDialog *scale_dialog = nullptr;
SpinBox *scale = nullptr;
+ ConfirmationDialog *ease_dialog = nullptr;
+ OptionButton *transition_selection = nullptr;
+ OptionButton *ease_selection = nullptr;
+ SpinBox *ease_fps = nullptr;
+
void _select_all_tracks_for_copy();
void _edit_menu_about_to_popup();
@@ -521,6 +533,8 @@ public:
EDIT_SCALE_SELECTION,
EDIT_SCALE_FROM_CURSOR,
EDIT_SCALE_CONFIRM,
+ EDIT_EASE_SELECTION,
+ EDIT_EASE_CONFIRM,
EDIT_DUPLICATE_SELECTION,
EDIT_DUPLICATE_TRANSPOSED,
EDIT_ADD_RESET_KEY,
@@ -529,6 +543,8 @@ public:
EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY, // Next step without updating animation.
EDIT_GOTO_PREV_STEP,
EDIT_APPLY_RESET,
+ EDIT_BAKE_ANIMATION,
+ EDIT_BAKE_ANIMATION_CONFIRM,
EDIT_OPTIMIZE_ANIMATION,
EDIT_OPTIMIZE_ANIMATION_CONFIRM,
EDIT_CLEAN_UP_ANIMATION,
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 3da9899052..0c17469e86 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1849,14 +1849,14 @@ Ref<Theme> create_custom_theme(const Ref<Theme> p_theme) {
return theme;
}
-Ref<ImageTexture> create_unscaled_default_project_icon() {
-#ifdef MODULE_SVG_ENABLED
+/**
+ * Returns the SVG code for the default project icon.
+ */
+String get_default_project_icon() {
for (int i = 0; i < editor_icons_count; i++) {
- // ESCALE should never affect size of the icon
if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0) {
- return editor_generate_icon(i, false, 1.0);
+ return String(editor_icons_sources[i]);
}
}
-#endif
- return Ref<ImageTexture>(memnew(ImageTexture));
+ return String();
}
diff --git a/editor/editor_themes.h b/editor/editor_themes.h
index 95184b9d4a..1c69761435 100644
--- a/editor/editor_themes.h
+++ b/editor/editor_themes.h
@@ -38,6 +38,6 @@ Ref<Theme> create_editor_theme(Ref<Theme> p_theme = nullptr);
Ref<Theme> create_custom_theme(Ref<Theme> p_theme = nullptr);
-Ref<ImageTexture> create_unscaled_default_project_icon();
+String get_default_project_icon();
#endif // EDITOR_THEMES_H
diff --git a/editor/icons/CurveIn.svg b/editor/icons/CurveIn.svg
index 2ad44dc654..fefad9ce6c 100644
--- a/editor/icons/CurveIn.svg
+++ b/editor/icons/CurveIn.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 8-3 8-8" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 8-3 8-8" fill="none" stroke="#80ff45" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
diff --git a/editor/icons/CurveInOut.svg b/editor/icons/CurveInOut.svg
index 292dac4573..f099cb83f1 100644
--- a/editor/icons/CurveInOut.svg
+++ b/editor/icons/CurveInOut.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 3-8 8-8" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 3-8 8-8" fill="none" stroke="#45d7ff" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
diff --git a/editor/icons/CurveLinear.svg b/editor/icons/CurveLinear.svg
index 3c1fb2a0e2..41d37c9329 100644
--- a/editor/icons/CurveLinear.svg
+++ b/editor/icons/CurveLinear.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 8-8" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 8-8" fill="none" stroke="#ffe345" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
diff --git a/editor/icons/CurveOut.svg b/editor/icons/CurveOut.svg
index dfa9a26144..19710aa38d 100644
--- a/editor/icons/CurveOut.svg
+++ b/editor/icons/CurveOut.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c0-5 3-8 8-8" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c0-5 3-8 8-8" fill="none" stroke="#45ffa2" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
diff --git a/editor/icons/CurveOutIn.svg b/editor/icons/CurveOutIn.svg
index 9a6463d0e9..7f200432bf 100644
--- a/editor/icons/CurveOutIn.svg
+++ b/editor/icons/CurveOutIn.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c0-5 8-3 8-8" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c0-5 8-3 8-8" fill="none" stroke="#ff4596" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 2798f3d93e..d14c2cbce3 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -46,6 +46,7 @@
#include "editor/scene_tree_dock.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/collision_shape_3d.h"
+#include "scene/3d/decal.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
@@ -2972,6 +2973,13 @@ void Node3DEditorViewport::_menu_option(int p_option) {
xform.scale_basis(sp->get_scale());
}
+ if (Object::cast_to<Decal>(E)) {
+ // Adjust rotation to match Decal's default orientation.
+ // This makes the decal "look" in the same direction as the camera,
+ // rather than pointing down relative to the camera orientation.
+ xform.basis.rotate_local(Vector3(1, 0, 0), Math_TAU * 0.25);
+ }
+
undo_redo->add_do_method(sp, "set_global_transform", xform);
undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
}
@@ -2999,7 +3007,16 @@ void Node3DEditorViewport::_menu_option(int p_option) {
continue;
}
- undo_redo->add_do_method(sp, "set_rotation", camera_transform.basis.get_euler_normalized());
+ Basis basis = camera_transform.basis;
+
+ if (Object::cast_to<Decal>(E)) {
+ // Adjust rotation to match Decal's default orientation.
+ // This makes the decal "look" in the same direction as the camera,
+ // rather than pointing down relative to the camera orientation.
+ basis.rotate_local(Vector3(1, 0, 0), Math_TAU * 0.25);
+ }
+
+ undo_redo->add_do_method(sp, "set_rotation", basis.get_euler_normalized());
undo_redo->add_undo_method(sp, "set_rotation", sp->get_rotation());
}
undo_redo->commit_action();
@@ -7615,7 +7632,7 @@ void Node3DEditor::_load_default_preview_settings() {
environ_tonemap_button->set_pressed(true);
environ_ao_button->set_pressed(false);
environ_gi_button->set_pressed(false);
- sun_max_distance->set_value(250);
+ sun_max_distance->set_value(100);
sun_color->set_pick_color(Color(1, 1, 1));
sun_energy->set_value(1.0);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 46eb7ac17c..cce71d9508 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -484,12 +484,20 @@ private:
project_features.sort();
initial_settings["application/config/features"] = project_features;
initial_settings["application/config/name"] = project_name->get_text().strip_edges();
- initial_settings["application/config/icon"] = "res://icon.png";
+ initial_settings["application/config/icon"] = "res://icon.svg";
if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) {
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
} else {
- ResourceSaver::save(create_unscaled_default_project_icon(), dir.plus_file("icon.png"));
+ // Store default project icon in SVG format.
+ Error err;
+ Ref<FileAccess> fa_icon = FileAccess::open(dir.plus_file("icon.svg"), FileAccess::WRITE, &err);
+ fa_icon->store_string(get_default_project_icon());
+
+ if (err != OK) {
+ set_message(TTR("Couldn't create icon.svg in project path."), MESSAGE_ERROR);
+ }
+
EditorVCSInterface::create_vcs_metadata_files(EditorVCSInterface::VCSMetadata(vcs_metadata_selection->get_selected()), dir);
}
} else if (mode == MODE_INSTALL) {
diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp
index 1e1204aa57..cc1ca9131d 100644
--- a/modules/gltf/register_types.cpp
+++ b/modules/gltf/register_types.cpp
@@ -66,17 +66,24 @@ static void _editor_init() {
bool blend_enabled = GLOBAL_GET("filesystem/import/blender/enabled");
// Defined here because EditorSettings doesn't exist in `register_gltf_types` yet.
- EDITOR_DEF_RST("filesystem/import/blender/blender3_path", "");
+ String blender3_path = EDITOR_DEF_RST("filesystem/import/blender/blender3_path", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,
"filesystem/import/blender/blender3_path", PROPERTY_HINT_GLOBAL_DIR));
if (blend_enabled) {
- Ref<EditorSceneFormatImporterBlend> importer;
- importer.instantiate();
- ResourceImporterScene::add_importer(importer);
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ if (blender3_path.is_empty()) {
+ WARN_PRINT("Blend file import is enabled in the project settings, but no Blender path is configured in the editor settings. Blend files will not be imported.");
+ } else if (!da->file_exists(blender3_path)) {
+ WARN_PRINT("Blend file import is enabled, but the Blender path doesn't point to an accessible file. Blend files will not be imported.");
+ } else {
+ Ref<EditorSceneFormatImporterBlend> importer;
+ importer.instantiate();
+ ResourceImporterScene::add_importer(importer);
- Ref<EditorFileSystemImportFormatSupportQueryBlend> blend_import_query;
- blend_import_query.instantiate();
- EditorFileSystem::get_singleton()->add_import_format_support_query(blend_import_query);
+ Ref<EditorFileSystemImportFormatSupportQueryBlend> blend_import_query;
+ blend_import_query.instantiate();
+ EditorFileSystem::get_singleton()->add_import_format_support_query(blend_import_query);
+ }
}
// FBX to glTF importer.
@@ -89,9 +96,9 @@ static void _editor_init() {
if (fbx_enabled) {
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (fbx2gltf_path.is_empty()) {
- WARN_PRINT("FBX file import is enabled, but no FBX2glTF path is configured. FBX files will not be imported.");
+ WARN_PRINT("FBX file import is enabled in the project settings, but no FBX2glTF path is configured in the editor settings. FBX files will not be imported.");
} else if (!da->file_exists(fbx2gltf_path)) {
- WARN_PRINT("FBX file import is enabled, but the FBX2glTF path doesn't point to a valid FBX2glTF executable. FBX files will not be imported.");
+ WARN_PRINT("FBX file import is enabled, but the FBX2glTF path doesn't point to an accessible file. FBX files will not be imported.");
} else {
Ref<EditorSceneFormatImporterFBX> importer;
importer.instantiate();
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
index 8d0e77d171..1b7f5158fd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
@@ -149,11 +149,5 @@ namespace Godot
NativeFuncs.godotsharp_callable_call_deferred(callable, (godot_variant**)argsPtr, argc);
}
}
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern object godot_icall_Callable_Call(ref Callable callable, object[] args);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern void godot_icall_Callable_CallDeferred(ref Callable callable, object[] args);
}
}
diff --git a/modules/mono/glue/callable_glue.cpp b/modules/mono/glue/callable_glue.cpp
deleted file mode 100644
index 521dc3dff7..0000000000
--- a/modules/mono/glue/callable_glue.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*************************************************************************/
-/* callable_glue.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "../mono_gd/gd_mono_marshal.h"
-#include "arguments_vector.h"
-
-MonoObject *godot_icall_Callable_Call(GDMonoMarshal::M_Callable *p_callable, MonoArray *p_args) {
- Callable callable = GDMonoMarshal::managed_to_callable(*p_callable);
-
- int argc = mono_array_length(p_args);
-
- ArgumentsVector<Variant> arg_store(argc);
- ArgumentsVector<const Variant *> args(argc);
-
- for (int i = 0; i < argc; i++) {
- MonoObject *elem = mono_array_get(p_args, MonoObject *, i);
- arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem));
- args.set(i, &arg_store.get(i));
- }
-
- Variant result;
- Callable::CallError error;
- callable.callp(args.ptr(), argc, result, error);
-
- return GDMonoMarshal::variant_to_mono_object(result);
-}
-
-void godot_icall_Callable_CallDeferred(GDMonoMarshal::M_Callable *p_callable, MonoArray *p_args) {
- Callable callable = GDMonoMarshal::managed_to_callable(*p_callable);
-
- int argc = mono_array_length(p_args);
-
- ArgumentsVector<Variant> arg_store(argc);
- ArgumentsVector<const Variant *> args(argc);
-
- for (int i = 0; i < argc; i++) {
- MonoObject *elem = mono_array_get(p_args, MonoObject *, i);
- arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem));
- args.set(i, &arg_store.get(i));
- }
-
- callable.call_deferredp(args.ptr(), argc);
-}
-
-void godot_register_callable_icalls() {
- GDMonoUtils::add_internal_call("Godot.Callable::godot_icall_Callable_Call", godot_icall_Callable_Call);
- GDMonoUtils::add_internal_call("Godot.Callable::godot_icall_Callable_CallDeferred", godot_icall_Callable_CallDeferred);
-}
-
-#endif // MONO_GLUE_ENABLED
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index eb344d3b43..428135de56 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -135,6 +135,20 @@ String DirAccessJAndroid::get_drive(int p_drive) {
}
}
+String DirAccessJAndroid::get_current_dir(bool p_include_drive) const {
+ String base = _get_root_path();
+ String bd = current_dir;
+ if (!base.is_empty()) {
+ bd = current_dir.replace_first(base, "");
+ }
+
+ if (bd.begins_with("/")) {
+ return _get_root_string() + bd.substr(1, bd.length());
+ } else {
+ return _get_root_string() + bd;
+ }
+}
+
Error DirAccessJAndroid::change_dir(String p_dir) {
String new_dir = get_absolute_path(p_dir);
if (new_dir == current_dir) {
diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h
index d469c9d317..5b7b4a9c4d 100644
--- a/platform/android/dir_access_jandroid.h
+++ b/platform/android/dir_access_jandroid.h
@@ -67,6 +67,7 @@ public:
virtual int get_drive_count() override;
virtual String get_drive(int p_drive) override;
+ virtual String get_current_dir(bool p_include_drive = true) const override; ///< return current dir location
virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index dbc71cd9e7..7d9f83b7a2 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -479,12 +479,8 @@ Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, f
case Variant::QUATERNION: {
Quaternion i = p_initial_val;
Quaternion d = p_delta_val;
- Quaternion r;
-
- APPLY_EQUATION(x);
- APPLY_EQUATION(y);
- APPLY_EQUATION(z);
- APPLY_EQUATION(w);
+ Quaternion r = i * d;
+ r = i.slerp(r, run_equation(p_trans, p_ease, p_time, 0.0, 1.0, p_duration));
return r;
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index ab466089a7..ea080a8954 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1346,7 +1346,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
return line_count;
}
-void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside) {
+void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside, bool p_meta) {
if (r_click_item) {
*r_click_item = nullptr;
}
@@ -1369,7 +1369,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs);
while (ofs.y < size.height && from_line < to_line) {
MutexLock lock(main->lines[from_line].text_buf->get_mutex());
- _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char);
+ _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char, false, p_meta);
ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation"));
if (((r_click_item != nullptr) && ((*r_click_item) != nullptr)) || ((r_click_frame != nullptr) && ((*r_click_frame) != nullptr))) {
if (r_outside != nullptr) {
@@ -1381,7 +1381,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
}
}
-float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool p_table) {
+float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool p_table, bool p_meta) {
Vector2 off;
bool line_clicked = false;
@@ -1479,7 +1479,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
}
if (crect.has_point(p_click)) {
for (int j = 0; j < (int)frame->lines.size(); j++) {
- _find_click_in_line(frame, j, rect.position + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_click, &table_click_frame, &table_click_line, &table_click_item, &table_click_char, true);
+ _find_click_in_line(frame, j, rect.position + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_click, &table_click_frame, &table_click_line, &table_click_item, &table_click_char, true, p_meta);
if (table_click_frame && table_click_item) {
// Save cell detected cell hit data.
table_range = Vector2i(INT32_MAX, 0);
@@ -1512,7 +1512,15 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) {
if ((!rtl && p_click.x >= rect.position.x) || (rtl && p_click.x <= rect.position.x + rect.size.x)) {
- char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
+ if (p_meta) {
+ int64_t glyph_idx = TS->shaped_text_hit_test_grapheme(rid, p_click.x - rect.position.x);
+ if (glyph_idx >= 0) {
+ const Glyph *glyphs = TS->shaped_text_get_glyphs(rid);
+ char_pos = glyphs[glyph_idx].start;
+ }
+ } else {
+ char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
+ }
}
line_clicked = true;
text_rect_begin = rtl ? rect.position.x + rect.size.x : rect.position.x;
@@ -1825,7 +1833,7 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
Item *item = nullptr;
bool outside = true;
- const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &item, nullptr, &outside);
+ const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &item, nullptr, &outside, true);
if (item && !outside && const_cast<RichTextLabel *>(this)->_find_meta(item, nullptr)) {
return CURSOR_POINTING_HAND;
@@ -1850,7 +1858,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
selection.drag_attempt = false;
- _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside);
+ _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside, false);
if (c_item != nullptr) {
if (selection.enabled) {
selection.click_frame = c_frame;
@@ -1888,7 +1896,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
selection.drag_attempt = false;
- _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside);
+ _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside, false);
if (c_frame) {
const Line &l = c_frame->lines[c_line];
@@ -1938,7 +1946,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
Item *c_item = nullptr;
bool outside = true;
- _find_click(main, b->get_position(), nullptr, nullptr, &c_item, nullptr, &outside);
+ _find_click(main, b->get_position(), nullptr, nullptr, &c_item, nullptr, &outside, true);
if (c_item) {
Variant meta;
@@ -2044,7 +2052,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
int c_index = 0;
bool outside;
- _find_click(main, m->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside);
+ _find_click(main, m->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside, false);
if (selection.click_item && c_item) {
selection.from_frame = selection.click_frame;
selection.from_line = selection.click_line;
@@ -2102,7 +2110,7 @@ String RichTextLabel::get_tooltip(const Point2 &p_pos) const {
Item *c_item = nullptr;
bool outside;
- const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &c_item, nullptr, &outside);
+ const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &c_item, nullptr, &outside, true);
String description;
if (c_item && !outside && const_cast<RichTextLabel *>(this)->_find_hint(c_item, &description)) {
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index e5f0469c01..95e55bf1a1 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -444,7 +444,7 @@ private:
TextServer::VisibleCharactersBehavior visible_chars_behavior = TextServer::VC_CHARS_BEFORE_SHAPING;
bool _is_click_inside_selection() const;
- void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr);
+ void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr, bool p_meta = false);
String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const;
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
@@ -455,7 +455,7 @@ private:
void _update_line_font(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size);
int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs, int &r_processed_glyphs);
- float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool p_table = false);
+ float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool p_table = false, bool p_meta = false);
String _roman(int p_num, bool p_capitalize) const;
String _letters(int p_num, bool p_capitalize) const;
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index d7aa516ee6..9505a30540 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -98,11 +98,10 @@ void SplitContainer::_resort() {
// Compute the final middle separation
middle_sep = no_offset_middle_sep;
if (!collapsed) {
- int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, (get_size()[axis] - ms_second[axis] - sep) - no_offset_middle_sep);
- middle_sep += clamped_split_offset;
+ int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, get_size()[axis] - ms_second[axis] - sep);
+ middle_sep = MAX(middle_sep, clamped_split_offset);
if (should_clamp_split_offset) {
split_offset = clamped_split_offset;
-
should_clamp_split_offset = false;
}
}
diff --git a/scene/resources/skeleton_modification_3d_ccdik.h b/scene/resources/skeleton_modification_3d_ccdik.h
index 7098794038..1fe53e94b6 100644
--- a/scene/resources/skeleton_modification_3d_ccdik.h
+++ b/scene/resources/skeleton_modification_3d_ccdik.h
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef SKELETON_MODIFICATION_3D_CCDIK_H
+#define SKELETON_MODIFICATION_3D_CCDIK_H
+
#include "core/templates/local_vector.h"
#include "scene/3d/skeleton_3d.h"
#include "scene/resources/skeleton_modification_3d.h"
-#ifndef SKELETON_MODIFICATION_3D_CCDIK_H
-#define SKELETON_MODIFICATION_3D_CCDIK_H
-
class SkeletonModification3DCCDIK : public SkeletonModification3D {
GDCLASS(SkeletonModification3DCCDIK, SkeletonModification3D);
diff --git a/scene/resources/skeleton_modification_3d_fabrik.h b/scene/resources/skeleton_modification_3d_fabrik.h
index 3d66bb6d99..e2e490d636 100644
--- a/scene/resources/skeleton_modification_3d_fabrik.h
+++ b/scene/resources/skeleton_modification_3d_fabrik.h
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef SKELETON_MODIFICATION_3D_FABRIK_H
+#define SKELETON_MODIFICATION_3D_FABRIK_H
+
#include "core/templates/local_vector.h"
#include "scene/3d/skeleton_3d.h"
#include "scene/resources/skeleton_modification_3d.h"
-#ifndef SKELETON_MODIFICATION_3D_FABRIK_H
-#define SKELETON_MODIFICATION_3D_FABRIK_H
-
class SkeletonModification3DFABRIK : public SkeletonModification3D {
GDCLASS(SkeletonModification3DFABRIK, SkeletonModification3D);
diff --git a/scene/resources/skeleton_modification_3d_jiggle.h b/scene/resources/skeleton_modification_3d_jiggle.h
index f41ffcd58d..bd1ee51d93 100644
--- a/scene/resources/skeleton_modification_3d_jiggle.h
+++ b/scene/resources/skeleton_modification_3d_jiggle.h
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef SKELETON_MODIFICATION_3D_JIGGLE_H
+#define SKELETON_MODIFICATION_3D_JIGGLE_H
+
#include "core/templates/local_vector.h"
#include "scene/3d/skeleton_3d.h"
#include "scene/resources/skeleton_modification_3d.h"
-#ifndef SKELETON_MODIFICATION_3D_JIGGLE_H
-#define SKELETON_MODIFICATION_3D_JIGGLE_H
-
class SkeletonModification3DJiggle : public SkeletonModification3D {
GDCLASS(SkeletonModification3DJiggle, SkeletonModification3D);
diff --git a/scene/resources/skeleton_modification_3d_lookat.h b/scene/resources/skeleton_modification_3d_lookat.h
index 4e5714b5dc..cea63fc34f 100644
--- a/scene/resources/skeleton_modification_3d_lookat.h
+++ b/scene/resources/skeleton_modification_3d_lookat.h
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "scene/3d/skeleton_3d.h"
-#include "scene/resources/skeleton_modification_3d.h"
-
#ifndef SKELETON_MODIFICATION_3D_LOOKAT_H
#define SKELETON_MODIFICATION_3D_LOOKAT_H
+#include "scene/3d/skeleton_3d.h"
+#include "scene/resources/skeleton_modification_3d.h"
+
class SkeletonModification3DLookAt : public SkeletonModification3D {
GDCLASS(SkeletonModification3DLookAt, SkeletonModification3D);
diff --git a/scene/resources/skeleton_modification_3d_stackholder.h b/scene/resources/skeleton_modification_3d_stackholder.h
index ae22099158..2071de5457 100644
--- a/scene/resources/skeleton_modification_3d_stackholder.h
+++ b/scene/resources/skeleton_modification_3d_stackholder.h
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "scene/3d/skeleton_3d.h"
-#include "scene/resources/skeleton_modification_3d.h"
-
#ifndef SKELETON_MODIFICATION_3D_STACKHOLDER_H
#define SKELETON_MODIFICATION_3D_STACKHOLDER_H
+#include "scene/3d/skeleton_3d.h"
+#include "scene/resources/skeleton_modification_3d.h"
+
class SkeletonModification3DStackHolder : public SkeletonModification3D {
GDCLASS(SkeletonModification3DStackHolder, SkeletonModification3D);
diff --git a/scene/resources/skeleton_modification_3d_twoboneik.h b/scene/resources/skeleton_modification_3d_twoboneik.h
index 57e8237511..7bd7c8291d 100644
--- a/scene/resources/skeleton_modification_3d_twoboneik.h
+++ b/scene/resources/skeleton_modification_3d_twoboneik.h
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "scene/3d/skeleton_3d.h"
-#include "scene/resources/skeleton_modification_3d.h"
-
#ifndef SKELETON_MODIFICATION_3D_TWOBONEIK_H
#define SKELETON_MODIFICATION_3D_TWOBONEIK_H
+#include "scene/3d/skeleton_3d.h"
+#include "scene/resources/skeleton_modification_3d.h"
+
class SkeletonModification3DTwoBoneIK : public SkeletonModification3D {
GDCLASS(SkeletonModification3DTwoBoneIK, SkeletonModification3D);
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 73b03966c5..bfb81925bc 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -72,6 +72,41 @@ static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport,
return xf;
}
+Vector<RendererViewport::Viewport *> RendererViewport::_sort_active_viewports() {
+ // We need to sort the viewports in a "topological order",
+ // children first and parents last, we use the Kahn's algorithm to achieve that.
+
+ Vector<Viewport *> result;
+ List<Viewport *> nodes;
+
+ for (Viewport *viewport : active_viewports) {
+ if (viewport->parent.is_valid()) {
+ continue;
+ }
+
+ nodes.push_back(viewport);
+ }
+
+ while (!nodes.is_empty()) {
+ Viewport *node = nodes[0];
+ nodes.pop_front();
+
+ result.insert(0, node);
+
+ for (Viewport *child : active_viewports) {
+ if (child->parent != node->self) {
+ continue;
+ }
+
+ if (!nodes.find(child)) {
+ nodes.push_back(child);
+ }
+ }
+ }
+
+ return result;
+}
+
void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
if (p_viewport->render_buffers.is_valid()) {
if (p_viewport->size.width == 0 || p_viewport->size.height == 0) {
@@ -548,8 +583,10 @@ void RendererViewport::draw_viewports() {
set_default_clear_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
}
- //sort viewports
- active_viewports.sort_custom<ViewportSort>();
+ if (sorted_active_viewports_dirty) {
+ sorted_active_viewports = _sort_active_viewports();
+ sorted_active_viewports_dirty = false;
+ }
HashMap<DisplayServer::WindowID, Vector<BlitToScreen>> blit_to_screen_list;
//draw viewports
@@ -558,9 +595,9 @@ void RendererViewport::draw_viewports() {
//determine what is visible
draw_viewports_pass++;
- for (int i = active_viewports.size() - 1; i >= 0; i--) { //to compute parent dependency, must go in reverse draw order
+ for (int i = sorted_active_viewports.size() - 1; i >= 0; i--) { //to compute parent dependency, must go in reverse draw order
- Viewport *vp = active_viewports[i];
+ Viewport *vp = sorted_active_viewports[i];
if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED) {
continue;
@@ -621,8 +658,8 @@ void RendererViewport::draw_viewports() {
int objects_drawn = 0;
int draw_calls_used = 0;
- for (int i = 0; i < active_viewports.size(); i++) {
- Viewport *vp = active_viewports[i];
+ for (int i = 0; i < sorted_active_viewports.size(); i++) {
+ Viewport *vp = sorted_active_viewports[i];
if (vp->last_pass != draw_viewports_pass) {
continue; //should not draw
@@ -814,6 +851,8 @@ void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
} else {
active_viewports.erase(viewport);
}
+
+ sorted_active_viewports_dirty = true;
}
void RendererViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) {
@@ -1243,6 +1282,7 @@ bool RendererViewport::free(RID p_rid) {
viewport_set_scenario(p_rid, RID());
active_viewports.erase(viewport);
+ sorted_active_viewports_dirty = true;
if (viewport->use_occlusion_culling) {
RendererSceneOcclusionCull::get_singleton()->remove_buffer(p_rid);
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index 5e37c96336..ab4893a908 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -185,25 +185,16 @@ public:
mutable RID_Owner<Viewport, true> viewport_owner;
- struct ViewportSort {
- _FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const {
- bool left_to_screen = p_left->viewport_to_screen_rect.size != Size2();
- bool right_to_screen = p_right->viewport_to_screen_rect.size != Size2();
-
- if (left_to_screen == right_to_screen) {
- return p_right->parent == p_left->self;
- }
- return (right_to_screen ? 0 : 1) < (left_to_screen ? 0 : 1);
- }
- };
-
Vector<Viewport *> active_viewports;
+ Vector<Viewport *> sorted_active_viewports;
+ bool sorted_active_viewports_dirty = false;
int total_objects_drawn = 0;
int total_vertices_drawn = 0;
int total_draw_calls_used = 0;
private:
+ Vector<Viewport *> _sort_active_viewports();
void _configure_3d_render_buffers(Viewport *p_viewport);
void _draw_3d(Viewport *p_viewport);
void _draw_viewport(Viewport *p_viewport);
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 664401fca6..9f6e6e8ec5 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -195,6 +195,7 @@ Files extracted from upstream source:
to `glslang/build_info.h`
- `LICENSE.txt`
- Unnecessary files like `CMakeLists.txt`, `*.m4` and `updateGrammar` removed.
+- Patch in `patches/unused_cleanup.diff` must be applied.
## graphite
diff --git a/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp b/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp
index 81da99c2c4..1cbd616e98 100644
--- a/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp
+++ b/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp
@@ -66,43 +66,6 @@ static void DetachThreadLinux(void *)
}
//
-// Registers cleanup handler, sets cancel type and state, and executes the thread specific
-// cleanup handler. This function will be called in the Standalone.cpp for regression
-// testing. When OpenGL applications are run with the driver code, Linux OS does the
-// thread cleanup.
-//
-void OS_CleanupThreadData(void)
-{
-#if defined(__ANDROID__) || defined(__Fuchsia__)
- DetachThreadLinux(NULL);
-#else
- int old_cancel_state, old_cancel_type;
- void *cleanupArg = NULL;
-
- //
- // Set thread cancel state and push cleanup handler.
- //
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
- pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);
-
- //
- // Put the thread in deferred cancellation mode.
- //
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);
-
- //
- // Pop cleanup handler and execute it prior to unregistering the cleanup handler.
- //
- pthread_cleanup_pop(1);
-
- //
- // Restore the thread's previous cancellation mode.
- //
- pthread_setcanceltype(old_cancel_state, NULL);
-#endif
-}
-
-//
// Thread Local Storage Operations
//
inline OS_TLSIndex PthreadKeyToTLSIndex(pthread_key_t key)
diff --git a/thirdparty/glslang/glslang/OSDependent/osinclude.h b/thirdparty/glslang/glslang/OSDependent/osinclude.h
index 218abe4f23..fcfeff2cc4 100644
--- a/thirdparty/glslang/glslang/OSDependent/osinclude.h
+++ b/thirdparty/glslang/glslang/OSDependent/osinclude.h
@@ -54,8 +54,6 @@ void ReleaseGlobalLock();
typedef unsigned int (*TThreadEntrypoint)(void*);
-void OS_CleanupThreadData(void);
-
void OS_DumpMemoryCounters();
} // end namespace glslang
diff --git a/thirdparty/glslang/patches/unused_cleanup.diff b/thirdparty/glslang/patches/unused_cleanup.diff
new file mode 100644
index 0000000000..3e9a9c23f9
--- /dev/null
+++ b/thirdparty/glslang/patches/unused_cleanup.diff
@@ -0,0 +1,61 @@
+diff --git a/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp b/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp
+index 81da99c2c4..1cbd616e98 100644
+--- a/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp
++++ b/thirdparty/glslang/glslang/OSDependent/Unix/ossource.cpp
+@@ -65,43 +65,6 @@ static void DetachThreadLinux(void *)
+ DetachThread();
+ }
+
+-//
+-// Registers cleanup handler, sets cancel type and state, and executes the thread specific
+-// cleanup handler. This function will be called in the Standalone.cpp for regression
+-// testing. When OpenGL applications are run with the driver code, Linux OS does the
+-// thread cleanup.
+-//
+-void OS_CleanupThreadData(void)
+-{
+-#if defined(__ANDROID__) || defined(__Fuchsia__)
+- DetachThreadLinux(NULL);
+-#else
+- int old_cancel_state, old_cancel_type;
+- void *cleanupArg = NULL;
+-
+- //
+- // Set thread cancel state and push cleanup handler.
+- //
+- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
+- pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);
+-
+- //
+- // Put the thread in deferred cancellation mode.
+- //
+- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);
+-
+- //
+- // Pop cleanup handler and execute it prior to unregistering the cleanup handler.
+- //
+- pthread_cleanup_pop(1);
+-
+- //
+- // Restore the thread's previous cancellation mode.
+- //
+- pthread_setcanceltype(old_cancel_state, NULL);
+-#endif
+-}
+-
+ //
+ // Thread Local Storage Operations
+ //
+diff --git a/thirdparty/glslang/glslang/OSDependent/osinclude.h b/thirdparty/glslang/glslang/OSDependent/osinclude.h
+index 218abe4f23..fcfeff2cc4 100644
+--- a/thirdparty/glslang/glslang/OSDependent/osinclude.h
++++ b/thirdparty/glslang/glslang/OSDependent/osinclude.h
+@@ -54,8 +54,6 @@ void ReleaseGlobalLock();
+
+ typedef unsigned int (*TThreadEntrypoint)(void*);
+
+-void OS_CleanupThreadData(void);
+-
+ void OS_DumpMemoryCounters();
+
+ } // end namespace glslang