summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/core_bind.cpp1
-rw-r--r--core/extension/gdnative_interface.cpp8
-rw-r--r--core/extension/gdnative_interface.h1
-rw-r--r--core/input/input.cpp2
-rw-r--r--core/io/image.cpp2
-rw-r--r--core/math/color.h4
-rw-r--r--core/variant/variant.h1
-rw-r--r--core/variant/variant_call.cpp4
-rw-r--r--core/variant/variant_setget.cpp104
-rw-r--r--doc/classes/Camera3D.xml2
-rw-r--r--doc/classes/CollisionObject2D.xml1
-rw-r--r--doc/classes/Color.xml26
-rw-r--r--doc/classes/EditorSceneFormatImporter.xml14
-rw-r--r--doc/classes/EditorScenePostImportPlugin.xml6
-rw-r--r--doc/classes/Signal.xml2
-rw-r--r--editor/animation_track_editor.cpp63
-rw-r--r--editor/animation_track_editor.h1
-rw-r--r--editor/editor_node.cpp11
-rw-r--r--editor/editor_plugin.cpp8
-rw-r--r--editor/filesystem_dock.cpp24
-rw-r--r--editor/import/editor_import_collada.cpp21
-rw-r--r--editor/import/editor_import_collada.h1
-rw-r--r--editor/import/resource_importer_obj.cpp4
-rw-r--r--editor/import/resource_importer_obj.h1
-rw-r--r--editor/import/resource_importer_scene.cpp124
-rw-r--r--editor/import/resource_importer_scene.h39
-rw-r--r--editor/import/scene_import_settings.cpp128
-rw-r--r--editor/import/scene_import_settings.h7
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp4
-rw-r--r--modules/gltf/editor/editor_scene_importer_blend.cpp14
-rw-r--r--modules/gltf/editor/editor_scene_importer_blend.h4
-rw-r--r--modules/gltf/editor/editor_scene_importer_fbx.cpp7
-rw-r--r--modules/gltf/editor/editor_scene_importer_fbx.h4
-rw-r--r--modules/gltf/editor/editor_scene_importer_gltf.cpp5
-rw-r--r--modules/gltf/editor/editor_scene_importer_gltf.h2
-rw-r--r--modules/gltf/gltf_document.cpp18
-rw-r--r--modules/gltf/register_types.cpp6
-rw-r--r--modules/hdr/image_loader_hdr.cpp2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp4
-rw-r--r--platform/linuxbsd/display_server_x11.cpp2
-rw-r--r--platform/osx/display_server_osx.mm2
-rw-r--r--platform/windows/display_server_windows.cpp2
-rw-r--r--scene/3d/camera_3d.cpp4
-rw-r--r--scene/3d/lightmap_gi.cpp2
-rw-r--r--scene/3d/node_3d.cpp10
-rw-r--r--scene/animation/animation_tree.cpp61
-rw-r--r--scene/animation/animation_tree.h3
-rw-r--r--scene/gui/popup_menu.cpp21
-rw-r--r--scene/gui/popup_menu.h3
-rw-r--r--scene/gui/rich_text_label.cpp11
-rw-r--r--scene/resources/animation.cpp2
-rw-r--r--scene/resources/animation_library.cpp2
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp14
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp12
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp16
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp16
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp6
-rw-r--r--tests/core/math/test_color.h8
61 files changed, 624 insertions, 269 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 53c58084ac..892b74c26a 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -1072,7 +1072,6 @@ Error File::open_compressed(const String &p_path, ModeFlags p_mode_flags, Compre
}
Error File::open(const String &p_path, ModeFlags p_mode_flags) {
- close();
Error err;
f = FileAccess::open(p_path, p_mode_flags, &err);
if (f.is_valid()) {
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index b5b340731d..a312ce4ebd 100644
--- a/core/extension/gdnative_interface.cpp
+++ b/core/extension/gdnative_interface.cpp
@@ -241,6 +241,13 @@ static GDNativeBool gdnative_variant_booleanize(const GDNativeVariantPtr p_self)
return self->booleanize();
}
+static void gdnative_variant_sub(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, GDNativeVariantPtr r_dst) {
+ const Variant *a = (const Variant *)p_a;
+ const Variant *b = (const Variant *)p_b;
+ memnew_placement(r_dst, Variant);
+ Variant::sub(*a, *b, *(Variant *)r_dst);
+}
+
static void gdnative_variant_blend(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst) {
const Variant *a = (const Variant *)p_a;
const Variant *b = (const Variant *)p_b;
@@ -939,6 +946,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.variant_iter_get = gdnative_variant_iter_get;
gdni.variant_hash_compare = gdnative_variant_hash_compare;
gdni.variant_booleanize = gdnative_variant_booleanize;
+ gdni.variant_sub = gdnative_variant_sub;
gdni.variant_blend = gdnative_variant_blend;
gdni.variant_interpolate = gdnative_variant_interpolate;
gdni.variant_duplicate = gdnative_variant_duplicate;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index 732a1b5af0..2bac52dc4a 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -416,6 +416,7 @@ typedef struct {
void (*variant_iter_get)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_iter, GDNativeVariantPtr r_ret, GDNativeBool *r_valid);
GDNativeBool (*variant_hash_compare)(const GDNativeVariantPtr p_self, const GDNativeVariantPtr p_other);
GDNativeBool (*variant_booleanize)(const GDNativeVariantPtr p_self);
+ void (*variant_sub)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, GDNativeVariantPtr r_dst);
void (*variant_blend)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst);
void (*variant_interpolate)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst);
void (*variant_duplicate)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep);
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 343076b4e1..0db20a7c82 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -855,6 +855,8 @@ void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, co
return;
}
+ ERR_FAIL_INDEX(p_shape, CursorShape::CURSOR_MAX);
+
set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
}
diff --git a/core/io/image.cpp b/core/io/image.cpp
index fad9942017..4aed5a913a 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -3276,7 +3276,7 @@ Ref<Image> Image::rgbe_to_srgb() {
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
- new_image->set_pixel(col, row, get_pixel(col, row).to_srgb());
+ new_image->set_pixel(col, row, get_pixel(col, row).linear_to_srgb());
}
}
diff --git a/core/math/color.h b/core/math/color.h
index b90a0f33a2..91e0bf5532 100644
--- a/core/math/color.h
+++ b/core/math/color.h
@@ -169,14 +169,14 @@ struct _NO_DISCARD_ Color {
return res;
}
- _FORCE_INLINE_ Color to_linear() const {
+ _FORCE_INLINE_ Color srgb_to_linear() const {
return Color(
r < 0.04045f ? r * (1.0 / 12.92) : Math::pow((r + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f),
g < 0.04045f ? g * (1.0 / 12.92) : Math::pow((g + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f),
b < 0.04045f ? b * (1.0 / 12.92) : Math::pow((b + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f),
a);
}
- _FORCE_INLINE_ Color to_srgb() const {
+ _FORCE_INLINE_ Color linear_to_srgb() const {
return Color(
r < 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * Math::pow(r, 1.0f / 2.4f) - 0.055f,
g < 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * Math::pow(g, 1.0f / 2.4f) - 0.055f,
diff --git a/core/variant/variant.h b/core/variant/variant.h
index ca18249f36..475bf7158d 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -511,6 +511,7 @@ public:
Variant recursive_duplicate(bool p_deep, int recursion_count) const;
static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
+ static void sub(const Variant &a, const Variant &b, Variant &r_dst);
/* Built-In Methods */
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index c11925fa8c..f1daf1de13 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1656,8 +1656,8 @@ static void _register_variant_builtin_methods() {
bind_method(Color, darkened, sarray("amount"), varray());
bind_method(Color, blend, sarray("over"), varray());
bind_method(Color, get_luminance, sarray(), varray());
- bind_method(Color, to_linear, sarray(), varray());
- bind_method(Color, to_srgb, sarray(), varray());
+ bind_method(Color, srgb_to_linear, sarray(), varray());
+ bind_method(Color, linear_to_srgb, sarray(), varray());
bind_method(Color, is_equal_approx, sarray("to"), varray());
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index e604ff9567..705aa27be6 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -1868,6 +1868,110 @@ Variant Variant::recursive_duplicate(bool p_deep, int recursion_count) const {
}
}
+void Variant::sub(const Variant &a, const Variant &b, Variant &r_dst) {
+ if (a.type != b.type) {
+ return;
+ }
+
+ switch (a.type) {
+ case NIL: {
+ r_dst = Variant();
+ }
+ return;
+ case INT: {
+ int64_t va = a._data._int;
+ int64_t vb = b._data._int;
+ r_dst = int(va - vb);
+ }
+ return;
+ case FLOAT: {
+ double ra = a._data._float;
+ double rb = b._data._float;
+ r_dst = ra - rb;
+ }
+ return;
+ case VECTOR2: {
+ r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) - *reinterpret_cast<const Vector2 *>(b._data._mem);
+ }
+ return;
+ case VECTOR2I: {
+ int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x;
+ int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x;
+ int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y;
+ int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y;
+ r_dst = Vector2i(int32_t(vax - vbx), int32_t(vay - vby));
+ }
+ return;
+ case RECT2: {
+ const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem);
+ const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem);
+ r_dst = Rect2(ra->position - rb->position, ra->size - rb->size);
+ }
+ return;
+ case RECT2I: {
+ const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem);
+ const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem);
+
+ int32_t vax = ra->position.x;
+ int32_t vay = ra->position.y;
+ int32_t vbx = ra->size.x;
+ int32_t vby = ra->size.y;
+ int32_t vcx = rb->position.x;
+ int32_t vcy = rb->position.y;
+ int32_t vdx = rb->size.x;
+ int32_t vdy = rb->size.y;
+
+ r_dst = Rect2i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vcx - vdx), int32_t(vcy - vdy));
+ }
+ return;
+ case VECTOR3: {
+ r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) - *reinterpret_cast<const Vector3 *>(b._data._mem);
+ }
+ return;
+ case VECTOR3I: {
+ int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x;
+ int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x;
+ int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y;
+ int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y;
+ int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z;
+ int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z;
+ r_dst = Vector3i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vaz - vbz));
+ }
+ return;
+ case AABB: {
+ const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem);
+ const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem);
+ r_dst = ::AABB(ra->position - rb->position, ra->size - rb->size);
+ }
+ return;
+ case QUATERNION: {
+ Quaternion empty_rot;
+ const Quaternion *qa = reinterpret_cast<const Quaternion *>(a._data._mem);
+ const Quaternion *qb = reinterpret_cast<const Quaternion *>(b._data._mem);
+ r_dst = (*qb).inverse() * *qa;
+ }
+ return;
+ case COLOR: {
+ const Color *ca = reinterpret_cast<const Color *>(a._data._mem);
+ const Color *cb = reinterpret_cast<const Color *>(b._data._mem);
+ float new_r = ca->r - cb->r;
+ float new_g = ca->g - cb->g;
+ float new_b = ca->b - cb->b;
+ float new_a = ca->a - cb->a;
+ new_r = new_r > 1.0 ? 1.0 : new_r;
+ new_g = new_g > 1.0 ? 1.0 : new_g;
+ new_b = new_b > 1.0 ? 1.0 : new_b;
+ new_a = new_a > 1.0 ? 1.0 : new_a;
+ r_dst = Color(new_r, new_g, new_b, new_a);
+ }
+ return;
+ default: {
+ r_dst = a;
+ }
+ return;
+ }
+}
+
void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) {
if (a.type != b.type) {
if (a.is_num() && b.is_num()) {
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index f7a0d41626..5008cd826e 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -192,7 +192,7 @@
The camera's projection mode. In [constant PROJECTION_PERSPECTIVE] mode, objects' Z distance from the camera's local space scales their perceived size.
</member>
<member name="size" type="float" setter="set_size" getter="get_size" default="1.0">
- The camera's size measured as 1/2 the width or height. Only applicable in orthogonal mode. Since [member keep_aspect] locks on axis, [code]size[/code] sets the other axis' size length.
+ The camera's size measured as 1/2 the width or height. Only applicable in orthogonal and frustum modes. Since [member keep_aspect] locks on axis, [code]size[/code] sets the other axis' size length.
</member>
<member name="v_offset" type="float" setter="set_v_offset" getter="get_v_offset" default="0.0">
The vertical (Y) offset of the camera viewport.
diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml
index 99bf9f7853..5d025985cc 100644
--- a/doc/classes/CollisionObject2D.xml
+++ b/doc/classes/CollisionObject2D.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
CollisionObject2D is the base class for 2D physics objects. It can hold any number of 2D collision [Shape2D]s. Each shape must be assigned to a [i]shape owner[/i]. The CollisionObject2D can have any number of shape owners. Shape owners are not nodes and do not appear in the editor, but are accessible through code using the [code]shape_owner_*[/code] methods.
+ [b]Note:[/b] Only collisions between objects within the same canvas ([Viewport] canvas or [CanvasLayer]) are supported. The behavior of collisions between objects in different canvases is undefined.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index 5b48804d9d..7b8a57ed22 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -183,7 +183,7 @@
<description>
Returns the luminance of the color in the [code][0.0, 1.0][/code] range.
This is useful when determining light or dark color. Colors with a luminance smaller than 0.5 can be generally considered dark.
- [b]Note:[/b] [method get_luminance] relies on the colour being in the linear color space to return an accurate relative luminance value. If the color is in the sRGB color space, use [method to_linear] to convert it to the linear color space first.
+ [b]Note:[/b] [method get_luminance] relies on the colour being in the linear color space to return an accurate relative luminance value. If the color is in the sRGB color space, use [method srgb_to_linear] to convert it to the linear color space first.
</description>
</method>
<method name="get_named_color" qualifiers="static">
@@ -321,6 +321,18 @@
[/codeblocks]
</description>
</method>
+ <method name="linear_to_srgb" qualifiers="const">
+ <return type="Color" />
+ <description>
+ Returns the color converted to the [url=https://en.wikipedia.org/wiki/SRGB]sRGB[/url] color space. This assumes the original color is in the linear color space. See also [method srgb_to_linear] which performs the opposite operation.
+ </description>
+ </method>
+ <method name="srgb_to_linear" qualifiers="const">
+ <return type="Color" />
+ <description>
+ Returns the color converted to the linear color space. This assumes the original color is in the sRGB color space. See also [method linear_to_srgb] which performs the opposite operation.
+ </description>
+ </method>
<method name="to_abgr32" qualifiers="const">
<return type="int" />
<description>
@@ -405,12 +417,6 @@
[/codeblocks]
</description>
</method>
- <method name="to_linear" qualifiers="const">
- <return type="Color" />
- <description>
- Returns the color converted to the linear color space. This assumes the original color is in the sRGB color space. See also [method to_srgb] which performs the opposite operation.
- </description>
- </method>
<method name="to_rgba32" qualifiers="const">
<return type="int" />
<description>
@@ -443,12 +449,6 @@
[/codeblocks]
</description>
</method>
- <method name="to_srgb" qualifiers="const">
- <return type="Color" />
- <description>
- Returns the color converted to the [url=https://en.wikipedia.org/wiki/SRGB]sRGB[/url] color space. This assumes the original color is in the linear color space. See also [method to_linear] which performs the opposite operation.
- </description>
- </method>
</methods>
<members>
<member name="a" type="float" setter="" getter="" default="1.0">
diff --git a/doc/classes/EditorSceneFormatImporter.xml b/doc/classes/EditorSceneFormatImporter.xml
index 63c1498f20..0290d7207d 100644
--- a/doc/classes/EditorSceneFormatImporter.xml
+++ b/doc/classes/EditorSceneFormatImporter.xml
@@ -29,16 +29,8 @@
<method name="_get_option_visibility" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="path" type="String" />
- <argument index="1" name="option" type="String" />
- <description>
- </description>
- </method>
- <method name="_import_animation" qualifiers="virtual">
- <return type="Animation" />
- <argument index="0" name="path" type="String" />
- <argument index="1" name="flags" type="int" />
- <argument index="2" name="options" type="Dictionary" />
- <argument index="3" name="bake_fps" type="int" />
+ <argument index="1" name="for_animation" type="bool" />
+ <argument index="2" name="option" type="String" />
<description>
</description>
</method>
@@ -63,5 +55,7 @@
</constant>
<constant name="IMPORT_USE_NAMED_SKIN_BINDS" value="16">
</constant>
+ <constant name="IMPORT_DISCARD_MESHES_AND_MATERIALS" value="32">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/EditorScenePostImportPlugin.xml b/doc/classes/EditorScenePostImportPlugin.xml
index de9d5e067a..0fdbd5db1e 100644
--- a/doc/classes/EditorScenePostImportPlugin.xml
+++ b/doc/classes/EditorScenePostImportPlugin.xml
@@ -34,7 +34,8 @@
<method name="_get_internal_option_visibility" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="category" type="int" />
- <argument index="1" name="option" type="String" />
+ <argument index="1" name="for_animation" type="bool" />
+ <argument index="2" name="option" type="String" />
<description>
Return true or false whether a given option should be visible. Return null to ignore.
</description>
@@ -42,7 +43,8 @@
<method name="_get_option_visibility" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="path" type="String" />
- <argument index="1" name="option" type="String" />
+ <argument index="1" name="for_animation" type="bool" />
+ <argument index="2" name="option" type="String" />
<description>
Return true or false whether a given option should be visible. Return null to ignore.
</description>
diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml
index c5855e30a4..049e7f8777 100644
--- a/doc/classes/Signal.xml
+++ b/doc/classes/Signal.xml
@@ -6,6 +6,8 @@
<description>
</description>
<tutorials>
+ <link title="Using Signals">$DOCS_URL/getting_started/step_by_step/signals.html</link>
+ <link title="GDScript Basics">$DOCS_URL/tutorials/scripting/gdscript/gdscript_basics.html#signals</link>
</tutorials>
<constructors>
<constructor name="Signal">
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 53631c1e3b..685dde4d98 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -2252,6 +2252,8 @@ void AnimationTrackEdit::_notification(int p_what) {
break;
case NOTIFICATION_MOUSE_EXIT:
hovered = false;
+ // When the mouse cursor exits the track, we're no longer hovering any keyframe.
+ hovering_key_idx = -1;
update();
[[fallthrough]];
case NOTIFICATION_DRAG_END: {
@@ -2365,7 +2367,13 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
}
}
- draw_texture(icon_to_draw, ofs);
+ // Use a different color for the currently hovered key.
+ // The color multiplier is chosen to work with both dark and light editor themes,
+ // and on both unselected and selected key icons.
+ draw_texture(
+ icon_to_draw,
+ ofs,
+ p_index == hovering_key_idx ? get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")) : Color(1, 1, 1));
}
// Helper.
@@ -2952,6 +2960,59 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
+ const int previous_hovering_key_idx = hovering_key_idx;
+
+ // Hovering compressed keyframes for editing is not possible.
+ if (!animation->track_is_compressed(track)) {
+ const float scale = timeline->get_zoom_scale();
+ const int limit = timeline->get_name_limit();
+ const int limit_end = get_size().width - timeline->get_buttons_width();
+ // Left Border including space occupied by keyframes on t=0.
+ const int limit_start_hitbox = limit - type_icon->get_width();
+ const Point2 pos = mm->get_position();
+
+ if (pos.x >= limit_start_hitbox && pos.x <= limit_end) {
+ // Use the same logic as key selection to ensure that hovering accurately represents
+ // which key will be selected when clicking.
+ int key_idx = -1;
+ float key_distance = 1e20;
+
+ hovering_key_idx = -1;
+
+ // Hovering should happen in the opposite order of drawing for more accurate overlap hovering.
+ for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) {
+ Rect2 rect = get_key_rect(i, scale);
+ float offset = animation->track_get_key_time(track, i) - timeline->get_value();
+ offset = offset * scale + limit;
+ rect.position.x += offset;
+
+ if (rect.has_point(pos)) {
+ if (is_key_selectable_by_distance()) {
+ const float distance = ABS(offset - pos.x);
+ if (key_idx == -1 || distance < key_distance) {
+ key_idx = i;
+ key_distance = distance;
+ hovering_key_idx = i;
+ }
+ } else {
+ // First one does it.
+ hovering_key_idx = i;
+ break;
+ }
+ }
+ }
+
+ print_line(hovering_key_idx);
+
+ if (hovering_key_idx != previous_hovering_key_idx) {
+ // Required to draw keyframe hover feedback on the correct keyframe.
+ update();
+ }
+ }
+ }
+ }
+
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && moving_selection_attempt) {
if (!moving_selection) {
moving_selection = true;
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index a8a5d11c12..0f6d12b4d4 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -173,6 +173,7 @@ class AnimationTrackEdit : public Control {
bool hovered = false;
bool clicking_on_name = false;
+ int hovering_key_idx = -1;
void _zoom_changed();
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 99e30593a9..6fe6309eed 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5997,18 +5997,22 @@ EditorNode::EditorNode() {
import_scene.instantiate();
ResourceFormatImporter::get_singleton()->add_importer(import_scene);
+ Ref<ResourceImporterScene> import_animation;
+ import_animation = Ref<ResourceImporterScene>(memnew(ResourceImporterScene(true)));
+ ResourceFormatImporter::get_singleton()->add_importer(import_animation);
+
{
Ref<EditorSceneFormatImporterCollada> import_collada;
import_collada.instantiate();
- import_scene->add_importer(import_collada);
+ ResourceImporterScene::add_importer(import_collada);
Ref<EditorOBJImporter> import_obj2;
import_obj2.instantiate();
- import_scene->add_importer(import_obj2);
+ ResourceImporterScene::add_importer(import_obj2);
Ref<EditorSceneFormatImporterESCN> import_escn;
import_escn.instantiate();
- import_scene->add_importer(import_escn);
+ ResourceImporterScene::add_importer(import_escn);
}
Ref<ResourceImporterBitMap> import_bitmap;
@@ -7245,6 +7249,7 @@ EditorNode::EditorNode() {
EditorNode::~EditorNode() {
EditorInspector::cleanup_plugins();
EditorTranslationParser::get_singleton()->clean_parsers();
+ ResourceImporterScene::clean_up_importer_plugins();
remove_print_handler(&print_handler);
EditorHelp::cleanup_doc();
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 5166200ee3..6596c245bc 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -763,20 +763,20 @@ void EditorPlugin::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_p
void EditorPlugin::add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer, bool p_first_priority) {
ERR_FAIL_COND(!p_importer.is_valid());
- ResourceImporterScene::get_singleton()->add_importer(p_importer, p_first_priority);
+ ResourceImporterScene::add_importer(p_importer, p_first_priority);
}
void EditorPlugin::remove_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer) {
ERR_FAIL_COND(!p_importer.is_valid());
- ResourceImporterScene::get_singleton()->remove_importer(p_importer);
+ ResourceImporterScene::remove_importer(p_importer);
}
void EditorPlugin::add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority) {
- ResourceImporterScene::get_singleton()->add_post_importer_plugin(p_plugin, p_first_priority);
+ ResourceImporterScene::add_post_importer_plugin(p_plugin, p_first_priority);
}
void EditorPlugin::remove_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) {
- ResourceImporterScene::get_singleton()->remove_post_importer_plugin(p_plugin);
+ ResourceImporterScene::remove_post_importer_plugin(p_plugin);
}
int find(const PackedStringArray &a, const String &v) {
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index a45568db48..778c5c33ff 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -989,7 +989,7 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit
{
List<String> importer_exts;
- ResourceImporterScene::get_singleton()->get_recognized_extensions(&importer_exts);
+ ResourceImporterScene::get_scene_singleton()->get_recognized_extensions(&importer_exts);
String extension = fpath.get_extension();
for (const String &E : importer_exts) {
if (extension.nocasecmp_to(E) == 0) {
@@ -1000,7 +1000,27 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit
}
if (is_imported) {
- ResourceImporterScene::get_singleton()->show_advanced_options(fpath);
+ ResourceImporterScene::get_scene_singleton()->show_advanced_options(fpath);
+ } else {
+ EditorNode::get_singleton()->open_request(fpath);
+ }
+ } else if (ResourceLoader::get_resource_type(fpath) == "AnimationLibrary") {
+ bool is_imported = false;
+
+ {
+ List<String> importer_exts;
+ ResourceImporterScene::get_animation_singleton()->get_recognized_extensions(&importer_exts);
+ String extension = fpath.get_extension();
+ for (const String &E : importer_exts) {
+ if (extension.nocasecmp_to(E) == 0) {
+ is_imported = true;
+ break;
+ }
+ }
+ }
+
+ if (is_imported) {
+ ResourceImporterScene::get_animation_singleton()->show_advanced_options(fpath);
} else {
EditorNode::get_singleton()->open_request(fpath);
}
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 97fc33ad25..013dcb5deb 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -1817,26 +1817,5 @@ 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, const Map<StringName, Variant> &p_options, int p_bake_fps) {
- ColladaImport state;
-
- state.use_mesh_builtin_materials = false;
-
- Error err = state.load(p_path, Collada::IMPORT_FLAG_ANIMATION, p_flags & EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS);
- ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load animation from file '" + p_path + "'.");
-
- state.create_animations(true);
- if (state.scene) {
- memdelete(state.scene);
- }
-
- if (state.animations.size() == 0) {
- return Ref<Animation>();
- }
- Ref<Animation> anim = state.animations[0];
-
- return anim;
-}
-
EditorSceneFormatImporterCollada::EditorSceneFormatImporterCollada() {
}
diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h
index c32d785d1c..be3f74d821 100644
--- a/editor/import/editor_import_collada.h
+++ b/editor/import/editor_import_collada.h
@@ -40,7 +40,6 @@ 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, 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 308eb9cefa..88837d089a 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -457,10 +457,6 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, co
return scene;
}
-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>();
-}
-
void EditorOBJImporter::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("obj");
}
diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h
index d7e3f0209d..1b5e8bbdc1 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -40,7 +40,6 @@ 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, 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 bfa71bfda4..bdb0c3c493 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -87,26 +87,13 @@ Node *EditorSceneFormatImporter::import_scene(const String &p_path, uint32_t p_f
ERR_FAIL_V(nullptr);
}
-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, options_dict, p_bake_fps, ret)) {
- return ret;
- }
-
- ERR_FAIL_V(nullptr);
-}
-
void EditorSceneFormatImporter::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
GDVIRTUAL_CALL(_get_import_options, p_path);
}
-Variant EditorSceneFormatImporter::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) {
+Variant EditorSceneFormatImporter::get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options) {
Variant ret;
- GDVIRTUAL_CALL(_get_option_visibility, p_path, p_option, ret);
+ GDVIRTUAL_CALL(_get_option_visibility, p_path, p_for_animation, p_option, ret);
return ret;
}
@@ -114,15 +101,15 @@ void EditorSceneFormatImporter::_bind_methods() {
GDVIRTUAL_BIND(_get_import_flags);
GDVIRTUAL_BIND(_get_extensions);
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");
+ GDVIRTUAL_BIND(_get_option_visibility, "path", "for_animation", "option");
BIND_CONSTANT(IMPORT_SCENE);
BIND_CONSTANT(IMPORT_ANIMATION);
BIND_CONSTANT(IMPORT_FAIL_ON_MISSING_DEPENDENCIES);
BIND_CONSTANT(IMPORT_GENERATE_TANGENT_ARRAYS);
BIND_CONSTANT(IMPORT_USE_NAMED_SKIN_BINDS);
+ BIND_CONSTANT(IMPORT_DISCARD_MESHES_AND_MATERIALS);
}
/////////////////////////////////
@@ -179,10 +166,10 @@ void EditorScenePostImportPlugin::get_internal_import_options(InternalImportCate
GDVIRTUAL_CALL(_get_internal_import_options, p_category);
current_option_list = nullptr;
}
-Variant EditorScenePostImportPlugin::get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const {
+Variant EditorScenePostImportPlugin::get_internal_option_visibility(InternalImportCategory p_category, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options) const {
current_options = &p_options;
Variant ret;
- GDVIRTUAL_CALL(_get_internal_option_visibility, p_category, p_option, ret);
+ GDVIRTUAL_CALL(_get_internal_option_visibility, p_category, p_for_animation, p_option, ret);
current_options = nullptr;
return ret;
}
@@ -205,10 +192,10 @@ void EditorScenePostImportPlugin::get_import_options(const String &p_path, List<
GDVIRTUAL_CALL(_get_import_options, p_path);
current_option_list = nullptr;
}
-Variant EditorScenePostImportPlugin::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
+Variant EditorScenePostImportPlugin::get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options) const {
current_options = &p_options;
Variant ret;
- GDVIRTUAL_CALL(_get_option_visibility, p_path, p_option, ret);
+ GDVIRTUAL_CALL(_get_option_visibility, p_path, p_for_animation, p_option, ret);
current_options = nullptr;
return ret;
}
@@ -231,11 +218,11 @@ void EditorScenePostImportPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_import_option_advanced", "type", "name", "default_value", "hint", "hint_string", "usage_flags"), &EditorScenePostImportPlugin::add_import_option_advanced, DEFVAL(PROPERTY_HINT_NONE), DEFVAL(""), DEFVAL(PROPERTY_USAGE_DEFAULT));
GDVIRTUAL_BIND(_get_internal_import_options, "category");
- GDVIRTUAL_BIND(_get_internal_option_visibility, "category", "option");
+ GDVIRTUAL_BIND(_get_internal_option_visibility, "category", "for_animation", "option");
GDVIRTUAL_BIND(_get_internal_option_update_view_required, "category", "option");
GDVIRTUAL_BIND(_internal_process, "category", "base_node", "node", "resource");
GDVIRTUAL_BIND(_get_import_options, "path");
- GDVIRTUAL_BIND(_get_option_visibility, "path", "option");
+ GDVIRTUAL_BIND(_get_option_visibility, "path", "for_animation", "option");
GDVIRTUAL_BIND(_pre_process, "scene");
GDVIRTUAL_BIND(_post_process, "scene");
@@ -251,11 +238,11 @@ void EditorScenePostImportPlugin::_bind_methods() {
/////////////////////////////////////////////////////////
String ResourceImporterScene::get_importer_name() const {
- return "scene";
+ return animation_importer ? "animation_library" : "scene";
}
String ResourceImporterScene::get_visible_name() const {
- return "Scene";
+ return animation_importer ? "Animation Library" : "Scene";
}
void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const {
@@ -265,11 +252,11 @@ void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions
}
String ResourceImporterScene::get_save_extension() const {
- return "scn";
+ return animation_importer ? "res" : "scn";
}
String ResourceImporterScene::get_resource_type() const {
- return "PackedScene";
+ return animation_importer ? "AnimationLibrary" : "PackedScene";
}
int ResourceImporterScene::get_format_version() const {
@@ -277,26 +264,34 @@ int ResourceImporterScene::get_format_version() const {
}
bool ResourceImporterScene::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
- if (p_option.begins_with("animation/")) {
+ if (animation_importer) {
+ if (p_option == "animation/import") { // Option ignored, animation always imported.
+ return false;
+ }
+ } else if (p_option.begins_with("animation/")) {
if (p_option != "animation/import" && !bool(p_options["animation/import"])) {
return false;
}
}
+ if (animation_importer && (p_option.begins_with("nodes/") || p_option.begins_with("meshes/") || p_option.begins_with("skins/"))) {
+ return false; // Nothing to do here for animations.
+ }
+
if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) != 2) {
// Only display the lightmap texel size import option when using the Static Lightmaps light baking mode.
return false;
}
for (int i = 0; i < post_importer_plugins.size(); i++) {
- Variant ret = post_importer_plugins.write[i]->get_option_visibility(p_path, p_option, p_options);
+ Variant ret = post_importer_plugins.write[i]->get_option_visibility(p_path, animation_importer, p_option, p_options);
if (ret.get_type() == Variant::BOOL) {
return ret;
}
}
for (Ref<EditorSceneFormatImporter> importer : importers) {
- Variant ret = importer->get_option_visibility(p_path, p_option, p_options);
+ Variant ret = importer->get_option_visibility(p_path, animation_importer, p_option, p_options);
if (ret.get_type() == Variant::BOOL) {
return ret;
}
@@ -1482,7 +1477,7 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
}
for (int i = 0; i < post_importer_plugins.size(); i++) {
- Variant ret = post_importer_plugins.write[i]->get_internal_option_visibility(EditorScenePostImportPlugin::InternalImportCategory(p_category), p_option, p_options);
+ Variant ret = post_importer_plugins.write[i]->get_internal_option_visibility(EditorScenePostImportPlugin::InternalImportCategory(p_category), animation_importer, p_option, p_options);
if (ret.get_type() == Variant::BOOL) {
return ret;
}
@@ -1974,8 +1969,13 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
int import_flags = 0;
- if (bool(p_options["animation/import"])) {
+ if (animation_importer) {
import_flags |= EditorSceneFormatImporter::IMPORT_ANIMATION;
+ import_flags |= EditorSceneFormatImporter::IMPORT_DISCARD_MESHES_AND_MATERIALS;
+ } else {
+ if (bool(p_options["animation/import"])) {
+ import_flags |= EditorSceneFormatImporter::IMPORT_ANIMATION;
+ }
}
if (bool(p_options["skins/use_named_skins"])) {
@@ -2139,11 +2139,35 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
progress.step(TTR("Saving..."), 104);
- Ref<PackedScene> packer = memnew(PackedScene);
- packer->pack(scene);
- print_verbose("Saving scene to: " + p_save_path + ".scn");
- err = ResourceSaver::save(p_save_path + ".scn", packer); //do not take over, let the changed files reload themselves
- ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save scene to file '" + p_save_path + ".scn'.");
+ if (animation_importer) {
+ Ref<AnimationLibrary> library;
+ for (int i = 0; i < scene->get_child_count(); i++) {
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(scene->get_child(i));
+ if (ap) {
+ List<StringName> libs;
+ ap->get_animation_library_list(&libs);
+ if (libs.size()) {
+ library = ap->get_animation_library(libs.front()->get());
+ break;
+ }
+ }
+ }
+
+ if (!library.is_valid()) {
+ library.instantiate(); // Will be empty
+ }
+
+ print_verbose("Saving animation to: " + p_save_path + ".scn");
+ err = ResourceSaver::save(p_save_path + ".res", library); //do not take over, let the changed files reload themselves
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save animation to file '" + p_save_path + ".res'.");
+
+ } else {
+ Ref<PackedScene> packer = memnew(PackedScene);
+ packer->pack(scene);
+ print_verbose("Saving scene to: " + p_save_path + ".scn");
+ err = ResourceSaver::save(p_save_path + ".scn", packer); //do not take over, let the changed files reload themselves
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save scene to file '" + p_save_path + ".scn'.");
+ }
memdelete(scene);
@@ -2153,17 +2177,26 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
return OK;
}
-ResourceImporterScene *ResourceImporterScene::singleton = nullptr;
+ResourceImporterScene *ResourceImporterScene::scene_singleton = nullptr;
+ResourceImporterScene *ResourceImporterScene::animation_singleton = nullptr;
+
+Vector<Ref<EditorSceneFormatImporter>> ResourceImporterScene::importers;
+Vector<Ref<EditorScenePostImportPlugin>> ResourceImporterScene::post_importer_plugins;
bool ResourceImporterScene::ResourceImporterScene::has_advanced_options() const {
return true;
}
void ResourceImporterScene::ResourceImporterScene::show_advanced_options(const String &p_path) {
- SceneImportSettings::get_singleton()->open_settings(p_path);
+ SceneImportSettings::get_singleton()->open_settings(p_path, animation_importer);
}
-ResourceImporterScene::ResourceImporterScene() {
- singleton = this;
+ResourceImporterScene::ResourceImporterScene(bool p_animation_import) {
+ if (p_animation_import) {
+ animation_singleton = this;
+ } else {
+ scene_singleton = this;
+ }
+ animation_importer = p_animation_import;
}
void ResourceImporterScene::add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority) {
@@ -2192,6 +2225,11 @@ void ResourceImporterScene::remove_importer(Ref<EditorSceneFormatImporter> p_imp
importers.erase(p_importer);
}
+void ResourceImporterScene::clean_up_importer_plugins() {
+ importers.clear();
+ post_importer_plugins.clear();
+}
+
///////////////////////////////////////
uint32_t EditorSceneFormatImporterESCN::get_import_flags() const {
@@ -2212,7 +2250,3 @@ 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, 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 a819be682d..368f68ae8f 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -56,9 +56,8 @@ protected:
GDVIRTUAL0RC(int, _get_import_flags)
GDVIRTUAL0RC(Vector<String>, _get_extensions)
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)
+ GDVIRTUAL3RC(Variant, _get_option_visibility, String, bool, String)
public:
enum ImportFlags {
@@ -67,14 +66,14 @@ public:
IMPORT_FAIL_ON_MISSING_DEPENDENCIES = 4,
IMPORT_GENERATE_TANGENT_ARRAYS = 8,
IMPORT_USE_NAMED_SKIN_BINDS = 16,
+ IMPORT_DISCARD_MESHES_AND_MATERIALS = 32, //used for optimizing animation import
};
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, 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);
+ virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options);
EditorSceneFormatImporter() {}
};
@@ -118,11 +117,11 @@ private:
protected:
GDVIRTUAL1(_get_internal_import_options, int)
- GDVIRTUAL2RC(Variant, _get_internal_option_visibility, int, String)
+ GDVIRTUAL3RC(Variant, _get_internal_option_visibility, int, bool, String)
GDVIRTUAL2RC(Variant, _get_internal_option_update_view_required, int, String)
GDVIRTUAL4(_internal_process, int, Node *, Node *, RES)
GDVIRTUAL1(_get_import_options, String)
- GDVIRTUAL2RC(Variant, _get_option_visibility, String, String)
+ GDVIRTUAL3RC(Variant, _get_option_visibility, String, bool, String)
GDVIRTUAL1(_pre_process, Node *)
GDVIRTUAL1(_post_process, Node *)
@@ -134,13 +133,13 @@ public:
void add_import_option_advanced(Variant::Type p_type, const String &p_name, Variant p_default_value, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = String(), int p_usage_flags = PROPERTY_USAGE_DEFAULT);
virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options);
- virtual Variant get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;
+ virtual Variant get_internal_option_visibility(InternalImportCategory p_category, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options) const;
virtual Variant get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;
virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, RES p_resource, const Dictionary &p_options);
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) const;
+ virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options) const;
virtual void pre_process(Node *p_scene, const Map<StringName, Variant> &p_options);
virtual void post_process(Node *p_scene, const Map<StringName, Variant> &p_options);
@@ -153,9 +152,11 @@ VARIANT_ENUM_CAST(EditorScenePostImportPlugin::InternalImportCategory)
class ResourceImporterScene : public ResourceImporter {
GDCLASS(ResourceImporterScene, ResourceImporter);
- Vector<Ref<EditorSceneFormatImporter>> importers;
+ static Vector<Ref<EditorSceneFormatImporter>> importers;
+ static Vector<Ref<EditorScenePostImportPlugin>> post_importer_plugins;
- static ResourceImporterScene *singleton;
+ static ResourceImporterScene *scene_singleton;
+ static ResourceImporterScene *animation_singleton;
enum LightBakeMode {
LIGHT_BAKE_DISABLED,
@@ -225,18 +226,21 @@ class ResourceImporterScene : public ResourceImporter {
void _optimize_track_usage(AnimationPlayer *p_player, AnimationImportTracks *p_track_actions);
- mutable Vector<Ref<EditorScenePostImportPlugin>> post_importer_plugins;
+ bool animation_importer = false;
public:
- static ResourceImporterScene *get_singleton() { return singleton; }
+ static ResourceImporterScene *get_scene_singleton() { return scene_singleton; }
+ static ResourceImporterScene *get_animation_singleton() { return animation_singleton; }
- void add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority = false);
- void remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin);
+ static void add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority = false);
+ static void remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin);
const Vector<Ref<EditorSceneFormatImporter>> &get_importers() const { return importers; }
- void add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority = false);
- void remove_importer(Ref<EditorSceneFormatImporter> p_importer);
+ static void add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority = false);
+ static void remove_importer(Ref<EditorSceneFormatImporter> p_importer);
+
+ static void clean_up_importer_plugins();
virtual String get_importer_name() const override;
virtual String get_visible_name() const override;
@@ -283,7 +287,7 @@ public:
virtual bool can_import_threaded() const override { return false; }
- ResourceImporterScene();
+ ResourceImporterScene(bool p_animation_import = false);
template <class M>
static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options);
@@ -299,7 +303,6 @@ 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, 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/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp
index 302bc98499..4e53a644ee 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -47,6 +47,8 @@ class SceneImportSettingsData : public Object {
Map<StringName, Variant> current;
Map<StringName, Variant> defaults;
List<ResourceImporter::ImportOption> options;
+ bool hide_options = false;
+ String path;
ResourceImporterScene::InternalImportCategory category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX;
@@ -60,8 +62,26 @@ class SceneImportSettingsData : public Object {
current[p_name] = p_value;
- if (ResourceImporterScene::get_singleton()->get_internal_option_update_view_required(category, p_name, current)) {
- SceneImportSettings::get_singleton()->update_view();
+ if (SceneImportSettings::get_singleton()->is_editing_animation()) {
+ if (category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
+ if (ResourceImporterScene::get_animation_singleton()->get_option_visibility(path, p_name, current)) {
+ SceneImportSettings::get_singleton()->update_view();
+ }
+ } else {
+ if (ResourceImporterScene::get_animation_singleton()->get_internal_option_update_view_required(category, p_name, current)) {
+ SceneImportSettings::get_singleton()->update_view();
+ }
+ }
+ } else {
+ if (category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
+ if (ResourceImporterScene::get_scene_singleton()->get_option_visibility(path, p_name, current)) {
+ SceneImportSettings::get_singleton()->update_view();
+ }
+ } else {
+ if (ResourceImporterScene::get_scene_singleton()->get_internal_option_update_view_required(category, p_name, current)) {
+ SceneImportSettings::get_singleton()->update_view();
+ }
+ }
}
return true;
@@ -82,9 +102,30 @@ class SceneImportSettingsData : public Object {
return false;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
+ if (hide_options) {
+ return;
+ }
for (const ResourceImporter::ImportOption &E : options) {
- if (ResourceImporterScene::get_singleton()->get_internal_option_visibility(category, E.option.name, current)) {
- p_list->push_back(E.option);
+ if (SceneImportSettings::get_singleton()->is_editing_animation()) {
+ if (category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
+ if (ResourceImporterScene::get_animation_singleton()->get_option_visibility(path, E.option.name, current)) {
+ p_list->push_back(E.option);
+ }
+ } else {
+ if (ResourceImporterScene::get_animation_singleton()->get_internal_option_visibility(category, E.option.name, current)) {
+ p_list->push_back(E.option);
+ }
+ }
+ } else {
+ if (category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
+ if (ResourceImporterScene::get_scene_singleton()->get_option_visibility(path, E.option.name, current)) {
+ p_list->push_back(E.option);
+ }
+ } else {
+ if (ResourceImporterScene::get_scene_singleton()->get_internal_option_visibility(category, E.option.name, current)) {
+ p_list->push_back(E.option);
+ }
+ }
}
}
}
@@ -326,7 +367,9 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
}
MeshInstance3D *mesh_node = Object::cast_to<MeshInstance3D>(p_node);
if (mesh_node && mesh_node->get_mesh().is_valid()) {
- _fill_mesh(scene_tree, mesh_node->get_mesh(), item);
+ if (!editing_animation) {
+ _fill_mesh(scene_tree, mesh_node->get_mesh(), item);
+ }
// Add the collider view.
MeshInstance3D *collider_view = memnew(MeshInstance3D);
@@ -365,6 +408,9 @@ void SceneImportSettings::_update_scene() {
}
void SceneImportSettings::_update_view_gizmos() {
+ if (!is_visible()) {
+ return;
+ }
for (const KeyValue<String, NodeData> &e : node_map) {
bool generate_collider = false;
if (e.value.settings.has(SNAME("generate/physics"))) {
@@ -378,6 +424,7 @@ void SceneImportSettings::_update_view_gizmos() {
}
TypedArray<Node> descendants = mesh_node->find_nodes("collider_view", "MeshInstance3D");
+
CRASH_COND_MSG(descendants.is_empty(), "This is unreachable, since the collider view is always created even when the collision is not used! If this is triggered there is a bug on the function `_fill_scene`.");
MeshInstance3D *collider_view = static_cast<MeshInstance3D *>(descendants[0].operator Object *());
@@ -460,7 +507,11 @@ void SceneImportSettings::_load_default_subresource_settings(Map<StringName, Var
if (d.has(p_import_id)) {
d = d[p_import_id];
List<ResourceImporterScene::ImportOption> options;
- ResourceImporterScene::get_singleton()->get_internal_import_options(p_category, &options);
+ if (editing_animation) {
+ ResourceImporterScene::get_animation_singleton()->get_internal_import_options(p_category, &options);
+ } else {
+ ResourceImporterScene::get_scene_singleton()->get_internal_import_options(p_category, &options);
+ }
for (const ResourceImporterScene::ImportOption &E : options) {
String key = E.option.name;
if (d.has(key)) {
@@ -472,21 +523,32 @@ void SceneImportSettings::_load_default_subresource_settings(Map<StringName, Var
}
void SceneImportSettings::update_view() {
- _update_view_gizmos();
+ update_view_timer->start();
}
-void SceneImportSettings::open_settings(const String &p_path) {
+void SceneImportSettings::open_settings(const String &p_path, bool p_for_animation) {
if (scene) {
memdelete(scene);
scene = nullptr;
}
+
+ editing_animation = p_for_animation;
scene_import_settings_data->settings = nullptr;
- scene = ResourceImporterScene::get_singleton()->pre_import(p_path);
+ scene_import_settings_data->path = p_path;
+
+ scene = ResourceImporterScene::get_scene_singleton()->pre_import(p_path); // Use the scene singleton here because we want to see the full thing.
if (scene == nullptr) {
EditorNode::get_singleton()->show_warning(TTR("Error opening scene"));
return;
}
+ // Visibility
+ data_mode->set_tab_hidden(1, p_for_animation);
+ data_mode->set_tab_hidden(2, p_for_animation);
+
+ action_menu->get_popup()->set_item_disabled(action_menu->get_popup()->get_item_id(ACTION_EXTRACT_MATERIALS), p_for_animation);
+ action_menu->get_popup()->set_item_disabled(action_menu->get_popup()->get_item_id(ACTION_CHOOSE_MESH_SAVE_PATHS), p_for_animation);
+
base_path = p_path;
material_set.clear();
@@ -540,7 +602,11 @@ void SceneImportSettings::open_settings(const String &p_path) {
_update_view_gizmos();
_update_camera();
- set_title(vformat(TTR("Advanced Import Settings for '%s'"), base_path.get_file()));
+ if (p_for_animation) {
+ set_title(vformat(TTR("Advanced Import Settings for AnimationLibrary '%s'"), base_path.get_file()));
+ } else {
+ set_title(vformat(TTR("Advanced Import Settings for Scene '%s'"), base_path.get_file()));
+ }
}
SceneImportSettings *SceneImportSettings::singleton = nullptr;
@@ -551,6 +617,7 @@ SceneImportSettings *SceneImportSettings::get_singleton() {
void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) {
selecting = true;
+ scene_import_settings_data->hide_options = false;
if (p_type == "Node") {
node_selected->hide(); //always hide just in case
@@ -585,10 +652,12 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) {
scene_import_settings_data->settings = &nd.settings;
if (mi) {
scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE;
+ scene_import_settings_data->hide_options = editing_animation;
} else if (Object::cast_to<AnimationPlayer>(nd.node)) {
scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE;
} else {
scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_NODE;
+ scene_import_settings_data->hide_options = editing_animation;
}
}
} else if (p_type == "Animation") {
@@ -671,24 +740,36 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) {
List<ResourceImporter::ImportOption> options;
- if (scene_import_settings_data->category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
- ResourceImporterScene::get_singleton()->get_import_options(base_path, &options);
+ if (editing_animation) {
+ if (scene_import_settings_data->category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
+ ResourceImporterScene::get_animation_singleton()->get_import_options(base_path, &options);
+ } else {
+ ResourceImporterScene::get_animation_singleton()->get_internal_import_options(scene_import_settings_data->category, &options);
+ }
+
} else {
- ResourceImporterScene::get_singleton()->get_internal_import_options(scene_import_settings_data->category, &options);
+ if (scene_import_settings_data->category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
+ ResourceImporterScene::get_scene_singleton()->get_import_options(base_path, &options);
+ } else {
+ ResourceImporterScene::get_scene_singleton()->get_internal_import_options(scene_import_settings_data->category, &options);
+ }
}
scene_import_settings_data->defaults.clear();
scene_import_settings_data->current.clear();
- for (const ResourceImporter::ImportOption &E : options) {
- scene_import_settings_data->defaults[E.option.name] = E.default_value;
- //needed for visibility toggling (fails if something is missing)
- if (scene_import_settings_data->settings->has(E.option.name)) {
- scene_import_settings_data->current[E.option.name] = (*scene_import_settings_data->settings)[E.option.name];
- } else {
- scene_import_settings_data->current[E.option.name] = E.default_value;
+ if (scene_import_settings_data->settings) {
+ for (const ResourceImporter::ImportOption &E : options) {
+ scene_import_settings_data->defaults[E.option.name] = E.default_value;
+ //needed for visibility toggling (fails if something is missing)
+ if (scene_import_settings_data->settings->has(E.option.name)) {
+ scene_import_settings_data->current[E.option.name] = (*scene_import_settings_data->settings)[E.option.name];
+ } else {
+ scene_import_settings_data->current[E.option.name] = E.default_value;
+ }
}
}
+
scene_import_settings_data->options = options;
inspector->edit(scene_import_settings_data);
scene_import_settings_data->notify_property_list_changed();
@@ -836,7 +917,7 @@ void SceneImportSettings::_re_import() {
main_settings["_subresources"] = subresources;
}
- EditorFileSystem::get_singleton()->reimport_file_with_custom_parameters(base_path, "scene", main_settings);
+ EditorFileSystem::get_singleton()->reimport_file_with_custom_parameters(base_path, editing_animation ? "animation_library" : "scene", main_settings);
}
void SceneImportSettings::_notification(int p_what) {
@@ -1282,6 +1363,11 @@ SceneImportSettings::SceneImportSettings() {
item_save_path->connect("file_selected", callable_mp(this, &SceneImportSettings::_save_path_changed));
save_path->connect("dir_selected", callable_mp(this, &SceneImportSettings::_save_dir_callback));
+
+ update_view_timer = memnew(Timer);
+ update_view_timer->set_wait_time(0.2);
+ update_view_timer->connect("timeout", callable_mp(this, &SceneImportSettings::_update_view_gizmos));
+ add_child(update_view_timer);
}
SceneImportSettings::~SceneImportSettings() {
diff --git a/editor/import/scene_import_settings.h b/editor/import/scene_import_settings.h
index 3cf708740b..55cfba3275 100644
--- a/editor/import/scene_import_settings.h
+++ b/editor/import/scene_import_settings.h
@@ -189,12 +189,17 @@ class SceneImportSettings : public ConfirmationDialog {
void _load_default_subresource_settings(Map<StringName, Variant> &settings, const String &p_type, const String &p_import_id, ResourceImporterScene::InternalImportCategory p_category);
+ bool editing_animation = false;
+
+ Timer *update_view_timer;
+
protected:
void _notification(int p_what);
public:
+ bool is_editing_animation() const { return editing_animation; }
void update_view();
- void open_settings(const String &p_path);
+ void open_settings(const String &p_path, bool p_for_animation = false);
static SceneImportSettings *get_singleton();
SceneImportSettings();
~SceneImportSettings();
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index a90e151adb..8d0db697e2 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2298,7 +2298,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
add_node_menu->reset_size();
- add_node_menu->set_position(get_screen_transform().xform(b->get_position()));
+ add_node_menu->set_position(viewport->get_screen_transform().xform(b->get_position()));
add_node_menu->popup();
node_create_position = transform.affine_inverse().xform(b->get_position());
return true;
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 855fc2b2a9..f2ca1fcfeb 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -7120,7 +7120,9 @@ void Node3DEditor::_request_gizmo(Object *p_obj) {
}
}
}
- sp->update_gizmos();
+ if (!sp->get_gizmos().is_empty()) {
+ sp->update_gizmos();
+ }
}
}
diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp
index ae05c1b68d..173d5131cf 100644
--- a/modules/gltf/editor/editor_scene_importer_blend.cpp
+++ b/modules/gltf/editor/editor_scene_importer_blend.cpp
@@ -238,13 +238,12 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_
return gltf->generate_scene(state, p_bake_fps);
}
-Ref<Animation> EditorSceneFormatImporterBlend::import_animation(const String &p_path, uint32_t p_flags,
- const Map<StringName, Variant> &p_options, int p_bake_fps) {
- return Ref<Animation>();
-}
-
-Variant EditorSceneFormatImporterBlend::get_option_visibility(const String &p_path, const String &p_option,
+Variant EditorSceneFormatImporterBlend::get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option,
const Map<StringName, Variant> &p_options) {
+ if (p_path.get_extension().to_lower() != "blend") {
+ return true;
+ }
+
if (p_option.begins_with("animation/")) {
if (p_option != "animation/import" && !bool(p_options["animation/import"])) {
return false;
@@ -254,6 +253,9 @@ Variant EditorSceneFormatImporterBlend::get_option_visibility(const String &p_pa
}
void EditorSceneFormatImporterBlend::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
+ if (p_path.get_extension().to_lower() != "blend") {
+ return;
+ }
#define ADD_OPTION_BOOL(PATH, VALUE) \
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, SNAME(PATH)), VALUE));
#define ADD_OPTION_ENUM(PATH, ENUM_HINT, VALUE) \
diff --git a/modules/gltf/editor/editor_scene_importer_blend.h b/modules/gltf/editor/editor_scene_importer_blend.h
index 9a1b5f5803..0925333a28 100644
--- a/modules/gltf/editor/editor_scene_importer_blend.h
+++ b/modules/gltf/editor/editor_scene_importer_blend.h
@@ -68,11 +68,9 @@ public:
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;
virtual void get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) override;
- virtual Variant get_option_visibility(const String &p_path, const String &p_option,
+ virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option,
const Map<StringName, Variant> &p_options) override;
};
diff --git a/modules/gltf/editor/editor_scene_importer_fbx.cpp b/modules/gltf/editor/editor_scene_importer_fbx.cpp
index 24564f55be..893d2efcec 100644
--- a/modules/gltf/editor/editor_scene_importer_fbx.cpp
+++ b/modules/gltf/editor/editor_scene_importer_fbx.cpp
@@ -105,12 +105,7 @@ Node *EditorSceneFormatImporterFBX::import_scene(const String &p_path, uint32_t
return gltf->generate_scene(state, p_bake_fps);
}
-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>();
-}
-
-Variant EditorSceneFormatImporterFBX::get_option_visibility(const String &p_path,
+Variant EditorSceneFormatImporterFBX::get_option_visibility(const String &p_path, bool p_for_animation,
const String &p_option, const Map<StringName, Variant> &p_options) {
return true;
}
diff --git a/modules/gltf/editor/editor_scene_importer_fbx.h b/modules/gltf/editor/editor_scene_importer_fbx.h
index bb69cfaa30..84de7fd1cc 100644
--- a/modules/gltf/editor/editor_scene_importer_fbx.h
+++ b/modules/gltf/editor/editor_scene_importer_fbx.h
@@ -47,11 +47,9 @@ public:
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;
virtual void get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) override;
- virtual Variant get_option_visibility(const String &p_path, const String &p_option,
+ virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option,
const Map<StringName, Variant> &p_options) override;
};
diff --git a/modules/gltf/editor/editor_scene_importer_gltf.cpp b/modules/gltf/editor/editor_scene_importer_gltf.cpp
index 1d6a82e58a..5e7811ad2b 100644
--- a/modules/gltf/editor/editor_scene_importer_gltf.cpp
+++ b/modules/gltf/editor/editor_scene_importer_gltf.cpp
@@ -64,9 +64,4 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
return doc->generate_scene(state, p_bake_fps);
}
-Ref<Animation> EditorSceneFormatImporterGLTF::import_animation(const String &p_path,
- uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
- return Ref<Animation>();
-}
-
#endif // TOOLS_ENABLED
diff --git a/modules/gltf/editor/editor_scene_importer_gltf.h b/modules/gltf/editor/editor_scene_importer_gltf.h
index 1f62ca9537..b714ada124 100644
--- a/modules/gltf/editor/editor_scene_importer_gltf.h
+++ b/modules/gltf/editor/editor_scene_importer_gltf.h
@@ -47,8 +47,6 @@ public:
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;
};
#endif // TOOLS_ENABLED
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 73222330db..784733aba2 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -3272,7 +3272,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
Dictionary mr;
{
Array arr;
- const Color c = material->get_albedo().to_linear();
+ const Color c = material->get_albedo().srgb_to_linear();
arr.push_back(c.r);
arr.push_back(c.g);
arr.push_back(c.b);
@@ -3473,7 +3473,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
}
if (material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
- const Color c = material->get_emission().to_srgb();
+ const Color c = material->get_emission().linear_to_srgb();
Array arr;
arr.push_back(c.r);
arr.push_back(c.g);
@@ -3555,7 +3555,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
if (sgm.has("diffuseFactor")) {
const Array &arr = sgm["diffuseFactor"];
ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR);
- const Color c = Color(arr[0], arr[1], arr[2], arr[3]).to_srgb();
+ const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb();
spec_gloss->diffuse_factor = c;
material->set_albedo(spec_gloss->diffuse_factor);
}
@@ -3586,7 +3586,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
if (mr.has("baseColorFactor")) {
const Array &arr = mr["baseColorFactor"];
ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR);
- const Color c = Color(arr[0], arr[1], arr[2], arr[3]).to_srgb();
+ const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb();
material->set_albedo(c);
}
@@ -3653,7 +3653,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
if (d.has("emissiveFactor")) {
const Array &arr = d["emissiveFactor"];
ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
- const Color c = Color(arr[0], arr[1], arr[2]).to_srgb();
+ const Color c = Color(arr[0], arr[1], arr[2]).linear_to_srgb();
material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true);
material->set_emission(c);
@@ -3737,11 +3737,11 @@ void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Re
}
for (int32_t y = 0; y < r_spec_gloss->spec_gloss_img->get_height(); y++) {
for (int32_t x = 0; x < r_spec_gloss->spec_gloss_img->get_width(); x++) {
- const Color specular_pixel = r_spec_gloss->spec_gloss_img->get_pixel(x, y).to_linear();
+ const Color specular_pixel = r_spec_gloss->spec_gloss_img->get_pixel(x, y).srgb_to_linear();
Color specular = Color(specular_pixel.r, specular_pixel.g, specular_pixel.b);
specular *= r_spec_gloss->specular_factor;
Color diffuse = Color(1.0f, 1.0f, 1.0f);
- diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).to_linear();
+ diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).srgb_to_linear();
float metallic = 0.0f;
Color base_color;
spec_gloss_to_metal_base_color(specular, diffuse, base_color, metallic);
@@ -3758,7 +3758,7 @@ void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Re
mr.g = 1.0f - mr.g;
rm_img->set_pixel(x, y, mr);
if (r_spec_gloss->diffuse_img.is_valid()) {
- r_spec_gloss->diffuse_img->set_pixel(x, y, base_color.to_srgb());
+ r_spec_gloss->diffuse_img->set_pixel(x, y, base_color.linear_to_srgb());
}
}
}
@@ -4626,7 +4626,7 @@ Error GLTFDocument::_parse_lights(Ref<GLTFState> state) {
if (d.has("color")) {
const Array &arr = d["color"];
ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
- const Color c = Color(arr[0], arr[1], arr[2]).to_srgb();
+ const Color c = Color(arr[0], arr[1], arr[2]).linear_to_srgb();
light->color = c;
}
if (d.has("intensity")) {
diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp
index e09c76f052..b656788a10 100644
--- a/modules/gltf/register_types.cpp
+++ b/modules/gltf/register_types.cpp
@@ -60,7 +60,7 @@
static void _editor_init() {
Ref<EditorSceneFormatImporterGLTF> import_gltf;
import_gltf.instantiate();
- ResourceImporterScene::get_singleton()->add_importer(import_gltf);
+ ResourceImporterScene::add_importer(import_gltf);
// Blend to glTF importer.
@@ -72,7 +72,7 @@ static void _editor_init() {
if (blend_enabled) {
Ref<EditorSceneFormatImporterBlend> importer;
importer.instantiate();
- ResourceImporterScene::get_singleton()->add_importer(importer);
+ ResourceImporterScene::add_importer(importer);
Ref<EditorFileSystemImportFormatSupportQueryBlend> blend_import_query;
blend_import_query.instantiate();
@@ -95,7 +95,7 @@ static void _editor_init() {
} else {
Ref<EditorSceneFormatImporterFBX> importer;
importer.instantiate();
- ResourceImporterScene::get_singleton()->add_importer(importer);
+ ResourceImporterScene::add_importer(importer);
}
}
}
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index 4588caf0a5..eca689e87a 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -132,7 +132,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_f
ptr[2] * exp / 255.0);
if (p_force_linear) {
- c = c.to_linear();
+ c = c.srgb_to_linear();
}
*(uint32_t *)ptr = c.to_rgbe9995();
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 1ff2600839..864df765ee 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -230,7 +230,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool
}
if (p_force_linear) {
- color = color.to_linear();
+ color = color.srgb_to_linear();
}
*row_w++ = Math::make_half_float(color.r);
@@ -261,7 +261,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool
}
if (p_force_linear) {
- color = color.to_linear();
+ color = color.srgb_to_linear();
}
*row_w++ = color.r;
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index db2fe274d9..7da30ac363 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -3062,7 +3062,7 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) {
Callable::CallError ce;
{
- List<WindowID>::Element *E = popup_list.front();
+ List<WindowID>::Element *E = popup_list.back();
if (E && Object::cast_to<InputEventKey>(*p_event)) {
// Redirect keyboard input to active popup.
if (windows.has(E->get())) {
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index c7381f06e3..d209c90d87 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -326,7 +326,7 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
Callable::CallError ce;
{
- List<WindowID>::Element *E = popup_list.front();
+ List<WindowID>::Element *E = popup_list.back();
if (E && Object::cast_to<InputEventKey>(*p_event)) {
// Redirect keyboard input to active popup.
if (windows.has(E->get())) {
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 736dc7d383..31bad0f053 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -2003,7 +2003,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
Callable::CallError ce;
{
- List<WindowID>::Element *E = popup_list.front();
+ List<WindowID>::Element *E = popup_list.back();
if (E && Object::cast_to<InputEventKey>(*p_event)) {
// Redirect keyboard input to active popup.
if (windows.has(E->get())) {
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 4eace17cc0..1f0c9acef5 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -509,7 +509,7 @@ void Camera3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov", "get_fov");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater,exp"), "set_near", "get_near");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_RANGE, "0.01,4000,0.01,or_greater,exp"), "set_far", "get_far");
@@ -557,7 +557,7 @@ void Camera3D::set_fov(real_t p_fov) {
}
void Camera3D::set_size(real_t p_size) {
- ERR_FAIL_COND(p_size < 0.1 || p_size > 16384);
+ ERR_FAIL_COND(p_size < 0.001 || p_size > 16384);
size = p_size;
_update_camera_mode();
}
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 3461caf638..8b457b683d 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -884,7 +884,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
Light3D *light = lights_found[i].light;
Transform3D xf = lights_found[i].xform;
- Color linear_color = light->get_color().to_linear();
+ Color linear_color = light->get_color().srgb_to_linear();
if (Object::cast_to<DirectionalLight3D>(light)) {
DirectionalLight3D *l = Object::cast_to<DirectionalLight3D>(light);
lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_STATIC, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE));
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 62cc7c143b..bbc977647e 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -181,15 +181,6 @@ void Node3D::_notification(int p_what) {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
- if (!data.gizmos_disabled) {
- for (int i = 0; i < data.gizmos.size(); i++) {
- data.gizmos.write[i]->create();
- if (is_visible_in_tree()) {
- data.gizmos.write[i]->redraw();
- }
- data.gizmos.write[i]->transform();
- }
- }
}
#endif
} break;
@@ -427,6 +418,7 @@ void Node3D::update_gizmos() {
}
if (data.gizmos.is_empty()) {
+ get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
return;
}
if (data.gizmos_dirty) {
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index ea9fbe8381..60f2623267 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -540,6 +540,11 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
List<StringName> sname;
player->get_animation_list(&sname);
+ Ref<Animation> reset_anim;
+ bool has_reset_anim = player->has_animation("RESET");
+ if (has_reset_anim) {
+ reset_anim = player->get_animation("RESET");
+ }
for (const StringName &E : sname) {
Ref<Animation> anim = player->get_animation(E);
for (int i = 0; i < anim->get_track_count(); i++) {
@@ -593,6 +598,12 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track = track_value;
+ if (has_reset_anim) {
+ int rt = reset_anim->find_track(path, track_type);
+ if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
+ track_value->init_value = reset_anim->track_get_key_value(rt, 0);
+ }
+ }
} break;
case Animation::TYPE_POSITION_3D:
case Animation::TYPE_ROTATION_3D:
@@ -645,6 +656,25 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
}
}
+ if (has_reset_anim) {
+ int rt = reset_anim->find_track(path, track_type);
+ if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
+ switch (track_type) {
+ case Animation::TYPE_POSITION_3D: {
+ track_xform->init_loc = reset_anim->track_get_key_value(rt, 0);
+ } break;
+ case Animation::TYPE_ROTATION_3D: {
+ track_xform->ref_rot = reset_anim->track_get_key_value(rt, 0);
+ track_xform->init_rot = track_xform->ref_rot.log();
+ } break;
+ case Animation::TYPE_SCALE_3D: {
+ track_xform->init_scale = reset_anim->track_get_key_value(rt, 0);
+ } break;
+ default: {
+ }
+ }
+ }
+ }
#endif // _3D_DISABLED
} break;
case Animation::TYPE_BLEND_SHAPE: {
@@ -675,6 +705,13 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track_bshape->object = mesh_3d;
track_bshape->object_id = mesh_3d->get_instance_id();
track = track_bshape;
+
+ if (has_reset_anim) {
+ int rt = reset_anim->find_track(path, track_type);
+ if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
+ track_bshape->init_value = reset_anim->track_get_key_value(rt, 0);
+ }
+ }
#endif
} break;
case Animation::TYPE_METHOD: {
@@ -704,6 +741,13 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track_bezier->object_id = track_bezier->object->get_instance_id();
track = track_bezier;
+
+ if (has_reset_anim) {
+ int rt = reset_anim->find_track(path, track_type);
+ if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
+ track_bezier->init_value = reset_anim->track_get_key_value(rt, 0);
+ }
+ }
} break;
case Animation::TYPE_AUDIO: {
TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
@@ -1244,7 +1288,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (t->process_pass != process_pass) {
t->process_pass = process_pass;
- t->value = 0;
+ t->value = t->init_value;
}
float value;
@@ -1256,7 +1300,7 @@ void AnimationTree::_process_graph(double p_delta) {
continue;
}
- t->value += value * blend;
+ t->value += (value - t->init_value) * blend;
#endif // _3D_DISABLED
} break;
case Animation::TYPE_VALUE: {
@@ -1274,10 +1318,15 @@ void AnimationTree::_process_graph(double p_delta) {
if (t->process_pass != process_pass) {
t->process_pass = process_pass;
- t->value = value;
- t->value.zero();
+ if (!t->init_value) {
+ t->init_value = value;
+ t->init_value.zero();
+ } else {
+ t->value = t->init_value;
+ }
}
+ Variant::sub(value, t->init_value, value);
Variant::blend(t->value, value, blend, t->value);
} else {
if (blend < CMP_EPSILON) {
@@ -1321,10 +1370,10 @@ void AnimationTree::_process_graph(double p_delta) {
if (t->process_pass != process_pass) {
t->process_pass = process_pass;
- t->value = 0;
+ t->value = t->init_value;
}
- t->value += bezier * blend;
+ t->value += (bezier - t->init_value) * blend;
} break;
case Animation::TYPE_AUDIO: {
if (blend < CMP_EPSILON) {
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 3ccb6be073..524f735894 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -212,12 +212,14 @@ private:
struct TrackCacheBlendShape : public TrackCache {
MeshInstance3D *mesh_3d = nullptr;
+ float init_value = 0;
float value = 0;
int shape_index = -1;
TrackCacheBlendShape() { type = Animation::TYPE_BLEND_SHAPE; }
};
struct TrackCacheValue : public TrackCache {
+ Variant init_value;
Variant value;
Vector<StringName> subpath;
TrackCacheValue() { type = Animation::TYPE_VALUE; }
@@ -228,6 +230,7 @@ private:
};
struct TrackCacheBezier : public TrackCache {
+ real_t init_value = 0.0;
real_t value = 0.0;
Vector<StringName> subpath;
TrackCacheBezier() {
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 9fc1fb072c..b01f45e9ab 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -169,7 +169,7 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
return -1;
}
-void PopupMenu::_activate_submenu(int p_over) {
+void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) {
Node *n = get_node(items[p_over].submenu);
ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[p_over].submenu + ".");
Popup *submenu_popup = Object::cast_to<Popup>(n);
@@ -213,8 +213,10 @@ void PopupMenu::_activate_submenu(int p_over) {
return;
}
+ submenu_pum->activated_by_keyboard = p_by_keyboard;
+
// If not triggered by the mouse, start the popup with its first item selected.
- if (submenu_pum->get_item_count() > 0 && Input::get_singleton()->is_action_just_pressed("ui_accept")) {
+ if (submenu_pum->get_item_count() > 0 && p_by_keyboard) {
submenu_pum->set_current_index(0);
}
@@ -323,14 +325,14 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
set_input_as_handled();
}
} else if (p_event->is_action("ui_right") && p_event->is_pressed()) {
- if (mouse_over >= 0 && mouse_over < items.size() && !!items[mouse_over].separator && items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) {
- _activate_submenu(mouse_over);
+ if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && !items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) {
+ _activate_submenu(mouse_over, true);
set_input_as_handled();
}
} else if (p_event->is_action("ui_accept") && p_event->is_pressed()) {
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) {
- _activate_submenu(mouse_over);
+ _activate_submenu(mouse_over, true);
} else {
activate_item(mouse_over);
}
@@ -396,6 +398,11 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
+ if (m->get_velocity().is_equal_approx(Vector2())) {
+ return;
+ }
+ activated_by_keyboard = false;
+
for (const Rect2 &E : autohide_areas) {
if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E.has_point(m->get_position())) {
_close_pressed();
@@ -687,7 +694,7 @@ void PopupMenu::_draw_background() {
void PopupMenu::_minimum_lifetime_timeout() {
close_allowed = true;
// If the mouse still isn't in this popup after timer expires, close.
- if (!get_visible_rect().has_point(get_mouse_position())) {
+ if (!activated_by_keyboard && !get_visible_rect().has_point(get_mouse_position())) {
_close_pressed();
}
}
@@ -772,7 +779,7 @@ void PopupMenu::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
// Only used when using operating system windows.
- if (!is_embedded() && autohide_areas.size()) {
+ if (!activated_by_keyboard && !is_embedded() && autohide_areas.size()) {
Point2 mouse_pos = DisplayServer::get_singleton()->mouse_get_position();
mouse_pos -= get_position();
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 518ba14dae..98d76875cb 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -87,6 +87,7 @@ class PopupMenu : public Popup {
};
bool close_allowed = false;
+ bool activated_by_keyboard = false;
Timer *minimum_lifetime_timer = nullptr;
Timer *submenu_timer = nullptr;
@@ -107,7 +108,7 @@ class PopupMenu : public Popup {
void _shape_item(int p_item);
virtual void gui_input(const Ref<InputEvent> &p_event);
- void _activate_submenu(int p_over);
+ void _activate_submenu(int p_over, bool p_by_keyboard = false);
void _submenu_timeout();
uint64_t popup_time_msec = 0;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index c00298ff2f..ec13399f82 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -4257,7 +4257,7 @@ void RichTextLabel::select_all() {
while (it) {
if (it->type != ITEM_FRAME) {
- if (from_item == nullptr) {
+ if (!from_item) {
from_item = it;
} else {
to_item = it;
@@ -4265,13 +4265,22 @@ void RichTextLabel::select_all() {
}
it = _get_next_item(it, true);
}
+ if (!from_item || !to_item) {
+ return;
+ }
ItemFrame *from_frame = nullptr;
int from_line = 0;
_find_frame(from_item, &from_frame, &from_line);
+ if (!from_frame) {
+ return;
+ }
ItemFrame *to_frame = nullptr;
int to_line = 0;
_find_frame(to_item, &to_frame, &to_line);
+ if (!to_frame) {
+ return;
+ }
selection.from_line = from_line;
selection.from_frame = from_frame;
selection.from_char = 0;
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 0ddf164c79..e045a379d2 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -3828,7 +3828,7 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("compress", "page_size", "fps", "split_tolerance"), &Animation::compress, DEFVAL(8192), DEFVAL(120), DEFVAL(4.0));
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode"), "set_loop_mode", "get_loop_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Ping-Pong"), "set_loop_mode", "get_loop_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step");
ADD_SIGNAL(MethodInfo("tracks_changed"));
diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp
index f7b8c6a648..229d9ab218 100644
--- a/scene/resources/animation_library.cpp
+++ b/scene/resources/animation_library.cpp
@@ -55,7 +55,7 @@ void AnimationLibrary::remove_animation(const StringName &p_name) {
void AnimationLibrary::rename_animation(const StringName &p_name, const StringName &p_new_name) {
ERR_FAIL_COND(!animations.has(p_name));
- ERR_FAIL_COND_MSG(String(p_name).contains("/") || String(p_name).contains(":") || String(p_name).contains(",") || String(p_name).contains("["), "Invalid animation name: " + String(p_name) + ".");
+ ERR_FAIL_COND_MSG(String(p_new_name).contains("/") || String(p_new_name).contains(":") || String(p_new_name).contains(",") || String(p_new_name).contains("["), "Invalid animation name: " + String(p_new_name) + ".");
ERR_FAIL_COND(animations.has(p_new_name));
animations.insert(p_new_name, animations[p_name]);
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 365bef896f..b541e6ca88 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -783,7 +783,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
//ambient
if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);
- color = color.to_linear();
+ color = color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy;
@@ -793,7 +793,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
} else {
float energy = environment_get_ambient_light_energy(p_render_data->environment);
Color color = environment_get_ambient_light_color(p_render_data->environment);
- color = color.to_linear();
+ color = color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
@@ -829,7 +829,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
- Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear();
+ Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear();
float fog_energy = environment_get_fog_light_energy(p_render_data->environment);
scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
@@ -844,7 +844,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
} else {
scene_state.ubo.use_ambient_light = true;
Color clear_color = p_default_bg_color;
- clear_color = clear_color.to_linear();
+ clear_color = clear_color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = clear_color.r;
scene_state.ubo.ambient_light_color_energy[1] = clear_color.g;
scene_state.ubo.ambient_light_color_energy[2] = clear_color.b;
@@ -1391,7 +1391,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.b *= bg_energy;
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
- RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
+ RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
} break;
case RS::ENV_BG_COLOR: {
@@ -1401,7 +1401,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.b *= bg_energy;
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
- RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
+ RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
} break;
case RS::ENV_BG_SKY: {
@@ -1520,7 +1520,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
Vector<Color> c;
{
- Color cc = clear_color.to_linear();
+ Color cc = clear_color.srgb_to_linear();
if (using_separate_specular) {
cc.a = 0; //subsurf scatter must be 0
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 99a7fe6280..6b0d245e44 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -293,16 +293,16 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
raster_state.cull_mode = cull_mode_rd;
raster_state.wireframe = wireframe;
- RD::PipelineColorBlendState blend_state;
- RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
- RD::PipelineMultisampleState multisample_state;
-
if (k == PIPELINE_VERSION_COLOR_PASS) {
for (int l = 0; l < PIPELINE_COLOR_PASS_FLAG_COUNT; l++) {
if (!shader_singleton->valid_color_pass_pipelines.has(l)) {
continue;
}
+ RD::PipelineColorBlendState blend_state;
+ RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
+ RD::PipelineMultisampleState multisample_state;
+
int shader_flags = 0;
if (l & PIPELINE_COLOR_PASS_FLAG_TRANSPARENT) {
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
@@ -338,6 +338,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
color_pipelines[i][j][l].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
}
} else {
+ RD::PipelineColorBlendState blend_state;
+ RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
+ RD::PipelineMultisampleState multisample_state;
+
if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW) {
//none, leave empty
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 7272b2f8d0..6988e3c1dd 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -596,7 +596,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
/*
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
- RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
+ RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
*/
} break;
@@ -608,7 +608,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
/*
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
- RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
+ RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
*/
} break;
@@ -723,10 +723,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
{
// regular forward for now
Vector<Color> c;
- c.push_back(clear_color.to_linear()); // our render buffer
+ c.push_back(clear_color.srgb_to_linear()); // our render buffer
if (render_buffer) {
if (render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- c.push_back(clear_color.to_linear()); // our resolve buffer
+ c.push_back(clear_color.srgb_to_linear()); // our resolve buffer
}
if (using_subpass_post_process) {
c.push_back(Color()); // our 2D buffer we're copying into
@@ -1616,7 +1616,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
//ambient
if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);
- color = color.to_linear();
+ color = color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy;
@@ -1626,7 +1626,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
} else {
float energy = environment_get_ambient_light_energy(p_render_data->environment);
Color color = environment_get_ambient_light_color(p_render_data->environment);
- color = color.to_linear();
+ color = color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
@@ -1657,7 +1657,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
- Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear();
+ Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear();
float fog_energy = environment_get_fog_light_energy(p_render_data->environment);
scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
@@ -1672,7 +1672,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
} else {
scene_state.ubo.use_ambient_light = true;
Color clear_color = p_default_bg_color;
- clear_color = clear_color.to_linear();
+ clear_color = clear_color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = clear_color.r;
scene_state.ubo.ambient_light_color_energy[1] = clear_color.g;
scene_state.ubo.ambient_light_color_energy[2] = clear_color.b;
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
index 75202d5abb..c735fda5f8 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -921,7 +921,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env,
if (p_env->background == RS::ENV_BG_CLEAR_COLOR) {
push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR;
- Color c = storage->get_default_clear_color().to_linear();
+ Color c = storage->get_default_clear_color().srgb_to_linear();
push_constant.sky_color[0] = c.r;
push_constant.sky_color[1] = c.g;
push_constant.sky_color[2] = c.b;
@@ -1469,7 +1469,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re
lights[idx].direction[1] = dir.y;
lights[idx].direction[2] = dir.z;
Color color = storage->light_get_color(li->light);
- color = color.to_linear();
+ color = color.srgb_to_linear();
lights[idx].color[0] = color.r;
lights[idx].color[1] = color.g;
lights[idx].color[2] = color.b;
@@ -1514,7 +1514,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re
lights[idx].position[1] = pos.y;
lights[idx].position[2] = pos.z;
Color color = storage->light_get_color(li->light);
- color = color.to_linear();
+ color = color.srgb_to_linear();
lights[idx].color[0] = color.r;
lights[idx].color[1] = color.g;
lights[idx].color[2] = color.b;
@@ -1953,7 +1953,7 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32
lights[idx].position[1] = pos.y;
lights[idx].position[2] = pos.z;
Color color = storage->light_get_color(li->light);
- color = color.to_linear();
+ color = color.srgb_to_linear();
lights[idx].color[0] = color.r;
lights[idx].color[1] = color.g;
lights[idx].color[2] = color.b;
@@ -2396,7 +2396,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
l.attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
l.energy = storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
l.radius = to_cell.basis.xform(Vector3(storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();
- Color color = storage->light_get_color(light).to_linear();
+ Color color = storage->light_get_color(light).srgb_to_linear();
l.color[0] = color.r;
l.color[1] = color.g;
l.color[2] = color.b;
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index ac7ac692ce..b342e8f043 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -517,7 +517,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba
ambient_color_sky_mix = env->ambient_sky_contribution;
const float ambient_energy = env->ambient_light_energy;
ambient_color = env->ambient_light;
- ambient_color = ambient_color.to_linear();
+ ambient_color = ambient_color.srgb_to_linear();
ambient_color.r *= ambient_energy;
ambient_color.g *= ambient_energy;
ambient_color.b *= ambient_energy;
@@ -536,7 +536,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba
} else {
const float bg_energy = env->bg_energy;
Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? storage->get_default_clear_color() : env->bg_color);
- panorama_color = panorama_color.to_linear();
+ panorama_color = panorama_color.srgb_to_linear();
panorama_color.r *= bg_energy;
panorama_color.g *= bg_energy;
panorama_color.b *= bg_energy;
@@ -3245,7 +3245,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
reflection_ubo.exterior = !storage->reflection_probe_is_interior(base_probe);
reflection_ubo.box_project = storage->reflection_probe_is_box_projection(base_probe);
- Color ambient_linear = storage->reflection_probe_get_ambient_color(base_probe).to_linear();
+ Color ambient_linear = storage->reflection_probe_get_ambient_color(base_probe).srgb_to_linear();
float interior_ambient_energy = storage->reflection_probe_get_ambient_color_energy(base_probe);
reflection_ubo.ambient[0] = ambient_linear.r * interior_ambient_energy;
reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy;
@@ -3312,7 +3312,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI;
- Color linear_col = storage->light_get_color(base).to_linear();
+ Color linear_col = storage->light_get_color(base).srgb_to_linear();
light_data.color[0] = linear_col.r;
light_data.color[1] = linear_col.g;
light_data.color[2] = linear_col.b;
@@ -3491,7 +3491,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
Transform3D light_transform = li->transform;
float sign = storage->light_is_negative(base) ? -1 : 1;
- Color linear_col = storage->light_get_color(base).to_linear();
+ Color linear_col = storage->light_get_color(base).srgb_to_linear();
light_data.attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION);
@@ -4641,7 +4641,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.fog_frustum_end = fog_end;
- Color ambient_color = env->ambient_light.to_linear();
+ Color ambient_color = env->ambient_light.srgb_to_linear();
params.ambient_color[0] = ambient_color.r;
params.ambient_color[1] = ambient_color.g;
params.ambient_color[2] = ambient_color.b;
@@ -4653,13 +4653,13 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.directional_light_count = p_directional_light_count;
- Color emission = env->volumetric_fog_emission.to_linear();
+ Color emission = env->volumetric_fog_emission.srgb_to_linear();
params.base_emission[0] = emission.r * env->volumetric_fog_emission_energy;
params.base_emission[1] = emission.g * env->volumetric_fog_emission_energy;
params.base_emission[2] = emission.b * env->volumetric_fog_emission_energy;
params.base_density = env->volumetric_fog_density;
- Color base_scattering = env->volumetric_fog_scattering.to_linear();
+ Color base_scattering = env->volumetric_fog_scattering.srgb_to_linear();
params.base_scattering[0] = base_scattering.r;
params.base_scattering[1] = base_scattering.g;
params.base_scattering[2] = base_scattering.b;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 061aa8b4aa..44298711cd 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -1194,7 +1194,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
float sign = storage->light_is_negative(base) ? -1 : 1;
sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
- Color linear_col = storage->light_get_color(base).to_linear();
+ Color linear_col = storage->light_get_color(base).srgb_to_linear();
sky_light_data.color[0] = linear_col.r;
sky_light_data.color[1] = linear_col.g;
sky_light_data.color[2] = linear_col.b;
@@ -1286,7 +1286,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
sky_scene_state.ubo.fog_enabled = p_env->fog_enabled;
sky_scene_state.ubo.fog_density = p_env->fog_density;
sky_scene_state.ubo.fog_aerial_perspective = p_env->fog_aerial_perspective;
- Color fog_color = p_env->fog_light_color.to_linear();
+ Color fog_color = p_env->fog_light_color.srgb_to_linear();
float fog_energy = p_env->fog_light_energy;
sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index 9e3d124bbb..2a2c5f350a 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -422,7 +422,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
if (i < s) {
Color color = a[i];
if (p_linear_color) {
- color = color.to_linear();
+ color = color.srgb_to_linear();
}
gui[j] = color.r;
gui[j + 1] = color.g;
@@ -459,7 +459,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
Color v = value;
if (p_linear_color) {
- v = v.to_linear();
+ v = v.srgb_to_linear();
}
gui[0] = v.r;
@@ -1498,7 +1498,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = v.a;
GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1];
- v = v.to_linear();
+ v = v.srgb_to_linear();
bv_linear.x = v.r;
bv_linear.y = v.g;
bv_linear.z = v.b;
diff --git a/tests/core/math/test_color.h b/tests/core/math/test_color.h
index 6f40f8ecc0..51c3bc8bdc 100644
--- a/tests/core/math/test_color.h
+++ b/tests/core/math/test_color.h
@@ -146,8 +146,8 @@ TEST_CASE("[Color] Conversion methods") {
TEST_CASE("[Color] Linear <-> sRGB conversion") {
const Color color = Color(0.35, 0.5, 0.6, 0.7);
- const Color color_linear = color.to_linear();
- const Color color_srgb = color.to_srgb();
+ const Color color_linear = color.srgb_to_linear();
+ const Color color_srgb = color.linear_to_srgb();
CHECK_MESSAGE(
color_linear.is_equal_approx(Color(0.100481, 0.214041, 0.318547, 0.7)),
"The color converted to linear color space should match the expected value.");
@@ -155,10 +155,10 @@ TEST_CASE("[Color] Linear <-> sRGB conversion") {
color_srgb.is_equal_approx(Color(0.62621, 0.735357, 0.797738, 0.7)),
"The color converted to sRGB color space should match the expected value.");
CHECK_MESSAGE(
- color_linear.to_srgb().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)),
+ color_linear.linear_to_srgb().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)),
"The linear color converted back to sRGB color space should match the expected value.");
CHECK_MESSAGE(
- color_srgb.to_linear().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)),
+ color_srgb.srgb_to_linear().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)),
"The sRGB color converted back to linear color space should match the expected value.");
}