Merge pull request #85784 from YuriSizov/4.2-cherrypicks

Cherry-picks for the 4.2 branch (future 4.2.1) - 1st batch
This commit is contained in:
Rémi Verschelde 2023-12-07 11:12:40 +01:00 committed by GitHub
commit 9d22668b9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
104 changed files with 709 additions and 332 deletions

3
.github/CODEOWNERS vendored
View file

@ -140,10 +140,9 @@ doc_classes/* @godotengine/documentation
/platform/android/ @godotengine/android
/platform/ios/ @godotengine/ios
/platform/javascript/ @godotengine/html5
/platform/linuxbsd/ @godotengine/linux-bsd
/platform/macos/ @godotengine/macos
/platform/uwp/ @godotengine/uwp
/platform/web/ @godotengine/web
/platform/windows/ @godotengine/windows
# Scene

View file

@ -1113,11 +1113,10 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
Ref<Script> s = res;
StringName ibt = s->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "ResourceFormatLoader");
ERR_FAIL_COND_V_MSG(!valid_type, false, "Script does not inherit a CustomResourceLoader: " + script_path + ".");
ERR_FAIL_COND_V_MSG(!valid_type, false, vformat("Failed to add a custom resource loader, script '%s' does not inherit 'ResourceFormatLoader'.", script_path));
Object *obj = ClassDB::instantiate(ibt);
ERR_FAIL_NULL_V_MSG(obj, false, "Cannot instance script as custom resource loader, expected 'ResourceFormatLoader' inheritance, got: " + String(ibt) + ".");
ERR_FAIL_NULL_V_MSG(obj, false, vformat("Failed to add a custom resource loader, cannot instantiate '%s'.", ibt));
Ref<ResourceFormatLoader> crl = Object::cast_to<ResourceFormatLoader>(obj);
crl->set_script(s);

View file

@ -237,11 +237,10 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
Ref<Script> s = res;
StringName ibt = s->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "ResourceFormatSaver");
ERR_FAIL_COND_V_MSG(!valid_type, false, "Script does not inherit a CustomResourceSaver: " + script_path + ".");
ERR_FAIL_COND_V_MSG(!valid_type, false, vformat("Failed to add a custom resource saver, script '%s' does not inherit 'ResourceFormatSaver'.", script_path));
Object *obj = ClassDB::instantiate(ibt);
ERR_FAIL_NULL_V_MSG(obj, false, "Cannot instance script as custom resource saver, expected 'ResourceFormatSaver' inheritance, got: " + String(ibt) + ".");
ERR_FAIL_NULL_V_MSG(obj, false, vformat("Failed to add a custom resource saver, cannot instantiate '%s'.", ibt));
Ref<ResourceFormatSaver> crl = Object::cast_to<ResourceFormatSaver>(obj);
crl->set_script(s);

View file

@ -35,6 +35,8 @@
#include "core/object/class_db.h"
#include "core/object/script_language.h"
#include <stdio.h>
#ifdef DEV_ENABLED
// Includes safety checks to ensure that a queue set as a thread singleton override
// is only ever called from the thread it was set for.
@ -93,7 +95,7 @@ Error CallQueue::push_callablep(const Callable &p_callable, const Variant **p_ar
if ((page_bytes[pages_used - 1] + room_needed) > uint32_t(PAGE_SIZE_BYTES)) {
if (pages_used == max_pages) {
ERR_PRINT("Failed method: " + p_callable + ". Message queue out of memory. " + error_text);
fprintf(stderr, "Failed method: %s. Message queue out of memory. %s\n", String(p_callable).utf8().get_data(), error_text.utf8().get_data());
statistics();
UNLOCK_MUTEX;
return ERR_OUT_OF_MEMORY;
@ -144,7 +146,7 @@ Error CallQueue::push_set(ObjectID p_id, const StringName &p_prop, const Variant
if (ObjectDB::get_instance(p_id)) {
type = ObjectDB::get_instance(p_id)->get_class();
}
ERR_PRINT("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id) + ". Message queue out of memory. " + error_text);
fprintf(stderr, "Failed set: %s: %s target ID: %s. Message queue out of memory. %s\n", type.utf8().get_data(), String(p_prop).utf8().get_data(), itos(p_id).utf8().get_data(), error_text.utf8().get_data());
statistics();
UNLOCK_MUTEX;
@ -181,7 +183,7 @@ Error CallQueue::push_notification(ObjectID p_id, int p_notification) {
if ((page_bytes[pages_used - 1] + room_needed) > uint32_t(PAGE_SIZE_BYTES)) {
if (pages_used == max_pages) {
ERR_PRINT("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id) + ". Message queue out of memory. " + error_text);
fprintf(stderr, "Failed notification: %s target ID: %s. Message queue out of memory. %s\n", itos(p_notification).utf8().get_data(), itos(p_id).utf8().get_data(), error_text.utf8().get_data());
statistics();
UNLOCK_MUTEX;
return ERR_OUT_OF_MEMORY;

View file

@ -631,6 +631,10 @@ bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const {
void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, const HashMap<StringName, Variant> &p_values) {
HashSet<StringName> new_values;
for (const PropertyInfo &E : p_properties) {
if (E.usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)) {
continue;
}
StringName n = E.name;
new_values.insert(n);

View file

@ -518,8 +518,12 @@ String TranslationServer::get_country_name(const String &p_country) const {
}
void TranslationServer::set_locale(const String &p_locale) {
locale = standardize_locale(p_locale);
String new_locale = standardize_locale(p_locale);
if (locale == new_locale) {
return;
}
locale = new_locale;
ResourceLoader::reload_translation_remaps();
if (OS::get_singleton()->get_main_loop()) {

View file

@ -310,7 +310,7 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return hash_fmix32(p_uchar); }
static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); }
static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
static _FORCE_INLINE_ uint32_t hash(const CharString &p_char_string) { return hash_djb2(p_char_string.ptr()); }
static _FORCE_INLINE_ uint32_t hash(const CharString &p_char_string) { return hash_djb2(p_char_string.get_data()); }
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); }

View file

@ -501,22 +501,22 @@
Represents the size of the [enum TextureParam] enum.
</constant>
<constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
The texture filter reads from the nearest pixel only. This makes the texture look pixelated from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter">
The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
The texture filter blends between the nearest 4 pixels. This makes the texture look smooth from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter">
The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
The texture filter reads from the nearest pixel and blends between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look pixelated from up close, and smooth from a distance.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="3" enum="TextureFilter">
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for most cases as mipmaps are important to smooth out pixels that are far from the camera.
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look smooth from up close, and smooth from a distance.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="4" enum="TextureFilter">
The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
The texture filter reads from the nearest pixel and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look pixelated from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
The texture filter blends between the nearest 4 pixels and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look smooth from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
</constant>
<constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter">
Represents the size of the [enum TextureFilter] enum.

View file

@ -32,7 +32,7 @@
Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled.
</member>
<member name="exposure_shutter_speed" type="float" setter="set_shutter_speed" getter="get_shutter_speed" default="100.0">
Time for shutter to open and close, measured in seconds. A higher value will let in more light leading to a brighter image, while a lower amount will let in less light leading to a darker image.
Time for shutter to open and close, evaluated as [code]1 / shutter_speed[/code] seconds. A higher value will allow less light (leading to a darker image), while a lower value will allow more light (leading to a brighter image).
Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled.
</member>
<member name="frustum_far" type="float" setter="set_far" getter="get_far" default="4000.0">

View file

@ -660,24 +660,26 @@
The [CanvasItem] will inherit the filter from its parent.
</constant>
<constant name="TEXTURE_FILTER_NEAREST" value="1" enum="TextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering. Useful for pixel art.
The texture filter reads from the nearest pixel only. This makes the texture look pixelated from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="TEXTURE_FILTER_LINEAR" value="2" enum="TextureFilter">
The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style.
The texture filter blends between the nearest 4 pixels. This makes the texture look smooth from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="TextureFilter">
The texture filter reads from the nearest pixel in the nearest mipmap. This is the fastest way to read from textures with mipmaps.
The texture filter reads from the nearest pixel and blends between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look pixelated from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="TextureFilter">
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look smooth from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_NEAREST_WITH_MIPMAPS] is usually more appropriate.
The texture filter reads from the nearest pixel and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look pixelated from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_NEAREST_WITH_MIPMAPS] is usually more appropriate in this case.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="TextureFilter">
The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_LINEAR_WITH_MIPMAPS] is usually more appropriate.
The texture filter blends between the nearest 4 pixels and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look smooth from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_LINEAR_WITH_MIPMAPS] is usually more appropriate in this case.
</constant>
<constant name="TEXTURE_FILTER_MAX" value="7" enum="TextureFilter">
Represents the size of the [enum TextureFilter] enum.

View file

@ -665,8 +665,8 @@
<member name="interface/theme/icon_and_font_color" type="int" setter="" getter="">
The icon and font color scheme to use in the editor.
- [b]Auto[/b] determines the color scheme to use automatically based on [member interface/theme/base_color].
- [b]Dark[/b] makes fonts and icons light (suitable for dark themes).
- [b]Light[/b] makes fonts and icons dark (suitable for light themes). Icon colors are automatically converted by the editor following [url=https://github.com/godotengine/godot/blob/master/editor/editor_themes.cpp#L135]this set of rules[/url].
- [b]Dark[/b] makes fonts and icons dark (suitable for light themes). Icon colors are automatically converted by the editor following the set of rules defined in [url=https://github.com/godotengine/godot/blob/master/editor/editor_themes.cpp]this file[/url].
- [b]Light[/b] makes fonts and icons light (suitable for dark themes).
</member>
<member name="interface/theme/icon_saturation" type="float" setter="" getter="">
The saturation to use for editor icons. Higher values result in more vibrant colors.

View file

@ -29,6 +29,12 @@
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="get_rid" qualifiers="const">
<return type="RID" />
<description>
Returns the [RID] of this link on the [NavigationServer2D].
</description>
</method>
<method name="set_global_end_position">
<return type="void" />
<param index="0" name="position" type="Vector2" />

View file

@ -29,6 +29,12 @@
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="get_rid" qualifiers="const">
<return type="RID" />
<description>
Returns the [RID] of this link on the [NavigationServer3D].
</description>
</method>
<method name="set_global_end_position">
<return type="void" />
<param index="0" name="position" type="Vector3" />

View file

@ -43,7 +43,14 @@
Returns the current navigation map [RID] used by this region.
</description>
</method>
<method name="get_region_rid" qualifiers="const">
<method name="get_region_rid" qualifiers="const" is_deprecated="true">
<return type="RID" />
<description>
Returns the [RID] of this region on the [NavigationServer2D].
[i]Deprecated.[/i] Use [method get_rid] instead.
</description>
</method>
<method name="get_rid" qualifiers="const">
<return type="RID" />
<description>
Returns the [RID] of this region on the [NavigationServer2D]. Combined with [method NavigationServer2D.map_get_closest_point_owner] can be used to identify the [NavigationRegion2D] closest to a point on the merged navigation map.

View file

@ -36,7 +36,14 @@
Returns the current navigation map [RID] used by this region.
</description>
</method>
<method name="get_region_rid" qualifiers="const">
<method name="get_region_rid" qualifiers="const" is_deprecated="true">
<return type="RID" />
<description>
Returns the [RID] of this region on the [NavigationServer3D].
[i]Deprecated.[/i] Use [method get_rid] instead.
</description>
</method>
<method name="get_rid" qualifiers="const">
<return type="RID" />
<description>
Returns the [RID] of this region on the [NavigationServer3D]. Combined with [method NavigationServer3D.map_get_closest_point_owner] can be used to identify the [NavigationRegion3D] closest to a point on the merged navigation map.

View file

@ -5130,22 +5130,26 @@
Uses the default filter mode for this [Viewport].
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="1" enum="CanvasItemTextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
The texture filter reads from the nearest pixel only. This makes the texture look pixelated from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="2" enum="CanvasItemTextureFilter">
The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
The texture filter blends between the nearest 4 pixels. This makes the texture look smooth from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="CanvasItemTextureFilter">
The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
The texture filter reads from the nearest pixel and blends between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look pixelated from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="CanvasItemTextureFilter">
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps.
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look smooth from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="CanvasItemTextureFilter">
The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera.
The texture filter reads from the nearest pixel and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look pixelated from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS] is usually more appropriate in this case.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="CanvasItemTextureFilter">
The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing.
The texture filter blends between the nearest 4 pixels and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look smooth from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS] is usually more appropriate in this case.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_MAX" value="7" enum="CanvasItemTextureFilter">
Max value for [enum CanvasItemTextureFilter] enum.

View file

@ -6,7 +6,6 @@
<description>
A control used for playback of [VideoStream] resources.
Supported video formats are [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]) and any format exposed via a GDExtension plugin.
[b]Note:[/b] Due to a bug, VideoStreamPlayer does not support localization remapping yet.
[b]Warning:[/b] On Web, video playback [i]will[/i] perform poorly due to missing architecture-specific assembly optimizations.
</description>
<tutorials>

View file

@ -560,16 +560,18 @@
Draws the internal resolution buffer of the scene before post-processing is applied.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
The texture filter reads from the nearest pixel only. This makes the texture look pixelated from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="1" enum="DefaultCanvasItemTextureFilter">
The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
The texture filter blends between the nearest 4 pixels. This makes the texture look smooth from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="2" enum="DefaultCanvasItemTextureFilter">
The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look smooth from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="DefaultCanvasItemTextureFilter">
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps.
The texture filter reads from the nearest pixel and blends between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look pixelated from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX" value="4" enum="DefaultCanvasItemTextureFilter">
Max value for [enum DefaultCanvasItemTextureFilter] enum.

View file

@ -57,24 +57,26 @@
Sample the texture using the filter determined by the node this shader is attached to.
</constant>
<constant name="FILTER_NEAREST" value="1" enum="TextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
The texture filter reads from the nearest pixel only. This makes the texture look pixelated from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="FILTER_LINEAR" value="2" enum="TextureFilter">
The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style.
The texture filter blends between the nearest 4 pixels. This makes the texture look smooth from up close, and grainy from a distance (due to mipmaps not being sampled).
</constant>
<constant name="FILTER_NEAREST_MIPMAP" value="3" enum="TextureFilter">
The texture filter reads from the nearest pixel in the nearest mipmap. This is the fastest way to read from textures with mipmaps.
The texture filter reads from the nearest pixel and blends between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look pixelated from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="FILTER_LINEAR_MIPMAP" value="4" enum="TextureFilter">
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look smooth from up close, and smooth from a distance.
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="FILTER_NEAREST_MIPMAP_ANISOTROPIC" value="5" enum="TextureFilter">
The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant FILTER_LINEAR_MIPMAP] is usually more appropriate.
The texture filter reads from the nearest pixel and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look pixelated from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant FILTER_NEAREST_MIPMAP] is usually more appropriate in this case.
</constant>
<constant name="FILTER_LINEAR_MIPMAP_ANISOTROPIC" value="6" enum="TextureFilter">
The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant FILTER_LINEAR_MIPMAP] is usually more appropriate.
The texture filter blends between the nearest 4 pixels and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look smooth from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant FILTER_LINEAR_MIPMAP] is usually more appropriate in this case.
</constant>
<constant name="FILTER_MAX" value="7" enum="TextureFilter">
Represents the size of the [enum TextureFilter] enum.

View file

@ -1361,7 +1361,7 @@ def make_enum(t: str, is_bitfield: bool, state: State) -> str:
if is_bitfield:
if not state.classes[c].enums[e].is_bitfield:
print_error(f'{state.current_class}.xml: Enum "{t}" is not bitfield.', state)
return f"|bitfield|\<:ref:`{e}<enum_{c}_{e}>`\>"
return f"|bitfield|\\<:ref:`{e}<enum_{c}_{e}>`\\>"
else:
return f":ref:`{e}<enum_{c}_{e}>`"
@ -1552,16 +1552,11 @@ def make_rst_index(grouped_classes: Dict[str, List[str]], dry_run: bool, output_
f.write(".. _doc_class_reference:\n\n")
main_title = translate("All classes")
f.write(f"{main_title}\n")
f.write(f"{'=' * len(main_title)}\n\n")
f.write(make_heading("All classes", "="))
for group_name in CLASS_GROUPS:
if group_name in grouped_classes:
group_title = translate(CLASS_GROUPS[group_name])
f.write(f"{group_title}\n")
f.write(f"{'=' * len(group_title)}\n\n")
f.write(make_heading(CLASS_GROUPS[group_name], "="))
f.write(".. toctree::\n")
f.write(" :maxdepth: 1\n")
@ -2082,9 +2077,9 @@ def format_text_block(
post_text = text[endurl_pos + 6 :]
if pre_text and pre_text[-1] not in MARKUP_ALLOWED_PRECEDENT:
pre_text += "\ "
pre_text += "\\ "
if post_text and post_text[0] not in MARKUP_ALLOWED_SUBSEQUENT:
post_text = "\ " + post_text
post_text = "\\ " + post_text
text = pre_text + tag_text + post_text
pos = len(pre_text) + len(tag_text)
@ -2162,9 +2157,9 @@ def format_text_block(
# Properly escape things like `[Node]s`
if escape_pre and pre_text and pre_text[-1] not in MARKUP_ALLOWED_PRECEDENT:
pre_text += "\ "
pre_text += "\\ "
if escape_post and post_text and post_text[0] not in MARKUP_ALLOWED_SUBSEQUENT:
post_text = "\ " + post_text
post_text = "\\ " + post_text
next_brac_pos = post_text.find("[", 0)
iter_pos = 0
@ -2172,7 +2167,7 @@ def format_text_block(
iter_pos = post_text.find("*", iter_pos, next_brac_pos)
if iter_pos == -1:
break
post_text = f"{post_text[:iter_pos]}\*{post_text[iter_pos + 1 :]}"
post_text = f"{post_text[:iter_pos]}\\*{post_text[iter_pos + 1 :]}"
iter_pos += 2
iter_pos = 0
@ -2181,7 +2176,7 @@ def format_text_block(
if iter_pos == -1:
break
if not post_text[iter_pos + 1].isalnum(): # don't escape within a snake_case word
post_text = f"{post_text[:iter_pos]}\_{post_text[iter_pos + 1 :]}"
post_text = f"{post_text[:iter_pos]}\\_{post_text[iter_pos + 1 :]}"
iter_pos += 2
else:
iter_pos += 1
@ -2222,7 +2217,7 @@ def escape_rst(text: str, until_pos: int = -1) -> str:
pos = text.find("*", pos, until_pos)
if pos == -1:
break
text = f"{text[:pos]}\*{text[pos + 1 :]}"
text = f"{text[:pos]}\\*{text[pos + 1 :]}"
pos += 2
# Escape _ character at the end of a word to avoid interpreting it as an inline hyperlink
@ -2232,7 +2227,7 @@ def escape_rst(text: str, until_pos: int = -1) -> str:
if pos == -1:
break
if not text[pos + 1].isalnum(): # don't escape within a snake_case word
text = f"{text[:pos]}\_{text[pos + 1 :]}"
text = f"{text[:pos]}\\_{text[pos + 1 :]}"
pos += 2
else:
pos += 1

View file

@ -2938,6 +2938,8 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
}
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::MODEL_FLAGS, inst->flags_cache, shader->version, instance_variant, spec_constants);
// Can be index count or vertex count
uint32_t count = 0;
if (surf->lod_index > 0) {

View file

@ -139,6 +139,8 @@ layout(location = 14) in highp vec4 instance_xform2;
layout(location = 15) in highp uvec4 instance_color_custom_data; // Color packed into xy, Custom data into zw.
#endif
#define FLAGS_NON_UNIFORM_SCALE (1 << 4)
layout(std140) uniform GlobalShaderUniformData { //ubo:1
vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS];
};
@ -242,6 +244,8 @@ uniform highp vec3 compressed_aabb_position;
uniform highp vec3 compressed_aabb_size;
uniform highp vec4 uv_scale;
uniform highp uint model_flags;
/* Varyings */
out highp vec3 vertex_interp;
@ -310,7 +314,14 @@ void main() {
#ifdef NORMAL_USED
vec3 normal = oct_to_vec3(axis_tangent_attrib.xy * 2.0 - 1.0);
#endif
highp mat3 model_normal_matrix = mat3(model_matrix);
highp mat3 model_normal_matrix;
if (bool(model_flags & uint(FLAGS_NON_UNIFORM_SCALE))) {
model_normal_matrix = transpose(inverse(mat3(model_matrix)));
} else {
model_normal_matrix = mat3(model_matrix);
}
#if defined(NORMAL_USED) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
@ -1600,6 +1611,8 @@ void main() {
#if !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT)
#ifndef SHADOWS_DISABLED
// Orthogonal shadows
#if !defined(LIGHT_USE_PSSM2) && !defined(LIGHT_USE_PSSM4)
float directional_shadow = sample_shadow(directional_shadow_atlas, directional_shadows[directional_shadow_index].shadow_atlas_pixel_size, shadow_coord);
@ -1706,6 +1719,9 @@ void main() {
directional_shadow = mix(directional_shadow, 1.0, smoothstep(directional_shadows[directional_shadow_index].fade_from, directional_shadows[directional_shadow_index].fade_to, vertex.z));
directional_shadow = mix(1.0, directional_shadow, directional_lights[directional_shadow_index].shadow_opacity);
#else
float directional_shadow = 1.0f;
#endif // SHADOWS_DISABLED
light_compute(normal, normalize(directional_lights[directional_shadow_index].direction), normalize(view), directional_lights[directional_shadow_index].size, directional_lights[directional_shadow_index].color * directional_lights[directional_shadow_index].energy, true, directional_shadow, f0, roughness, metallic, 1.0, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@ -1725,11 +1741,12 @@ void main() {
#endif // !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT)
#ifdef ADDITIVE_OMNI
float omni_shadow = 1.0f;
#ifndef SHADOWS_DISABLED
vec3 light_ray = ((positional_shadows[positional_shadow_index].shadow_matrix * vec4(shadow_coord.xyz, 1.0))).xyz;
float omni_shadow = texture(omni_shadow_texture, vec4(light_ray, length(light_ray) * omni_lights[omni_light_index].inv_radius));
omni_shadow = texture(omni_shadow_texture, vec4(light_ray, length(light_ray) * omni_lights[omni_light_index].inv_radius));
omni_shadow = mix(1.0, omni_shadow, omni_lights[omni_light_index].shadow_opacity);
#endif // SHADOWS_DISABLED
light_process_omni(omni_light_index, vertex, view, normal, f0, roughness, metallic, omni_shadow, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@ -1748,9 +1765,11 @@ void main() {
#endif // ADDITIVE_OMNI
#ifdef ADDITIVE_SPOT
float spot_shadow = sample_shadow(spot_shadow_texture, positional_shadows[positional_shadow_index].shadow_atlas_pixel_size, shadow_coord);
float spot_shadow = 1.0f;
#ifndef SHADOWS_DISABLED
spot_shadow = sample_shadow(spot_shadow_texture, positional_shadows[positional_shadow_index].shadow_atlas_pixel_size, shadow_coord);
spot_shadow = mix(1.0, spot_shadow, spot_lights[spot_light_index].shadow_opacity);
#endif // SHADOWS_DISABLED
light_process_spot(spot_light_index, vertex, view, normal, f0, roughness, metallic, spot_shadow, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,

View file

@ -2968,17 +2968,17 @@ void SceneShaderData::set_code(const String &p_code) {
depth_test = DepthTest(depth_testi);
cull_mode = Cull(cull_modei);
vertex_input_mask = uint64_t(uses_normal);
vertex_input_mask |= uses_tangent << 1;
vertex_input_mask |= uses_color << 2;
vertex_input_mask |= uses_uv << 3;
vertex_input_mask |= uses_uv2 << 4;
vertex_input_mask |= uses_custom0 << 5;
vertex_input_mask |= uses_custom1 << 6;
vertex_input_mask |= uses_custom2 << 7;
vertex_input_mask |= uses_custom3 << 8;
vertex_input_mask |= uses_bones << 9;
vertex_input_mask |= uses_weights << 10;
vertex_input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL; // We can always read vertices and normals.
vertex_input_mask |= uses_tangent << RS::ARRAY_TANGENT;
vertex_input_mask |= uses_color << RS::ARRAY_COLOR;
vertex_input_mask |= uses_uv << RS::ARRAY_TEX_UV;
vertex_input_mask |= uses_uv2 << RS::ARRAY_TEX_UV2;
vertex_input_mask |= uses_custom0 << RS::ARRAY_CUSTOM0;
vertex_input_mask |= uses_custom1 << RS::ARRAY_CUSTOM1;
vertex_input_mask |= uses_custom2 << RS::ARRAY_CUSTOM2;
vertex_input_mask |= uses_custom3 << RS::ARRAY_CUSTOM3;
vertex_input_mask |= uses_bones << RS::ARRAY_BONES;
vertex_input_mask |= uses_weights << RS::ARRAY_WEIGHTS;
uses_screen_texture = gen_code.uses_screen_texture;
uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;

View file

@ -764,14 +764,17 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
int skin_stride = 0;
for (int i = 0; i < RS::ARRAY_INDEX; i++) {
attribs[i].enabled = false;
attribs[i].integer = false;
if (!(s->format & (1ULL << i))) {
attribs[i].enabled = false;
attribs[i].integer = false;
continue;
}
attribs[i].enabled = true;
attribs[i].integer = false;
if ((p_input_mask & (1ULL << i))) {
// Only enable if it matches input mask.
// Iterate over all anyway, so we can calculate stride.
attribs[i].enabled = true;
}
switch (i) {
case RS::ARRAY_VERTEX: {
@ -1108,8 +1111,6 @@ void MeshStorage::_blend_shape_bind_mesh_instance_buffer(MeshInstance *p_mi, uin
}
void MeshStorage::_compute_skeleton(MeshInstance *p_mi, Skeleton *p_sk, uint32_t p_surface) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Add in the bones and weights.
glBindBuffer(GL_ARRAY_BUFFER, p_mi->mesh->surfaces[p_surface]->skin_buffer);
@ -1200,9 +1201,8 @@ void MeshStorage::update_mesh_instances() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLuint vertex_array_gl = 0;
uint64_t mask = ((1 << 10) - 1) << 3; // Mask from ARRAY_FORMAT_COLOR to ARRAY_FORMAT_INDEX.
mask = ~mask;
uint64_t format = mi->surfaces[i].format_cache & mask; // Format should only have vertex, normal, tangent (as necessary) + compressions.
uint64_t mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_VERTEX;
uint64_t format = mi->mesh->surfaces[i]->format & mask; // Format should only have vertex, normal, tangent (as necessary).
mesh_surface_get_vertex_arrays_and_format(mi->mesh->surfaces[i], format, vertex_array_gl);
glBindVertexArray(vertex_array_gl);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mi->surfaces[i].vertex_buffers[0]);
@ -1315,9 +1315,8 @@ void MeshStorage::update_mesh_instances() {
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);
GLuint vertex_array_gl = 0;
uint64_t mask = ((1 << 10) - 1) << 3; // Mask from ARRAY_FORMAT_COLOR to ARRAY_FORMAT_INDEX.
mask = ~mask;
uint64_t format = mi->surfaces[i].format_cache & mask; // Format should only have vertex, normal, tangent (as necessary) + compressions.
uint64_t mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_VERTEX;
uint64_t format = mi->mesh->surfaces[i]->format & mask; // Format should only have vertex, normal, tangent (as necessary).
mesh_surface_get_vertex_arrays_and_format(mi->mesh->surfaces[i], format, vertex_array_gl);
glBindVertexArray(vertex_array_gl);
_compute_skeleton(mi, sk, i);

View file

@ -1365,6 +1365,9 @@ Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size,
allocInfo.memoryTypeBits = 0;
allocInfo.pool = nullptr;
allocInfo.pUserData = nullptr;
if (p_mem_usage == VMA_MEMORY_USAGE_AUTO_PREFER_HOST) {
allocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
}
if (p_size <= SMALL_ALLOCATION_MAX_SIZE) {
uint32_t mem_type_index = 0;
vmaFindMemoryTypeIndexForBufferInfo(allocator, &bufferInfo, &allocInfo, &mem_type_index);
@ -1410,7 +1413,7 @@ Error RenderingDeviceVulkan::_insert_staging_block() {
VmaAllocationCreateInfo allocInfo;
allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST;
allocInfo.requiredFlags = 0;
allocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
allocInfo.preferredFlags = 0;
allocInfo.memoryTypeBits = 0;
allocInfo.pool = nullptr;
@ -5995,7 +5998,7 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint
// No barrier should be needed here.
// _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, true);
Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, p_post_barrier);
Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, true);
if (err) {
return err;
}

View file

@ -43,7 +43,7 @@
#define _DEBUG
#endif
#endif
#include "vk_mem_alloc.h"
#include "thirdparty/vulkan/vk_mem_alloc.h"
#ifdef USE_VOLK
#include <volk.h>
@ -1015,8 +1015,13 @@ class RenderingDeviceVulkan : public RenderingDevice {
List<ComputePipeline> compute_pipelines_to_dispose_of;
VkCommandPool command_pool = VK_NULL_HANDLE;
VkCommandBuffer setup_command_buffer = VK_NULL_HANDLE; // Used at the beginning of every frame for set-up.
VkCommandBuffer draw_command_buffer = VK_NULL_HANDLE; // Used at the beginning of every frame for set-up.
// Used for filling up newly created buffers with data provided on creation.
// Primarily intended to be accessed by worker threads.
// Ideally this cmd buffer should use an async transfer queue.
VkCommandBuffer setup_command_buffer = VK_NULL_HANDLE;
// The main cmd buffer for drawing and compute.
// Primarily intended to be used by the main thread to do most stuff.
VkCommandBuffer draw_command_buffer = VK_NULL_HANDLE;
struct Timestamp {
String description;

View file

@ -39,29 +39,25 @@
// The metadata key used to store and retrieve the version text to copy to the clipboard.
const String EditorAbout::META_TEXT_TO_COPY = "text_to_copy";
void EditorAbout::_theme_changed() {
const Ref<Font> font = get_theme_font(SNAME("source"), EditorStringName(EditorFonts));
const int font_size = get_theme_font_size(SNAME("source_size"), EditorStringName(EditorFonts));
_tpl_text->begin_bulk_theme_override();
_tpl_text->add_theme_font_override("normal_font", font);
_tpl_text->add_theme_font_size_override("normal_font_size", font_size);
_tpl_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
_tpl_text->end_bulk_theme_override();
_license_text->begin_bulk_theme_override();
_license_text->add_theme_font_override("normal_font", font);
_license_text->add_theme_font_size_override("normal_font_size", font_size);
_license_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
_license_text->end_bulk_theme_override();
_logo->set_texture(get_editor_theme_icon(SNAME("Logo")));
}
void EditorAbout::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_theme_changed();
case NOTIFICATION_THEME_CHANGED: {
const Ref<Font> font = get_theme_font(SNAME("source"), EditorStringName(EditorFonts));
const int font_size = get_theme_font_size(SNAME("source_size"), EditorStringName(EditorFonts));
_tpl_text->begin_bulk_theme_override();
_tpl_text->add_theme_font_override("normal_font", font);
_tpl_text->add_theme_font_size_override("normal_font_size", font_size);
_tpl_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
_tpl_text->end_bulk_theme_override();
_license_text->begin_bulk_theme_override();
_license_text->add_theme_font_override("normal_font", font);
_license_text->add_theme_font_size_override("normal_font_size", font_size);
_license_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
_license_text->end_bulk_theme_override();
_logo->set_texture(get_editor_theme_icon(SNAME("Logo")));
} break;
}
}
@ -128,12 +124,12 @@ EditorAbout::EditorAbout() {
set_hide_on_ok(true);
VBoxContainer *vbc = memnew(VBoxContainer);
vbc->connect("theme_changed", callable_mp(this, &EditorAbout::_theme_changed));
add_child(vbc);
HBoxContainer *hbc = memnew(HBoxContainer);
hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hbc->set_alignment(BoxContainer::ALIGNMENT_CENTER);
hbc->add_theme_constant_override("separation", 30 * EDSCALE);
add_child(vbc);
vbc->add_child(hbc);
_logo = memnew(TextureRect);

View file

@ -64,8 +64,6 @@ private:
RichTextLabel *_tpl_text = nullptr;
TextureRect *_logo = nullptr;
void _theme_changed();
protected:
void _notification(int p_what);
static void _bind_methods();

View file

@ -407,31 +407,30 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
scn.instantiate();
scn->set_path(p_path);
scn->reload_from_file();
ERR_FAIL_COND_V_MSG(!scn.is_valid(), nullptr, vformat("Can't autoload: %s.", p_path));
ERR_FAIL_COND_V_MSG(!scn.is_valid(), nullptr, vformat("Failed to create an autoload, can't load from path: %s.", p_path));
if (scn.is_valid()) {
n = scn->instantiate();
}
} else {
Ref<Resource> res = ResourceLoader::load(p_path);
ERR_FAIL_COND_V_MSG(res.is_null(), nullptr, vformat("Can't autoload: %s.", p_path));
ERR_FAIL_COND_V_MSG(res.is_null(), nullptr, vformat("Failed to create an autoload, can't load from path: %s.", p_path));
Ref<Script> scr = res;
if (scr.is_valid()) {
StringName ibt = scr->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
ERR_FAIL_COND_V_MSG(!valid_type, nullptr, vformat("Script does not inherit from Node: %s.", p_path));
ERR_FAIL_COND_V_MSG(!valid_type, nullptr, vformat("Failed to create an autoload, script '%s' does not inherit from 'Node'.", p_path));
Object *obj = ClassDB::instantiate(ibt);
ERR_FAIL_NULL_V_MSG(obj, nullptr, vformat("Cannot instance script for Autoload, expected 'Node' inheritance, got: %s.", ibt));
ERR_FAIL_NULL_V_MSG(obj, nullptr, vformat("Failed to create an autoload, cannot instantiate '%s'.", ibt));
n = Object::cast_to<Node>(obj);
n->set_script(scr);
}
}
ERR_FAIL_NULL_V_MSG(n, nullptr, vformat("Path in Autoload not a node or script: %s.", p_path));
ERR_FAIL_NULL_V_MSG(n, nullptr, vformat("Failed to create an autoload, path is not pointing to a scene or a script: %s.", p_path));
return n;
}

View file

@ -129,8 +129,8 @@ void EditorCommandPalette::_update_command_search(const String &search_text) {
section->set_text(0, item_name);
section->set_selectable(0, false);
section->set_selectable(1, false);
section->set_custom_bg_color(0, search_options->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
section->set_custom_bg_color(1, search_options->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
section->set_custom_bg_color(0, get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
section->set_custom_bg_color(1, get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
sections[section_name] = section;
}
@ -164,6 +164,10 @@ void EditorCommandPalette::_notification(int p_what) {
was_showed = true;
}
} break;
case NOTIFICATION_THEME_CHANGED: {
command_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
} break;
}
}
@ -303,10 +307,6 @@ Ref<Shortcut> EditorCommandPalette::add_shortcut_command(const String &p_command
return p_shortcut;
}
void EditorCommandPalette::_theme_changed() {
command_search_box->set_right_icon(search_options->get_editor_theme_icon(SNAME("Search")));
}
void EditorCommandPalette::_save_history() const {
Dictionary command_history;
@ -330,7 +330,6 @@ EditorCommandPalette::EditorCommandPalette() {
connect("confirmed", callable_mp(this, &EditorCommandPalette::_confirmed));
VBoxContainer *vbc = memnew(VBoxContainer);
vbc->connect("theme_changed", callable_mp(this, &EditorCommandPalette::_theme_changed));
add_child(vbc);
command_search_box = memnew(LineEdit);

View file

@ -83,10 +83,9 @@ class EditorCommandPalette : public ConfirmationDialog {
float _score_path(const String &p_search, const String &p_path);
void _sbox_input(const Ref<InputEvent> &p_ie);
void _confirmed();
void _update_command_keys();
void _add_command(String p_command_name, String p_key_name, Callable p_binded_action, String p_shortcut_text = "None");
void _theme_changed();
void _save_history() const;
EditorCommandPalette();
protected:

View file

@ -3459,13 +3459,13 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
}
// Plugin init scripts must inherit from EditorPlugin and be tools.
if (String(scr->get_instance_base_type()) != "EditorPlugin") {
show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), script_path));
if (!ClassDB::is_parent_class(scr->get_instance_base_type(), "EditorPlugin")) {
show_warning(vformat(TTR("Unable to load addon script from path: '%s'. Base type is not 'EditorPlugin'."), script_path));
return;
}
if (!scr->is_tool()) {
show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), script_path));
show_warning(vformat(TTR("Unable to load addon script from path: '%s'. Script is not in tool mode."), script_path));
return;
}
}

View file

@ -198,6 +198,10 @@ void EditorPropertyArray::_property_changed(const String &p_property, Variant p_
return;
}
if (p_value.get_type() == Variant::OBJECT && p_value.is_null()) {
p_value = Variant(); // `EditorResourcePicker` resets to `Ref<Resource>()`. See GH-82716.
}
int index;
if (p_property.begins_with("metadata/")) {
index = p_property.get_slice("/", 2).to_int();
@ -726,6 +730,10 @@ EditorPropertyArray::EditorPropertyArray() {
///////////////////// DICTIONARY ///////////////////////////
void EditorPropertyDictionary::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
if (p_value.get_type() == Variant::OBJECT && p_value.is_null()) {
p_value = Variant(); // `EditorResourcePicker` resets to `Ref<Resource>()`. See GH-82716.
}
if (p_property == "new_item_key") {
object->set_new_item_key(p_value);
} else if (p_property == "new_item_value") {

View file

@ -250,23 +250,22 @@ void EditorQuickOpen::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
} break;
case NOTIFICATION_EXIT_TREE: {
disconnect("confirmed", callable_mp(this, &EditorQuickOpen::_confirmed));
} break;
}
}
void EditorQuickOpen::_theme_changed() {
search_box->set_right_icon(search_options->get_editor_theme_icon(SNAME("Search")));
}
void EditorQuickOpen::_bind_methods() {
ADD_SIGNAL(MethodInfo("quick_open"));
}
EditorQuickOpen::EditorQuickOpen() {
VBoxContainer *vbc = memnew(VBoxContainer);
vbc->connect("theme_changed", callable_mp(this, &EditorQuickOpen::_theme_changed));
add_child(vbc);
search_box = memnew(LineEdit);

View file

@ -72,8 +72,6 @@ class EditorQuickOpen : public ConfirmationDialog {
void _sbox_input(const Ref<InputEvent> &p_ie);
void _text_changed(const String &p_newtext);
void _theme_changed();
protected:
void _notification(int p_what);
static void _bind_methods();

View file

@ -1431,7 +1431,7 @@ void EditorExportPlatform::zip_folder_recursive(zipFile &p_zip, const String &p_
nullptr,
0,
0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions
0);
1 << 11); // Bit 11 is the language encoding flag. When set, filename and comment fields must be encoded using UTF-8.
String target = da->read_link(f);
zipWriteInFileInZip(p_zip, target.utf8().get_data(), target.utf8().size());
@ -1475,7 +1475,7 @@ void EditorExportPlatform::zip_folder_recursive(zipFile &p_zip, const String &p_
nullptr,
0,
0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions
0);
1 << 11); // Bit 11 is the language encoding flag. When set, filename and comment fields must be encoded using UTF-8.
Ref<FileAccess> fa = FileAccess::open(dir.path_join(f), FileAccess::READ);
if (fa.is_null()) {

View file

@ -90,11 +90,6 @@ ProjectExportTextureFormatError::ProjectExportTextureFormatError() {
fix_texture_format_button->connect("pressed", callable_mp(this, &ProjectExportTextureFormatError::_on_fix_texture_format_pressed));
}
void ProjectExportDialog::_theme_changed() {
duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
}
void ProjectExportDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
@ -103,6 +98,11 @@ void ProjectExportDialog::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
} break;
case NOTIFICATION_READY: {
duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
@ -1161,8 +1161,8 @@ ProjectExportDialog::ProjectExportDialog() {
set_clamp_to_embedder(true);
VBoxContainer *main_vb = memnew(VBoxContainer);
main_vb->connect("theme_changed", callable_mp(this, &ProjectExportDialog::_theme_changed));
add_child(main_vb);
HSplitContainer *hbox = memnew(HSplitContainer);
main_vb->add_child(hbox);
hbox->set_v_size_flags(Control::SIZE_EXPAND_FILL);

View file

@ -188,7 +188,6 @@ class ProjectExportDialog : public ConfirmationDialog {
void _tab_changed(int);
protected:
void _theme_changed();
void _notification(int p_what);
static void _bind_methods();

View file

@ -1595,6 +1595,9 @@ void FileSystemDock::_update_dependencies_after_move(const HashMap<String, Strin
// The following code assumes that the following holds:
// 1) EditorFileSystem contains the old paths/folder structure from before the rename/move.
// 2) ResourceLoader can use the new paths without needing to call rescan.
// The currently edited scene should be reloaded first, so get it's path (GH-82652).
const String &edited_scene_path = EditorNode::get_editor_data().get_scene_path(EditorNode::get_editor_data().get_edited_scene());
List<String> scenes_to_reload;
for (const String &E : p_file_owners) {
// Because we haven't called a rescan yet the found remap might still be an old path itself.
@ -1604,7 +1607,11 @@ void FileSystemDock::_update_dependencies_after_move(const HashMap<String, Strin
const Error err = ResourceLoader::rename_dependencies(file, p_renames);
if (err == OK) {
if (ResourceLoader::get_resource_type(file) == "PackedScene") {
scenes_to_reload.push_back(file);
if (file == edited_scene_path) {
scenes_to_reload.push_front(file);
} else {
scenes_to_reload.push_back(file);
}
}
} else {
EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies for:") + "\n" + E + "\n");

View file

@ -50,7 +50,7 @@
#include "scene/main/window.h"
#include "scene/resources/packed_scene.h"
Node *SceneTreeEditor::get_scene_node() {
Node *SceneTreeEditor::get_scene_node() const {
ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
return get_tree()->get_edited_scene_root();
@ -1218,11 +1218,8 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
Node *n = get_node(np);
if (n) {
// Only allow selection if not part of an instantiated scene.
if (!n->get_owner() || n->get_owner() == get_scene_node() || n->get_owner()->get_scene_file_path().is_empty()) {
selected_nodes.push_back(n);
icons.push_back(next->get_icon(0));
}
selected_nodes.push_back(n);
icons.push_back(next->get_icon(0));
}
next = tree->get_next_selected(next);
}
@ -1336,7 +1333,21 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
}
}
return String(d["type"]) == "nodes" && filter.is_empty();
if (filter.is_empty() && String(d["type"]) == "nodes") {
Array nodes = d["nodes"];
for (int i = 0; i < nodes.size(); i++) {
Node *n = get_node(nodes[i]);
// Nodes from an instantiated scene can't be rearranged.
if (n && n->get_owner() && n->get_owner() != get_scene_node() && !n->get_owner()->get_scene_file_path().is_empty()) {
return false;
}
}
return true;
}
return false;
}
void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {

View file

@ -120,7 +120,7 @@ class SceneTreeEditor : public Control {
void _set_item_custom_color(TreeItem *p_item, Color p_color);
void _selection_changed();
Node *get_scene_node();
Node *get_scene_node() const;
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;

View file

@ -1 +1 @@
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 0v2H0v1h2v4H0v1h2v4H0v1h2v2h1v-2h3v-1H3V8h4l1-1V3h4v3h1V3h2V2h-2V0h-1v2H8V0H7v2H3V0zm1 3h4v4H3zm4 10v2h2v-2zm6 0v2h2v-2z" fill="#def"/><path d="M7 13h2v-2a2 2 0 0 1 4 0v2h2v-2a4 4 0 0 0-8 0z" fill="#def" fill-opacity=".8"/></svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 0v2H0v1h2v4H0v1h2v4H0v1h2v2h1v-2h3v-1H3V8h4l1-1V3h4v3h1V3h2V2h-2V0h-1v2H8V0H7v2H3V0zm1 3h4v4H3zm4 10v2h2v-2zm6 0v2h2v-2z" fill="#e0e0e0"/><path d="M7 13h2v-2a2 2 0 0 1 4 0v2h2v-2a4 4 0 0 0-8 0z" fill="#e0e0e0" fill-opacity=".8"/></svg>

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 311 B

View file

@ -1505,6 +1505,7 @@ void ResourceImporterScene::_create_slices(AnimationPlayer *ap, Ref<Animation> a
new_anim->add_track(anim->track_get_type(j));
dtrack = new_anim->get_track_count() - 1;
new_anim->track_set_path(dtrack, anim->track_get_path(j));
new_anim->track_set_imported(dtrack, true);
if (kt > (from + 0.01) && k > 0) {
if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
@ -1580,6 +1581,7 @@ void ResourceImporterScene::_create_slices(AnimationPlayer *ap, Ref<Animation> a
new_anim->add_track(anim->track_get_type(j));
dtrack = new_anim->get_track_count() - 1;
new_anim->track_set_path(dtrack, anim->track_get_path(j));
new_anim->track_set_imported(dtrack, true);
if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
Vector3 p;
anim->try_position_track_interpolate(j, from, &p);

View file

@ -292,7 +292,9 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
loop_end = file->get_32();
}
}
file->seek(file_pos + chunksize);
// Move to the start of the next chunk. Note that RIFF requires a padding byte for odd
// chunk sizes.
file->seek(file_pos + chunksize + (chunksize & 1));
}
// STEP 2, APPLY CONVERSIONS

View file

@ -553,9 +553,8 @@ void InputEventConfigurationDialog::_notification(int p_what) {
event_listener->grab_focus();
} break;
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
input_list_search->set_right_icon(input_list_search->get_editor_theme_icon(SNAME("Search")));
input_list_search->set_right_icon(get_editor_theme_icon(SNAME("Search")));
key_mode->set_item_icon(KEYMODE_KEYCODE, get_editor_theme_icon(SNAME("Keyboard")));
key_mode->set_item_icon(KEYMODE_PHY_KEYCODE, get_editor_theme_icon(SNAME("KeyboardPhysical")));
@ -613,12 +612,13 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION;
set_title(TTR("Event Configuration"));
set_min_size(Size2i(550 * EDSCALE, 0)); // Min width
set_min_size(Size2i(550, 0) * EDSCALE);
VBoxContainer *main_vbox = memnew(VBoxContainer);
add_child(main_vbox);
event_as_text = memnew(Label);
event_as_text->set_custom_minimum_size(Size2(500, 0) * EDSCALE);
event_as_text->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
event_as_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
event_as_text->add_theme_font_size_override("font_size", 18 * EDSCALE);

View file

@ -223,6 +223,9 @@ GPUParticles3DEditorBase::GPUParticles3DEditorBase() {
emission_dialog->connect("confirmed", callable_mp(this, &GPUParticles3DEditorBase::_generate_emission_points));
emission_tree_dialog = memnew(SceneTreeDialog);
Vector<StringName> valid_types;
valid_types.push_back("MeshInstance3D");
emission_tree_dialog->set_valid_types(valid_types);
add_child(emission_tree_dialog);
emission_tree_dialog->connect("selected", callable_mp(this, &GPUParticles3DEditorBase::_node_selected));
}

View file

@ -354,6 +354,9 @@ MultiMeshEditor::MultiMeshEditor() {
populate_dialog->get_ok_button()->connect("pressed", callable_mp(this, &MultiMeshEditor::_populate));
std = memnew(SceneTreeDialog);
Vector<StringName> valid_types;
valid_types.push_back("MeshInstance3D");
std->set_valid_types(valid_types);
populate_dialog->add_child(std);
std->connect("selected", callable_mp(this, &MultiMeshEditor::_browsed));

View file

@ -4152,6 +4152,7 @@ Node *Node3DEditorViewport::_sanitize_preview_node(Node *p_node) const {
}
void Node3DEditorViewport::_create_preview_node(const Vector<String> &files) const {
bool add_preview = false;
for (int i = 0; i < files.size(); i++) {
String path = files[i];
Ref<Resource> res = ResourceLoader::load(path);
@ -4172,9 +4173,13 @@ void Node3DEditorViewport::_create_preview_node(const Vector<String> &files) con
}
}
}
EditorNode::get_singleton()->get_scene_root()->add_child(preview_node);
add_preview = true;
}
}
if (add_preview) {
EditorNode::get_singleton()->get_scene_root()->add_child(preview_node);
}
*preview_bounds = _calculate_spatial_bounds(preview_node);
}

View file

@ -713,6 +713,9 @@ void Path3DEditorPlugin::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
// FIXME: This can trigger theme updates when the nodes that we want to update are not yet available.
// The toolbar should be extracted to a dedicated control and theme updates should be handled through
// the notification.
Node3DEditor::get_singleton()->connect("theme_changed", callable_mp(this, &Path3DEditorPlugin::_update_theme));
} break;
}

View file

@ -456,6 +456,7 @@ void Polygon2DEditor::_uv_mode(int p_mode) {
for (int i = 0; i < UV_MODE_MAX; i++) {
uv_button[i]->set_pressed(p_mode == i);
}
uv_edit_draw->queue_redraw();
}
void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
@ -989,9 +990,36 @@ void Polygon2DEditor::_uv_draw() {
mtx.columns[2] = -uv_draw_ofs;
mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom));
RS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(), mtx);
uv_edit_draw->draw_texture(base_tex, Point2());
RS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(), Transform2D());
// Draw texture as a background if editing uvs or no uv mapping exist.
if (uv_edit_mode[0]->is_pressed() || uv_mode == UV_MODE_CREATE || node->get_polygon().is_empty() || node->get_uv().size() != node->get_polygon().size()) {
Transform2D texture_transform = Transform2D(node->get_texture_rotation(), node->get_texture_offset());
texture_transform.scale(node->get_texture_scale());
texture_transform.affine_invert();
RS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(), mtx * texture_transform);
uv_edit_draw->draw_texture(base_tex, Point2());
RS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(), Transform2D());
preview_polygon->hide();
} else {
preview_polygon->set_transform(mtx);
// Keep in sync with newly added Polygon2D properties (when relevant).
preview_polygon->set_texture(node->get_texture());
preview_polygon->set_texture_offset(node->get_texture_offset());
preview_polygon->set_texture_rotation(node->get_texture_rotation());
preview_polygon->set_texture_scale(node->get_texture_scale());
preview_polygon->set_texture_filter(node->get_texture_filter_in_tree());
preview_polygon->set_texture_repeat(node->get_texture_repeat_in_tree());
preview_polygon->set_polygon(node->get_polygon());
preview_polygon->set_uv(node->get_uv());
preview_polygon->set_invert(node->get_invert());
preview_polygon->set_invert_border(node->get_invert_border());
preview_polygon->set_internal_vertex_count(node->get_internal_vertex_count());
if (uv_mode == UV_MODE_ADD_POLYGON) {
preview_polygon->set_polygons(Array());
} else {
preview_polygon->set_polygons(node->get_polygons());
}
preview_polygon->show();
}
if (snap_show_grid) {
Color grid_color = Color(1.0, 1.0, 1.0, 0.15);
@ -1357,10 +1385,19 @@ Polygon2DEditor::Polygon2DEditor() {
HSplitContainer *uv_main_hsc = memnew(HSplitContainer);
uv_main_vb->add_child(uv_main_hsc);
uv_main_hsc->set_v_size_flags(SIZE_EXPAND_FILL);
uv_edit_draw = memnew(Panel);
uv_main_hsc->add_child(uv_edit_draw);
uv_edit_draw->set_h_size_flags(SIZE_EXPAND_FILL);
uv_edit_draw->set_custom_minimum_size(Size2(200, 200) * EDSCALE);
uv_edit_background = memnew(Panel);
uv_main_hsc->add_child(uv_edit_background);
uv_edit_background->set_h_size_flags(SIZE_EXPAND_FILL);
uv_edit_background->set_custom_minimum_size(Size2(200, 200) * EDSCALE);
uv_edit_background->set_clip_contents(true);
preview_polygon = memnew(Polygon2D);
uv_edit_background->add_child(preview_polygon);
uv_edit_draw = memnew(Control);
uv_edit_background->add_child(uv_edit_draw);
uv_edit_draw->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
Control *space = memnew(Control);
uv_mode_hb->add_child(space);
@ -1503,8 +1540,6 @@ Polygon2DEditor::Polygon2DEditor() {
error = memnew(AcceptDialog);
add_child(error);
uv_edit_draw->set_clip_contents(true);
}
Polygon2DEditorPlugin::Polygon2DEditorPlugin() :

View file

@ -82,7 +82,9 @@ class Polygon2DEditor : public AbstractPolygon2DEditor {
Button *uv_button[UV_MODE_MAX];
Button *b_snap_enable = nullptr;
Button *b_snap_grid = nullptr;
Panel *uv_edit_draw = nullptr;
Panel *uv_edit_background = nullptr;
Polygon2D *preview_polygon = nullptr;
Control *uv_edit_draw = nullptr;
HSlider *uv_zoom = nullptr;
SpinBox *uv_zoom_value = nullptr;
HScrollBar *uv_hscroll = nullptr;

View file

@ -1650,7 +1650,7 @@ void ScriptTextEditor::reload(bool p_soft) {
return;
}
scr->set_source_code(te->get_text());
bool soft = p_soft || scr->get_instance_base_type() == "EditorPlugin"; // Always soft-reload editor plugins.
bool soft = p_soft || ClassDB::is_parent_class(scr->get_instance_base_type(), "EditorPlugin"); // Always soft-reload editor plugins.
scr->get_language()->reload_tool_script(scr, soft);
}

View file

@ -2373,7 +2373,9 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
// --- Bottom panel tiles ---
tiles_bottom_panel = memnew(VBoxContainer);
tiles_bottom_panel->connect("tree_entered", callable_mp(this, &TileMapEditorTilesPlugin::_update_theme));
// FIXME: This can trigger theme updates when the nodes that we want to update are not yet available.
// The toolbar should be extracted to a dedicated control and theme updates should be handled through
// the notification.
tiles_bottom_panel->connect("theme_changed", callable_mp(this, &TileMapEditorTilesPlugin::_update_theme));
tiles_bottom_panel->connect("visibility_changed", callable_mp(this, &TileMapEditorTilesPlugin::_stop_dragging));
tiles_bottom_panel->connect("visibility_changed", callable_mp(this, &TileMapEditorTilesPlugin::_tab_changed));
@ -3536,7 +3538,9 @@ void TileMapEditorTerrainsPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_la
TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() {
main_vbox_container = memnew(VBoxContainer);
main_vbox_container->connect("tree_entered", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme));
// FIXME: This can trigger theme updates when the nodes that we want to update are not yet available.
// The toolbar should be extracted to a dedicated control and theme updates should be handled through
// the notification.
main_vbox_container->connect("theme_changed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme));
main_vbox_container->set_name(TTR("Terrains"));

View file

@ -101,12 +101,6 @@ void ProjectDialog::_set_message(const String &p_msg, MessageType p_type, InputT
} else if (current_install_icon != new_icon && input_type == INSTALL_PATH) {
install_status_rect->set_texture(new_icon);
}
Size2i window_size = get_size();
Size2 contents_min_size = get_contents_minimum_size();
if (window_size.x < contents_min_size.x || window_size.y < contents_min_size.y) {
set_size(window_size.max(contents_min_size));
}
}
String ProjectDialog::_test_path() {
@ -868,6 +862,7 @@ ProjectDialog::ProjectDialog() {
msg = memnew(Label);
msg->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
msg->set_custom_minimum_size(Size2(200, 0) * EDSCALE);
vb->add_child(msg);
// Renderer selection.

View file

@ -2179,6 +2179,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
}
int child_pos = node->get_index(false);
bool reparented_to_container = Object::cast_to<Container>(new_parent) && Object::cast_to<Control>(node);
undo_redo->add_undo_method(node->get_parent(), "add_child", node, true);
undo_redo->add_undo_method(node->get_parent(), "move_child", node, child_pos);
@ -2194,10 +2195,14 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
if (Object::cast_to<Node3D>(node)) {
undo_redo->add_undo_method(node, "set_transform", Object::cast_to<Node3D>(node)->get_transform());
}
if (Object::cast_to<Control>(node)) {
if (!reparented_to_container && Object::cast_to<Control>(node)) {
undo_redo->add_undo_method(node, "set_position", Object::cast_to<Control>(node)->get_position());
}
}
if (reparented_to_container) {
undo_redo->add_undo_method(node, "_edit_set_state", Object::cast_to<Control>(node)->_edit_get_state());
}
}
perform_node_renames(nullptr, &path_renames);

View file

@ -48,8 +48,6 @@ enum ShaderType {
void ShaderCreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_update_theme();
String last_lang = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_language", "");
if (!last_lang.is_empty()) {
for (int i = 0; i < type_menu->get_item_count(); i++) {
@ -68,30 +66,19 @@ void ShaderCreateDialog::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
_update_theme();
static const char *shader_types[3] = { "Shader", "VisualShader", "TextFile" };
for (int i = 0; i < 3; i++) {
Ref<Texture2D> icon = get_editor_theme_icon(shader_types[i]);
if (icon.is_valid()) {
type_menu->set_item_icon(i, icon);
}
}
path_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
} break;
}
}
void ShaderCreateDialog::_update_theme() {
Ref<Texture2D> shader_icon = gc->get_editor_theme_icon(SNAME("Shader"));
if (shader_icon.is_valid()) {
type_menu->set_item_icon(0, shader_icon);
}
Ref<Texture2D> visual_shader_icon = gc->get_editor_theme_icon(SNAME("VisualShader"));
if (visual_shader_icon.is_valid()) {
type_menu->set_item_icon(1, visual_shader_icon);
}
Ref<Texture2D> include_icon = gc->get_editor_theme_icon(SNAME("TextFile"));
if (include_icon.is_valid()) {
type_menu->set_item_icon(2, include_icon);
}
path_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
}
void ShaderCreateDialog::_update_language_info() {
type_data.clear();
@ -175,9 +162,10 @@ void fragment() {
// Called for every pixel the material is visible on.
}
void light() {
//void light() {
// Called for every pixel for every light affecting the material.
}
// Uncomment to replace the default light processing function with this one.
//}
)";
break;
case Shader::MODE_CANVAS_ITEM:
@ -190,9 +178,10 @@ void fragment() {
// Called for every pixel the material is visible on.
}
void light() {
//void light() {
// Called for every pixel for every light affecting the CanvasItem.
}
// Uncomment to replace the default light processing function with this one.
//}
)";
break;
case Shader::MODE_PARTICLES:

View file

@ -101,7 +101,6 @@ class ShaderCreateDialog : public ConfirmationDialog {
void _update_dialog();
protected:
void _update_theme();
void _notification(int p_what);
static void _bind_methods();

View file

@ -1758,7 +1758,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#endif
String default_driver = driver_hints.get_slice(",", 0);
String default_driver_macos = driver_hints_angle.get_slice(",", 1);
GLOBAL_DEF_RST_NOVAL("rendering/gl_compatibility/driver", default_driver);
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.windows", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver);
@ -1766,7 +1765,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.web", PROPERTY_HINT_ENUM, driver_hints), default_driver);
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.android", PROPERTY_HINT_ENUM, driver_hints), default_driver);
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.ios", PROPERTY_HINT_ENUM, driver_hints), default_driver);
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver_macos);
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver);
GLOBAL_DEF_RST("rendering/gl_compatibility/nvidia_disable_threaded_optimization", true);
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_angle", true);
@ -3192,31 +3191,30 @@ bool Main::start() {
scn.instantiate();
scn->set_path(info.path);
scn->reload_from_file();
ERR_CONTINUE_MSG(!scn.is_valid(), vformat("Can't autoload: %s.", info.path));
ERR_CONTINUE_MSG(!scn.is_valid(), vformat("Failed to instantiate an autoload, can't load from path: %s.", info.path));
if (scn.is_valid()) {
n = scn->instantiate();
}
} else {
Ref<Resource> res = ResourceLoader::load(info.path);
ERR_CONTINUE_MSG(res.is_null(), vformat("Can't autoload: %s.", info.path));
ERR_CONTINUE_MSG(res.is_null(), vformat("Failed to instantiate an autoload, can't load from path: %s.", info.path));
Ref<Script> script_res = res;
if (script_res.is_valid()) {
StringName ibt = script_res->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
ERR_CONTINUE_MSG(!valid_type, vformat("Script does not inherit from Node: %s.", info.path));
ERR_CONTINUE_MSG(!valid_type, vformat("Failed to instantiate an autoload, script '%s' does not inherit from 'Node'.", info.path));
Object *obj = ClassDB::instantiate(ibt);
ERR_CONTINUE_MSG(!obj, vformat("Cannot instance script for autoload, expected 'Node' inheritance, got: %s."));
ERR_CONTINUE_MSG(!obj, vformat("Failed to instantiate an autoload, cannot instantiate '%s'.", ibt));
n = Object::cast_to<Node>(obj);
n->set_script(script_res);
}
}
ERR_CONTINUE_MSG(!n, vformat("Path in autoload not a node or script: %s.", info.path));
ERR_CONTINUE_MSG(!n, vformat("Failed to instantiate an autoload, path is not pointing to a scene or a script: %s.", info.path));
n->set_name(info.name);
//defer so references are all valid on _ready()

View file

@ -907,9 +907,16 @@ def generate_vs_project(env, original_args, project_name="godot"):
defines=mono_defines,
)
env["MSVSBUILDCOM"] = module_configs.build_commandline("scons")
env["MSVSREBUILDCOM"] = module_configs.build_commandline("scons vsproj=yes")
env["MSVSCLEANCOM"] = module_configs.build_commandline("scons --clean")
scons_cmd = "scons"
path_to_venv = os.getenv("VIRTUAL_ENV")
path_to_scons_exe = Path(str(path_to_venv)) / "Scripts" / "scons.exe"
if path_to_venv and path_to_scons_exe.exists():
scons_cmd = str(path_to_scons_exe)
env["MSVSBUILDCOM"] = module_configs.build_commandline(scons_cmd)
env["MSVSREBUILDCOM"] = module_configs.build_commandline(f"{scons_cmd} vsproj=yes")
env["MSVSCLEANCOM"] = module_configs.build_commandline(f"{scons_cmd} --clean")
if not env.get("MSVS"):
env["MSVS"]["PROJECTSUFFIX"] = ".vcxproj"
env["MSVS"]["SOLUTIONSUFFIX"] = ".sln"

View file

@ -2226,7 +2226,7 @@ void CSGPolygon3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path3D"), "set_path_node", "get_path_node");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_interval_type", PROPERTY_HINT_ENUM, "Distance,Subdivide"), "set_path_interval_type", "get_path_interval_type");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_interval", PROPERTY_HINT_RANGE, "0.01,1.0,0.01,exp,or_greater"), "set_path_interval", "get_path_interval");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_simplify_angle", PROPERTY_HINT_RANGE, "0.0,180.0,0.1,exp"), "set_path_simplify_angle", "get_path_simplify_angle");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_simplify_angle", PROPERTY_HINT_RANGE, "0.0,180.0,0.1"), "set_path_simplify_angle", "get_path_simplify_angle");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_rotation", PROPERTY_HINT_ENUM, "Polygon,Path,PathFollow"), "set_path_rotation", "get_path_rotation");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_local"), "set_path_local", "is_path_local");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_continuous_u"), "set_path_continuous_u", "is_path_continuous_u");

View file

@ -2329,6 +2329,19 @@ void GDScriptLanguage::reload_all_scripts() {
}
elem = elem->next();
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
// Reload all pointers to existing singletons so that tool scripts can work with the reloaded extensions.
List<Engine::Singleton> singletons;
Engine::get_singleton()->get_singletons(&singletons);
for (const Engine::Singleton &E : singletons) {
if (globals.has(E.name)) {
_add_global(E.name, E.ptr);
}
}
}
#endif
}
//as scripts are going to be reloaded, must proceed without locking here

View file

@ -1083,6 +1083,12 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
List<PropertyInfo> members;
scr->get_script_property_list(&members);
for (const PropertyInfo &E : members) {
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP)) {
continue;
}
if (E.name.contains("/")) {
continue;
}
int location = p_recursion_depth + _get_property_location(scr->get_class_name(), E.name);
ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, location);
r_result.insert(option.display, option);
@ -1152,7 +1158,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
List<PropertyInfo> pinfo;
ClassDB::get_property_list(type, &pinfo);
for (const PropertyInfo &E : pinfo) {
if (E.usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) {
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP)) {
continue;
}
if (E.name.contains("/")) {
@ -1213,6 +1219,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
}
for (const PropertyInfo &E : members) {
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP)) {
continue;
}
if (!String(E.name).contains("/")) {
ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER);
if (GDScriptParser::theme_color_names.has(E.name)) {
@ -2667,6 +2676,11 @@ static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, co
if (p_context.base == nullptr) {
return false;
}
if (p_subscript->base->datatype.type_source == GDScriptParser::DataType::ANNOTATED_EXPLICIT) {
// Annotated type takes precedence.
return false;
}
const GDScriptParser::GetNodeNode *get_node = nullptr;
switch (p_subscript->base->type) {
@ -2715,10 +2729,19 @@ static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, co
if (r_base != nullptr) {
*r_base = node;
}
r_base_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
r_base_type.kind = GDScriptParser::DataType::NATIVE;
r_base_type.type_source = GDScriptParser::DataType::INFERRED;
r_base_type.builtin_type = Variant::OBJECT;
r_base_type.native_type = node->get_class_name();
Ref<Script> scr = node->get_script();
if (scr.is_null()) {
r_base_type.kind = GDScriptParser::DataType::NATIVE;
} else {
r_base_type.kind = GDScriptParser::DataType::SCRIPT;
r_base_type.script_type = scr;
}
return true;
}
}

View file

@ -78,31 +78,30 @@ void init_autoloads() {
scn.instantiate();
scn->set_path(info.path);
scn->reload_from_file();
ERR_CONTINUE_MSG(!scn.is_valid(), vformat("Can't autoload: %s.", info.path));
ERR_CONTINUE_MSG(!scn.is_valid(), vformat("Failed to instantiate an autoload, can't load from path: %s.", info.path));
if (scn.is_valid()) {
n = scn->instantiate();
}
} else {
Ref<Resource> res = ResourceLoader::load(info.path);
ERR_CONTINUE_MSG(res.is_null(), vformat("Can't autoload: %s.", info.path));
ERR_CONTINUE_MSG(res.is_null(), vformat("Failed to instantiate an autoload, can't load from path: %s.", info.path));
Ref<Script> scr = res;
if (scr.is_valid()) {
StringName ibt = scr->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
ERR_CONTINUE_MSG(!valid_type, vformat("Script does not inherit from Node: %s.", info.path));
ERR_CONTINUE_MSG(!valid_type, vformat("Failed to instantiate an autoload, script '%s' does not inherit from 'Node'.", info.path));
Object *obj = ClassDB::instantiate(ibt);
ERR_CONTINUE_MSG(!obj, vformat("Cannot instance script for Autoload, expected 'Node' inheritance, got: %s.", ibt));
ERR_CONTINUE_MSG(!obj, vformat("Failed to instantiate an autoload, cannot instantiate '%s'.", ibt));
n = Object::cast_to<Node>(obj);
n->set_script(scr);
}
}
ERR_CONTINUE_MSG(!n, vformat("Path in autoload not a node or script: %s.", info.path));
ERR_CONTINUE_MSG(!n, vformat("Failed to instantiate an autoload, path is not pointing to a scene or a script: %s.", info.path));
n->set_name(info.name);
for (int i = 0; i < ScriptServer::get_language_count(); i++) {

View file

@ -1107,8 +1107,14 @@ void NavMap::_update_rvo_obstacles_tree_2d() {
obstacle_vertex_count += obstacle->get_vertices().size();
}
// Cleaning old obstacles.
for (size_t i = 0; i < rvo_simulation_2d.obstacles_.size(); ++i) {
delete rvo_simulation_2d.obstacles_[i];
}
rvo_simulation_2d.obstacles_.clear();
// Cannot use LocalVector here as RVO library expects std::vector to build KdTree
std::vector<RVO2D::Obstacle2D *> raw_obstacles;
std::vector<RVO2D::Obstacle2D *> &raw_obstacles = rvo_simulation_2d.obstacles_;
raw_obstacles.reserve(obstacle_vertex_count);
// The following block is modified copy from RVO2D::AddObstacle()
@ -1128,6 +1134,11 @@ void NavMap::_update_rvo_obstacles_tree_2d() {
real_t _obstacle_height = obstacle->get_height();
for (const Vector3 &_obstacle_vertex : _obstacle_vertices) {
#ifdef TOOLS_ENABLED
if (_obstacle_vertex.y != 0) {
WARN_PRINT_ONCE("Y coordinates of static obstacle vertices are ignored. Please use obstacle position Y to change elevation of obstacle.");
}
#endif
rvo_2d_vertices.push_back(RVO2D::Vector2(_obstacle_vertex.x + _obstacle_position.x, _obstacle_vertex.z + _obstacle_position.z));
}

View file

@ -177,7 +177,6 @@ void OpenXRActionMap::create_default_action_sets() {
Ref<OpenXRAction> trigger_touch = action_set->add_new_action("trigger_touch", "Trigger touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> grip = action_set->add_new_action("grip", "Grip", OpenXRAction::OPENXR_ACTION_FLOAT, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> grip_click = action_set->add_new_action("grip_click", "Grip click", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> grip_touch = action_set->add_new_action("grip_touch", "Grip touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> grip_force = action_set->add_new_action("grip_force", "Grip force", OpenXRAction::OPENXR_ACTION_FLOAT, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> primary = action_set->add_new_action("primary", "Primary joystick/thumbstick/trackpad", OpenXRAction::OPENXR_ACTION_VECTOR2, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> primary_click = action_set->add_new_action("primary_click", "Primary joystick/thumbstick/trackpad click", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");

View file

@ -68,6 +68,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitF
if (ret != TINYEXR_SUCCESS) {
if (err) {
ERR_PRINT(String(err));
FreeEXRErrorMessage(err);
}
return ERR_FILE_CORRUPT;
}
@ -86,6 +87,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitF
if (ret != TINYEXR_SUCCESS) {
if (err) {
ERR_PRINT(String(err));
FreeEXRErrorMessage(err);
}
return ERR_FILE_CORRUPT;
}

View file

@ -72,7 +72,24 @@ Error ZIPPacker::start_file(const String &p_path) {
zipfi.internal_fa = 0;
zipfi.external_fa = 0;
int err = zipOpenNewFileInZip(zf, p_path.utf8().get_data(), &zipfi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
int err = zipOpenNewFileInZip4(zf,
p_path.utf8().get_data(),
&zipfi,
nullptr,
0,
nullptr,
0,
nullptr,
Z_DEFLATED,
Z_DEFAULT_COMPRESSION,
0,
-MAX_WBITS,
DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY,
nullptr,
0,
0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions.
1 << 11); // Bit 11 is the language encoding flag. When set, filename and comment fields must be encoded using UTF-8.
return err == ZIP_OK ? OK : FAILED;
}

View file

@ -2074,15 +2074,21 @@ bool EditorExportPlatformIOS::is_package_name_valid(const String &p_package, Str
bool EditorExportPlatformIOS::_check_xcode_install() {
static bool xcode_found = false;
if (!xcode_found) {
String xcode_path;
List<String> args;
args.push_back("-p");
int ec = 0;
Error err = OS::get_singleton()->execute("xcode-select", args, &xcode_path, &ec, true);
if (err != OK || ec != 0) {
return false;
Vector<String> mdfind_paths;
List<String> mdfind_args;
mdfind_args.push_back("kMDItemCFBundleIdentifier=com.apple.dt.Xcode");
String output;
Error err = OS::get_singleton()->execute("mdfind", mdfind_args, &output);
if (err == OK) {
mdfind_paths = output.split("\n");
}
for (const String &found_path : mdfind_paths) {
xcode_found = !found_path.is_empty() && DirAccess::dir_exists_absolute(found_path.strip_edges());
if (xcode_found) {
break;
}
}
xcode_found = DirAccess::dir_exists_absolute(xcode_path.strip_edges());
}
return xcode_found;
}

View file

@ -3875,7 +3875,7 @@ void DisplayServerX11::_xim_preedit_draw_callback(::XIM xim, ::XPointer client_d
ds->im_selection = Point2i();
}
OS_Unix::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
OS_Unix::get_singleton()->get_main_loop()->call_deferred(SNAME("notification"), MainLoop::NOTIFICATION_OS_IME_UPDATE);
}
}

View file

@ -725,7 +725,8 @@ void DisplayServerMacOS::update_mouse_pos(DisplayServerMacOS::WindowData &p_wd,
}
void DisplayServerMacOS::pop_last_key_event() {
if (key_event_pos > 0) {
// Does not pop last key event when it is an IME key event.
if (key_event_pos > 0 && key_event_buffer[key_event_pos - 1].raw) {
key_event_pos--;
}
}

View file

@ -2026,9 +2026,9 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
bool EditorExportPlatformMacOS::has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug) const {
String err;
// Look for export templates (custom templates).
bool dvalid = false;
bool rvalid = false;
// Look for export templates (official templates first, then custom).
bool dvalid = exists_export_template("macos.zip", &err);
bool rvalid = dvalid; // Both in the same ZIP.
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
@ -2043,12 +2043,6 @@ bool EditorExportPlatformMacOS::has_valid_export_configuration(const Ref<EditorE
}
}
// Look for export templates (official templates, check only is custom templates are not set).
if (!dvalid || !rvalid) {
dvalid = exists_export_template("macos.zip", &err);
rvalid = dvalid; // Both in the same ZIP.
}
bool valid = dvalid || rvalid;
r_missing_templates = !valid;

View file

@ -48,7 +48,7 @@ EGLenum GLManagerANGLE_MacOS::_get_platform_extension_enum() const {
Vector<EGLAttrib> GLManagerANGLE_MacOS::_get_platform_display_attributes() const {
Vector<EGLAttrib> ret;
ret.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
ret.push_back(EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE);
ret.push_back(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE);
ret.push_back(EGL_NONE);
return ret;

View file

@ -481,7 +481,7 @@ def configure_msvc(env, vcvars_msvc_config):
env["BUILDERS"]["ProgramOriginal"] = env["BUILDERS"]["Program"]
env["BUILDERS"]["Program"] = methods.precious_program
env.Append(LINKFLAGS=["/NATVIS:platform\windows\godot.natvis"])
env.Append(LINKFLAGS=["/NATVIS:platform\\windows\\godot.natvis"])
env.AppendUnique(LINKFLAGS=["/STACK:" + str(STACK_SIZE)])

View file

@ -2958,9 +2958,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
} break;
case WM_MOUSEACTIVATE: {
if (windows[window_id].no_focus) {
return MA_NOACTIVATEANDEAT; // Do not activate, and discard mouse messages.
} else if (windows[window_id].is_popup) {
if (windows[window_id].no_focus || windows[window_id].is_popup) {
return MA_NOACTIVATE; // Do not activate, but process mouse messages.
}
} break;

View file

@ -294,6 +294,13 @@ NavigationAgent2D::NavigationAgent2D() {
NavigationServer2D::get_singleton()->agent_set_time_horizon_obstacles(agent, time_horizon_obstacles);
NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
NavigationServer2D::get_singleton()->agent_set_max_speed(agent, max_speed);
NavigationServer2D::get_singleton()->agent_set_avoidance_layers(agent, avoidance_layers);
NavigationServer2D::get_singleton()->agent_set_avoidance_mask(agent, avoidance_mask);
NavigationServer2D::get_singleton()->agent_set_avoidance_priority(agent, avoidance_priority);
NavigationServer2D::get_singleton()->agent_set_avoidance_enabled(agent, avoidance_enabled);
if (avoidance_enabled) {
NavigationServer2D::get_singleton()->agent_set_avoidance_callback(agent, callable_mp(this, &NavigationAgent2D::_avoidance_done));
}
// Preallocate query and result objects to improve performance.
navigation_query = Ref<NavigationPathQueryParameters2D>();
@ -302,11 +309,6 @@ NavigationAgent2D::NavigationAgent2D() {
navigation_result = Ref<NavigationPathQueryResult2D>();
navigation_result.instantiate();
set_avoidance_layers(avoidance_layers);
set_avoidance_mask(avoidance_mask);
set_avoidance_priority(avoidance_priority);
set_avoidance_enabled(avoidance_enabled);
#ifdef DEBUG_ENABLED
NavigationServer2D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed));
#endif // DEBUG_ENABLED

View file

@ -36,6 +36,8 @@
#include "servers/navigation_server_3d.h"
void NavigationLink2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationLink2D::get_rid);
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationLink2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationLink2D::is_enabled);
@ -175,6 +177,10 @@ bool NavigationLink2D::_edit_is_selected_on_click(const Point2 &p_point, double
}
#endif // TOOLS_ENABLED
RID NavigationLink2D::get_rid() const {
return link;
}
void NavigationLink2D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;
@ -343,7 +349,13 @@ PackedStringArray NavigationLink2D::get_configuration_warnings() const {
NavigationLink2D::NavigationLink2D() {
link = NavigationServer2D::get_singleton()->link_create();
NavigationServer2D::get_singleton()->link_set_owner_id(link, get_instance_id());
NavigationServer2D::get_singleton()->link_set_enter_cost(link, enter_cost);
NavigationServer2D::get_singleton()->link_set_travel_cost(link, travel_cost);
NavigationServer2D::get_singleton()->link_set_navigation_layers(link, navigation_layers);
NavigationServer2D::get_singleton()->link_set_bidirectional(link, bidirectional);
NavigationServer2D::get_singleton()->link_set_enabled(link, enabled);
set_notify_transform(true);
set_hide_clip_children(true);

View file

@ -61,6 +61,7 @@ public:
virtual Rect2 _edit_get_rect() const override;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
#endif
RID get_rid() const;
void set_enabled(bool p_enabled);
bool is_enabled() const { return enabled; }

View file

@ -148,10 +148,10 @@ void NavigationObstacle2D::_notification(int p_what) {
NavigationObstacle2D::NavigationObstacle2D() {
obstacle = NavigationServer2D::get_singleton()->obstacle_create();
set_radius(radius);
set_vertices(vertices);
set_avoidance_layers(avoidance_layers);
set_avoidance_enabled(avoidance_enabled);
NavigationServer2D::get_singleton()->obstacle_set_radius(obstacle, radius);
NavigationServer2D::get_singleton()->obstacle_set_vertices(obstacle, vertices);
NavigationServer2D::get_singleton()->obstacle_set_avoidance_layers(obstacle, avoidance_layers);
NavigationServer2D::get_singleton()->obstacle_set_avoidance_enabled(obstacle, avoidance_enabled);
}
NavigationObstacle2D::~NavigationObstacle2D() {

View file

@ -35,6 +35,10 @@
#include "scene/resources/world_2d.h"
#include "servers/navigation_server_2d.h"
RID NavigationRegion2D::get_rid() const {
return region;
}
void NavigationRegion2D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;
@ -136,7 +140,7 @@ real_t NavigationRegion2D::get_travel_cost() const {
}
RID NavigationRegion2D::get_region_rid() const {
return region;
return get_rid();
}
#ifdef TOOLS_ENABLED
@ -165,6 +169,7 @@ void NavigationRegion2D::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
set_physics_process_internal(false);
_region_update_transform();
} break;
case NOTIFICATION_DRAW: {
@ -279,6 +284,8 @@ PackedStringArray NavigationRegion2D::get_configuration_warnings() const {
}
void NavigationRegion2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationRegion2D::get_rid);
ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navigation_polygon"), &NavigationRegion2D::set_navigation_polygon);
ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationRegion2D::get_navigation_polygon);
@ -356,6 +363,9 @@ NavigationRegion2D::NavigationRegion2D() {
NavigationServer2D::get_singleton()->region_set_owner_id(region, get_instance_id());
NavigationServer2D::get_singleton()->region_set_enter_cost(region, get_enter_cost());
NavigationServer2D::get_singleton()->region_set_travel_cost(region, get_travel_cost());
NavigationServer2D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
NavigationServer2D::get_singleton()->region_set_use_edge_connections(region, use_edge_connections);
NavigationServer2D::get_singleton()->region_set_enabled(region, enabled);
#ifdef DEBUG_ENABLED
NavigationServer2D::get_singleton()->connect(SNAME("map_changed"), callable_mp(this, &NavigationRegion2D::_navigation_map_changed));

View file

@ -76,6 +76,7 @@ public:
virtual Rect2 _edit_get_rect() const override;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
#endif
RID get_rid() const;
void set_enabled(bool p_enabled);
bool is_enabled() const;

View file

@ -1191,7 +1191,7 @@ void TileMapLayer::_scenes_update() {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
// Check if we should cleanup everything.
bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree();
bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid();
if (forced_cleanup) {
// Clean everything.

View file

@ -327,6 +327,14 @@ NavigationAgent3D::NavigationAgent3D() {
NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
NavigationServer3D::get_singleton()->agent_set_height(agent, height);
NavigationServer3D::get_singleton()->agent_set_max_speed(agent, max_speed);
NavigationServer3D::get_singleton()->agent_set_avoidance_layers(agent, avoidance_layers);
NavigationServer3D::get_singleton()->agent_set_avoidance_mask(agent, avoidance_mask);
NavigationServer3D::get_singleton()->agent_set_avoidance_priority(agent, avoidance_priority);
NavigationServer3D::get_singleton()->agent_set_use_3d_avoidance(agent, use_3d_avoidance);
NavigationServer3D::get_singleton()->agent_set_avoidance_enabled(agent, avoidance_enabled);
if (avoidance_enabled) {
NavigationServer3D::get_singleton()->agent_set_avoidance_callback(agent, callable_mp(this, &NavigationAgent3D::_avoidance_done));
}
// Preallocate query and result objects to improve performance.
navigation_query = Ref<NavigationPathQueryParameters3D>();
@ -335,12 +343,6 @@ NavigationAgent3D::NavigationAgent3D() {
navigation_result = Ref<NavigationPathQueryResult3D>();
navigation_result.instantiate();
set_avoidance_layers(avoidance_layers);
set_avoidance_mask(avoidance_mask);
set_avoidance_priority(avoidance_priority);
set_use_3d_avoidance(use_3d_avoidance);
set_avoidance_enabled(avoidance_enabled);
#ifdef DEBUG_ENABLED
NavigationServer3D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent3D::_navigation_debug_changed));
#endif // DEBUG_ENABLED

View file

@ -147,6 +147,8 @@ void NavigationLink3D::_update_debug_mesh() {
#endif // DEBUG_ENABLED
void NavigationLink3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationLink3D::get_rid);
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationLink3D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationLink3D::is_enabled);
@ -263,7 +265,13 @@ void NavigationLink3D::_notification(int p_what) {
NavigationLink3D::NavigationLink3D() {
link = NavigationServer3D::get_singleton()->link_create();
NavigationServer3D::get_singleton()->link_set_owner_id(link, get_instance_id());
NavigationServer3D::get_singleton()->link_set_enter_cost(link, enter_cost);
NavigationServer3D::get_singleton()->link_set_travel_cost(link, travel_cost);
NavigationServer3D::get_singleton()->link_set_navigation_layers(link, navigation_layers);
NavigationServer3D::get_singleton()->link_set_bidirectional(link, bidirectional);
NavigationServer3D::get_singleton()->link_set_enabled(link, enabled);
set_notify_transform(true);
}
@ -284,6 +292,10 @@ NavigationLink3D::~NavigationLink3D() {
#endif // DEBUG_ENABLED
}
RID NavigationLink3D::get_rid() const {
return link;
}
void NavigationLink3D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;

View file

@ -67,6 +67,8 @@ public:
NavigationLink3D();
~NavigationLink3D();
RID get_rid() const;
void set_enabled(bool p_enabled);
bool is_enabled() const { return enabled; }

View file

@ -167,13 +167,11 @@ NavigationObstacle3D::NavigationObstacle3D() {
obstacle = NavigationServer3D::get_singleton()->obstacle_create();
NavigationServer3D::get_singleton()->obstacle_set_height(obstacle, height);
set_radius(radius);
set_height(height);
set_vertices(vertices);
set_avoidance_layers(avoidance_layers);
set_avoidance_enabled(avoidance_enabled);
set_use_3d_avoidance(use_3d_avoidance);
NavigationServer3D::get_singleton()->obstacle_set_radius(obstacle, radius);
NavigationServer3D::get_singleton()->obstacle_set_vertices(obstacle, vertices);
NavigationServer3D::get_singleton()->obstacle_set_avoidance_layers(obstacle, avoidance_layers);
NavigationServer3D::get_singleton()->obstacle_set_use_3d_avoidance(obstacle, use_3d_avoidance);
NavigationServer3D::get_singleton()->obstacle_set_avoidance_enabled(obstacle, avoidance_enabled);
#ifdef DEBUG_ENABLED
NavigationServer3D::get_singleton()->connect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_fake_agent_radius_debug));

View file

@ -33,6 +33,10 @@
#include "scene/resources/navigation_mesh_source_geometry_data_3d.h"
#include "servers/navigation_server_3d.h"
RID NavigationRegion3D::get_rid() const {
return region;
}
void NavigationRegion3D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;
@ -154,7 +158,7 @@ real_t NavigationRegion3D::get_travel_cost() const {
}
RID NavigationRegion3D::get_region_rid() const {
return region;
return get_rid();
}
void NavigationRegion3D::_notification(int p_what) {
@ -275,6 +279,8 @@ PackedStringArray NavigationRegion3D::get_configuration_warnings() const {
}
void NavigationRegion3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationRegion3D::get_rid);
ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navigation_mesh"), &NavigationRegion3D::set_navigation_mesh);
ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationRegion3D::get_navigation_mesh);
@ -410,6 +416,9 @@ NavigationRegion3D::NavigationRegion3D() {
NavigationServer3D::get_singleton()->region_set_owner_id(region, get_instance_id());
NavigationServer3D::get_singleton()->region_set_enter_cost(region, get_enter_cost());
NavigationServer3D::get_singleton()->region_set_travel_cost(region, get_travel_cost());
NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
NavigationServer3D::get_singleton()->region_set_use_edge_connections(region, use_edge_connections);
NavigationServer3D::get_singleton()->region_set_enabled(region, enabled);
#ifdef DEBUG_ENABLED
NavigationServer3D::get_singleton()->connect(SNAME("map_changed"), callable_mp(this, &NavigationRegion3D::_navigation_map_changed));

View file

@ -73,6 +73,8 @@ protected:
#endif // DISABLE_DEPRECATED
public:
RID get_rid() const;
void set_enabled(bool p_enabled);
bool is_enabled() const;

View file

@ -1985,6 +1985,7 @@ void AnimationMixer::reset() {
}
void AnimationMixer::restore(const Ref<AnimatedValuesBackup> &p_backup) {
ERR_FAIL_COND(p_backup.is_null());
track_cache = p_backup->get_data();
_blend_apply();
track_cache = HashMap<NodePath, AnimationMixer::TrackCache *>();

View file

@ -233,7 +233,7 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
pi.delta = delta;
pi.seeked = p_seeked;
}
pi.is_external_seeking = false;
pi.is_external_seeking = true; // AnimationPlayer doesn't have internal seeking.
pi.looped_flag = looped_flag;
pi.weight = p_blend;
make_animation_instance(cd.from->name, pi);

View file

@ -549,9 +549,12 @@ void PropertyTweener::start() {
return;
}
if (do_continue && Math::is_zero_approx(delay)) {
initial_val = target_instance->get_indexed(property);
do_continue = false;
if (do_continue) {
if (Math::is_zero_approx(delay)) {
initial_val = target_instance->get_indexed(property);
} else {
do_continue_delayed = true;
}
}
if (relative) {
@ -576,10 +579,10 @@ bool PropertyTweener::step(double &r_delta) {
if (elapsed_time < delay) {
r_delta = 0;
return true;
} else if (do_continue && !Math::is_zero_approx(delay)) {
} else if (do_continue_delayed && !Math::is_zero_approx(delay)) {
initial_val = target_instance->get_indexed(property);
delta_val = Animation::subtract_variant(final_val, initial_val);
do_continue = false;
do_continue_delayed = false;
}
double time = MIN(elapsed_time - delay, duration);

View file

@ -225,6 +225,7 @@ private:
double delay = 0;
bool do_continue = true;
bool do_continue_delayed = false;
bool relative = false;
};

View file

@ -1771,7 +1771,7 @@ void RichTextLabel::_scroll_changed(double) {
return;
}
if (scroll_follow && vscroll->get_value() >= (vscroll->get_max() - vscroll->get_page())) {
if (scroll_follow && vscroll->get_value() >= (vscroll->get_max() - Math::round(vscroll->get_page()))) {
scroll_following = true;
} else {
scroll_following = false;
@ -3121,6 +3121,8 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline)
current_char_ofs += t->text.length();
} else if (p_item->type == ITEM_IMAGE) {
current_char_ofs++;
} else if (p_item->type == ITEM_NEWLINE) {
current_char_ofs++;
}
if (p_enter) {

View file

@ -237,6 +237,12 @@ bool VideoStreamPlayer::has_loop() const {
void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) {
stop();
// Make sure to handle stream changes seamlessly, e.g. when done via
// translation remapping.
if (stream.is_valid()) {
stream->disconnect_changed(callable_mp(this, &VideoStreamPlayer::set_stream));
}
AudioServer::get_singleton()->lock();
mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
stream = p_stream;
@ -248,6 +254,10 @@ void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) {
}
AudioServer::get_singleton()->unlock();
if (stream.is_valid()) {
stream->connect_changed(callable_mp(this, &VideoStreamPlayer::set_stream).bind(stream));
}
if (!playback.is_null()) {
playback->set_paused(paused);
texture = playback->get_texture();

View file

@ -284,7 +284,13 @@ void Window::set_title(const String &p_title) {
embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
DisplayServer::get_singleton()->window_set_title(tr_title, window_id);
_update_window_size();
if (keep_title_visible) {
Size2i title_size = DisplayServer::get_singleton()->window_get_title_size(tr_title, window_id);
Size2i size_limit = get_clamped_minimum_size();
if (title_size.x > size_limit.x || title_size.y > size_limit.y) {
_update_window_size();
}
}
}
}
@ -961,6 +967,10 @@ Size2i Window::_clamp_window_size(const Size2i &p_size) {
void Window::_update_window_size() {
Size2i size_limit = get_clamped_minimum_size();
if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID && keep_title_visible) {
Size2i title_size = DisplayServer::get_singleton()->window_get_title_size(tr_title, window_id);
size_limit = size_limit.max(title_size);
}
size = size.max(size_limit);
@ -992,12 +1002,6 @@ void Window::_update_window_size() {
}
DisplayServer::get_singleton()->window_set_max_size(max_size_used, window_id);
if (keep_title_visible) {
Size2i title_size = DisplayServer::get_singleton()->window_get_title_size(tr_title, window_id);
size_limit = size_limit.max(title_size);
}
DisplayServer::get_singleton()->window_set_min_size(size_limit, window_id);
DisplayServer::get_singleton()->window_set_size(size, window_id);
}
@ -1297,7 +1301,13 @@ void Window::_notification(int p_what) {
if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID) {
DisplayServer::get_singleton()->window_set_title(tr_title, window_id);
_update_window_size();
if (keep_title_visible) {
Size2i title_size = DisplayServer::get_singleton()->window_get_title_size(tr_title, window_id);
Size2i size_limit = get_clamped_minimum_size();
if (title_size.x > size_limit.x || title_size.y > size_limit.y) {
_update_window_size();
}
}
}
} break;

View file

@ -286,10 +286,10 @@ void CameraAttributesPractical::_bind_methods() {
ADD_GROUP("DOF Blur", "dof_blur_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_distance", PROPERTY_HINT_RANGE, "0.01,8192,0.01,exp,suffix:m"), "set_dof_blur_far_distance", "get_dof_blur_far_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_RANGE, "-1,8192,0.01,exp"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_RANGE, "-1,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_distance", PROPERTY_HINT_RANGE, "0.01,8192,0.01,exp,suffix:m"), "set_dof_blur_near_distance", "get_dof_blur_near_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_RANGE, "-1,8192,0.01,exp"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_RANGE, "-1,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount");
ADD_GROUP("Auto Exposure", "auto_exposure_");

View file

@ -969,7 +969,7 @@ Vector<Ref<Shape3D>> ImporterMesh::convex_decompose(const Ref<MeshConvexDecompos
if (found_vertex) {
index = found_vertex->value;
} else {
index = ++vertex_count;
index = vertex_count++;
vertex_map[vertex] = index;
vertex_w[index] = vertex;
}

View file

@ -3167,7 +3167,7 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value)
{ "flags_use_shadow_to_opacity", "shadow_to_opacity" },
{ "flags_no_depth_test", "no_depth_test" },
{ "flags_use_point_size", "use_point_size" },
{ "flags_fixed_size", "fixed_Size" },
{ "flags_fixed_size", "fixed_size" },
{ "flags_albedo_tex_force_srgb", "albedo_texture_force_srgb" },
{ "flags_do_not_receive_shadows", "disable_receive_shadows" },
{ "flags_disable_ambient_light", "disable_ambient_light" },

View file

@ -1839,20 +1839,25 @@ Vector<Vector<Ref<Texture2D>>> TileSet::generate_terrains_icons(Size2i p_size) {
// Generate the icons.
for (int terrain_set = 0; terrain_set < get_terrain_sets_count(); terrain_set++) {
for (int terrain = 0; terrain < get_terrains_count(terrain_set); terrain++) {
Ref<Image> image;
image.instantiate();
Ref<Image> dst_image;
dst_image.instantiate();
if (counts[terrain_set][terrain].count > 0) {
// Get the best tile.
Ref<Texture2D> texture = counts[terrain_set][terrain].texture;
Ref<Texture2D> src_texture = counts[terrain_set][terrain].texture;
ERR_FAIL_COND_V(src_texture.is_null(), output);
Ref<Image> src_image = src_texture->get_image();
ERR_FAIL_COND_V(src_image.is_null(), output);
Rect2i region = counts[terrain_set][terrain].region;
image->initialize_data(region.size.x, region.size.y, false, Image::FORMAT_RGBA8);
image->blit_rect(texture->get_image(), region, Point2i());
image->resize(p_size.x, p_size.y, Image::INTERPOLATE_NEAREST);
dst_image->initialize_data(region.size.x, region.size.y, false, src_image->get_format());
dst_image->blit_rect(src_image, region, Point2i());
dst_image->convert(Image::FORMAT_RGBA8);
dst_image->resize(p_size.x, p_size.y, Image::INTERPOLATE_NEAREST);
} else {
image->initialize_data(1, 1, false, Image::FORMAT_RGBA8);
image->set_pixel(0, 0, get_terrain_color(terrain_set, terrain));
dst_image->initialize_data(1, 1, false, Image::FORMAT_RGBA8);
dst_image->set_pixel(0, 0, get_terrain_color(terrain_set, terrain));
}
Ref<ImageTexture> icon = ImageTexture::create_from_image(image);
Ref<ImageTexture> icon = ImageTexture::create_from_image(dst_image);
icon->set_size_override(p_size);
output.write[terrain_set].write[terrain] = icon;
}

View file

@ -172,6 +172,7 @@ Ref<VideoStreamPlayback> VideoStream::instantiate_playback() {
void VideoStream::set_file(const String &p_file) {
file = p_file;
emit_changed();
}
String VideoStream::get_file() {

View file

@ -950,7 +950,7 @@ void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_rende
RD::get_singleton()->draw_command_end_label(); // SSIL
RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER);
RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); // Zeroing importance_map_load_counter depends on us.
int zero[1] = { 0 };
RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
@ -1332,7 +1332,7 @@ void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORe
RD::get_singleton()->draw_command_end_label(); // Interleave
}
RD::get_singleton()->draw_command_end_label(); //SSAO
RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //wait for upcoming transfer
RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); // Zeroing importance_map_load_counter depends on us.
int zero[1] = { 0 };
RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier

Some files were not shown because too many files have changed in this diff Show more