mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
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:
commit
9d22668b9f
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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); }
|
||||
|
@ -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.
|
||||
|
@ -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">
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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" />
|
||||
|
@ -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" />
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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") {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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 |
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() :
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -101,7 +101,6 @@ class ShaderCreateDialog : public ConfirmationDialog {
|
||||
void _update_dialog();
|
||||
|
||||
protected:
|
||||
void _update_theme();
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -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()
|
||||
|
13
methods.py
13
methods.py
@ -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"
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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++) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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--;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)])
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
|
@ -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() {
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -67,6 +67,8 @@ public:
|
||||
NavigationLink3D();
|
||||
~NavigationLink3D();
|
||||
|
||||
RID get_rid() const;
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const { return enabled; }
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -73,6 +73,8 @@ protected:
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
public:
|
||||
RID get_rid() const;
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
|
@ -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 *>();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -225,6 +225,7 @@ private:
|
||||
|
||||
double delay = 0;
|
||||
bool do_continue = true;
|
||||
bool do_continue_delayed = false;
|
||||
bool relative = false;
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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_");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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" },
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user