diff options
-rw-r--r-- | core/object.cpp | 9 | ||||
-rw-r--r-- | doc/classes/NetworkedMultiplayerPeer.xml | 6 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 4 | ||||
-rw-r--r-- | drivers/gles2/shaders/scene.glsl | 199 | ||||
-rw-r--r-- | drivers/gles2/shaders/stdlib.glsl | 11 | ||||
-rw-r--r-- | drivers/unix/os_unix.cpp | 2 | ||||
-rw-r--r-- | editor/editor_inspector.cpp | 5 | ||||
-rw-r--r-- | editor/editor_properties.cpp | 2 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp | 266 | ||||
-rw-r--r-- | editor/filesystem_dock.h | 2 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 38 | ||||
-rw-r--r-- | main/main.cpp | 6 | ||||
-rw-r--r-- | modules/thekla_unwrap/config.py | 3 | ||||
-rw-r--r-- | modules/visual_script/visual_script_property_selector.cpp | 5 | ||||
-rw-r--r-- | modules/xatlas_unwrap/config.py | 3 | ||||
-rw-r--r-- | platform/android/export/export.cpp | 7 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 10 | ||||
-rw-r--r-- | scene/resources/mesh_data_tool.cpp | 8 |
18 files changed, 410 insertions, 176 deletions
diff --git a/core/object.cpp b/core/object.cpp index 86d9fbde20..345c018e6d 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -2014,11 +2014,13 @@ ObjectID ObjectDB::add_instance(Object *p_object) { ERR_FAIL_COND_V(p_object->get_instance_id() != 0, 0); rw_lock->write_lock(); - instances[++instance_counter] = p_object; - instance_checks[p_object] = instance_counter; + ObjectID instance_id = ++instance_counter; + instances[instance_id] = p_object; + instance_checks[p_object] = instance_id; + rw_lock->write_unlock(); - return instance_counter; + return instance_id; } void ObjectDB::remove_instance(Object *p_object) { @@ -2095,6 +2097,5 @@ void ObjectDB::cleanup() { instances.clear(); instance_checks.clear(); rw_lock->write_unlock(); - memdelete(rw_lock); } diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml index e878b3a746..ea6fe6d11c 100644 --- a/doc/classes/NetworkedMultiplayerPeer.xml +++ b/doc/classes/NetworkedMultiplayerPeer.xml @@ -92,13 +92,13 @@ </signals> <constants> <constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode"> - Packets are sent via unordered UDP packets. + Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [code]TRANSFER_MODE_UNRELIABLE_ORDERED[/code]. Use for non-critical data, and always consider whether the order matters. </constant> <constant name="TRANSFER_MODE_UNRELIABLE_ORDERED" value="1" enum="TransferMode"> - Packets are sent via ordered UDP packets. + Packets are not acknowledged, no resend attempts are made for lost packets. Packets are received in the order they were sent in. Potentially faster than [code]TRANSFER_MODE_RELIABLE[/code]. Use for non-critical data or data that would be outdated if received late due to resend attempt(s) anyway, for example movement and positional data. </constant> <constant name="TRANSFER_MODE_RELIABLE" value="2" enum="TransferMode"> - Packets are sent via TCP packets. + Packets must be received and resend attempts should be made until the packets are acknowledged. Packets must be received in the order they were sent in. Most reliable transfer mode, but potentially slowest due to the overhead. Use for critical data that must be transmitted and arrive in order, for example an ability being triggered or a chat message. Consider carefully if the information really is critical, and use sparingly. </constant> <constant name="CONNECTION_DISCONNECTED" value="0" enum="ConnectionStatus"> The ongoing connection disconnected. diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 043a5047ca..6314a69a90 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -54,6 +54,8 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; #define _EXT_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define _DEPTH_COMPONENT24_OES 0x81A6 + void RasterizerStorageGLES2::bind_quad_array() const { glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); @@ -3915,7 +3917,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glGenRenderbuffers(1, &rt->depth); glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, rt->width, rt->height); + glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, rt->width, rt->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index cc3bae060f..2b0b095ac9 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -15,6 +15,7 @@ precision highp int; #define M_PI 3.14159265359 + // // attributes // @@ -1214,14 +1215,17 @@ LIGHT_SHADER_CODE #ifdef USE_SHADOW #define SAMPLE_SHADOW_TEXEL(p_shadow, p_pos, p_depth) step(p_depth, texture2D(p_shadow, p_pos).r) +#define SAMPLE_SHADOW_TEXEL_PROJ(p_shadow, p_pos) step(p_pos.z, texture2DProj(p_shadow, p_pos).r) float sample_shadow( - highp sampler2D shadow, - highp vec2 pos, - highp float depth) { + highp sampler2D shadow,highp vec4 spos) { #ifdef SHADOW_MODE_PCF_13 + spos.xyz/=spos.w; + vec2 pos = spos.xy; + float depth = spos.z; + float avg = SAMPLE_SHADOW_TEXEL(shadow, pos, depth); avg += SAMPLE_SHADOW_TEXEL(shadow, pos + vec2(shadow_pixel_size.x, 0.0), depth); avg += SAMPLE_SHADOW_TEXEL(shadow, pos + vec2(-shadow_pixel_size.x, 0.0), depth); @@ -1240,6 +1244,10 @@ float sample_shadow( #ifdef SHADOW_MODE_PCF_5 + spos.xyz/=spos.w; + vec2 pos = spos.xy; + float depth = spos.z; + float avg = SAMPLE_SHADOW_TEXEL(shadow, pos, depth); avg += SAMPLE_SHADOW_TEXEL(shadow, pos + vec2(shadow_pixel_size.x, 0.0), depth); avg += SAMPLE_SHADOW_TEXEL(shadow, pos + vec2(-shadow_pixel_size.x, 0.0), depth); @@ -1251,7 +1259,7 @@ float sample_shadow( #if !defined(SHADOW_MODE_PCF_5) || !defined(SHADOW_MODE_PCF_13) - return SAMPLE_SHADOW_TEXEL(shadow, pos, depth); + return SAMPLE_SHADOW_TEXEL_PROJ(shadow, spos); #endif } @@ -1321,8 +1329,8 @@ FRAGMENT_SHADER_CODE normalmap.xy = normalmap.xy * 2.0 - 1.0; normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); - // normal = normalize(mix(normal_interp, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth)) * side; - normal = normalmap; + normal = normalize(mix(normal_interp, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth)) * side; + //normal = normalmap; #endif normal = normalize(normal); @@ -1493,10 +1501,10 @@ FRAGMENT_SHADER_CODE #ifdef USE_SHADOW { - highp vec3 splane = shadow_coord.xyz; - float shadow_len = length(splane); + highp vec4 splane = shadow_coord; + float shadow_len = length(splane.xyz); - splane = normalize(splane); + splane = normalize(splane.xyz); vec4 clamp_rect = light_clamp; @@ -1513,8 +1521,9 @@ FRAGMENT_SHADER_CODE splane.z = shadow_len / light_range; splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + splane.w = 1.0; - float shadow = sample_shadow(light_shadow_atlas, splane.xy, splane.z); + float shadow = sample_shadow(light_shadow_atlas, splane); light_att *= shadow; } @@ -1531,6 +1540,126 @@ FRAGMENT_SHADER_CODE float depth_z = -vertex.z; #ifdef USE_SHADOW + + +#ifdef USE_VERTEX_LIGHTING +//compute shadows in a mobile friendly way + +#ifdef LIGHT_USE_PSSM4 + //take advantage of prefetch + float shadow1 = sample_shadow(light_directional_shadow, shadow_coord); + float shadow2 = sample_shadow(light_directional_shadow, shadow_coord2); + float shadow3 = sample_shadow(light_directional_shadow, shadow_coord3); + float shadow4 = sample_shadow(light_directional_shadow, shadow_coord4); + + + if (depth_z < light_split_offsets.w) { + float pssm_fade = 0.0; + float shadow_att = 1.0; +#ifdef LIGHT_USE_PSSM_BLEND + float shadow_att2 = 1.0; + float pssm_blend = 0.0; + bool use_blend = true; +#endif + if (depth_z < light_split_offsets.y) { + if (depth_z < light_split_offsets.x) { + shadow_att = shadow1; + +#ifdef LIGHT_USE_PSSM_BLEND + shadow_att2 = shadow2; + + pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z); +#endif + } else { + shadow_att = shadow2; + +#ifdef LIGHT_USE_PSSM_BLEND + shadow_att2 = shadow3; + + pssm_blend = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z); +#endif + } + } else { + if (depth_z < light_split_offsets.z) { + + shadow_att = shadow3; + +#if defined(LIGHT_USE_PSSM_BLEND) + shadow_att2 = shadow4; + pssm_blend = smoothstep(light_split_offsets.y, light_split_offsets.z, depth_z); +#endif + + } else { + + shadow_att = shadow4; + pssm_fade = smoothstep(light_split_offsets.z, light_split_offsets.w, depth_z); + +#if defined(LIGHT_USE_PSSM_BLEND) + use_blend = false; +#endif + } + } +#if defined(LIGHT_USE_PSSM_BLEND) + if (use_blend) { + shadow_att = mix(shadow_att, shadow_att2, pssm_blend); + } +#endif + light_att *= shadow_att; + + } + +#endif //LIGHT_USE_PSSM4 + +#ifdef LIGHT_USE_PSSM2 + + //take advantage of prefetch + float shadow1 = sample_shadow(light_directional_shadow, shadow_coord); + float shadow2 = sample_shadow(light_directional_shadow, shadow_coord2); + + + + if (depth_z < light_split_offsets.y) { + float shadow_att = 1.0; + float pssm_fade = 0.0; + +#ifdef LIGHT_USE_PSSM_BLEND + float shadow_att2 = 1.0; + float pssm_blend = 0.0; + bool use_blend = true; +#endif + if (depth_z < light_split_offsets.x) { + float pssm_fade = 0.0; + shadow_att = shadow1; + +#ifdef LIGHT_USE_PSSM_BLEND + shadow_att2 = shadow2; + pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z); +#endif + } else { + + shadow_att = shadow2; + pssm_fade = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z); +#ifdef LIGHT_USE_PSSM_BLEND + use_blend = false; +#endif + } +#ifdef LIGHT_USE_PSSM_BLEND + if (use_blend) { + shadow_att = mix(shadow_att, shadow_att2, pssm_blend); + } +#endif + light_att *= shadow_att; + } + +#endif //LIGHT_USE_PSSM2 + +#if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM2) + + light_att *= sample_shadow(light_directional_shadow, shadow_coord); +#endif //orthogonal + +#else //fragment version of pssm + { #ifdef LIGHT_USE_PSSM4 if (depth_z < light_split_offsets.w) { @@ -1540,34 +1669,32 @@ FRAGMENT_SHADER_CODE if (depth_z < light_split_offsets.x) { #endif //pssm2 - vec3 pssm_coord; + highp vec4 pssm_coord; float pssm_fade = 0.0; #ifdef LIGHT_USE_PSSM_BLEND float pssm_blend; - vec3 pssm_coord2; + highp vec4 pssm_coord2; bool use_blend = true; #endif #ifdef LIGHT_USE_PSSM4 + + if (depth_z < light_split_offsets.y) { - if (depth_z < light_split_offsets.x) { - highp vec4 splane = shadow_coord; - pssm_coord = splane.xyz / splane.w; + if (depth_z < light_split_offsets.x) { + pssm_coord = shadow_coord; -#ifdef LIGHT_USE_PSSM_BLEND - splane = shadow_coord2; - pssm_coord2 = splane.xyz / splane.w; +#ifdef LIGHT_USE_PSSM_BLEND + pssm_coord2 = shadow_coord2; pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z); #endif } else { - highp vec4 splane = shadow_coord2; - pssm_coord = splane.xyz / splane.w; + pssm_coord = shadow_coord2; #ifdef LIGHT_USE_PSSM_BLEND - splane = shadow_coord3; - pssm_coord2 = splane.xyz / splane.w; + pssm_coord2 = shadow_coord3; pssm_blend = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z); #endif @@ -1575,19 +1702,16 @@ FRAGMENT_SHADER_CODE } else { if (depth_z < light_split_offsets.z) { - highp vec4 splane = shadow_coord3; - pssm_coord = splane.xyz / splane.w; + pssm_coord = shadow_coord3; #if defined(LIGHT_USE_PSSM_BLEND) - splane = shadow_coord4; - pssm_coord2 = splane.xyz / splane.w; + pssm_coord2 = shadow_coord4; pssm_blend = smoothstep(light_split_offsets.y, light_split_offsets.z, depth_z); #endif } else { - highp vec4 splane = shadow_coord4; - pssm_coord = splane.xyz / splane.w; + pssm_coord = shadow_coord4; pssm_fade = smoothstep(light_split_offsets.z, light_split_offsets.w, depth_z); #if defined(LIGHT_USE_PSSM_BLEND) @@ -1601,17 +1725,15 @@ FRAGMENT_SHADER_CODE #ifdef LIGHT_USE_PSSM2 if (depth_z < light_split_offsets.x) { - highp vec4 splane = shadow_coord; - pssm_coord = splane.xyz / splane.w; + pssm_coord = shadow_coord; #ifdef LIGHT_USE_PSSM_BLEND - splane = shadow_coord2; - pssm_coord2 = splane.xyz / splane.w; + pssm_coord2 = shadow_coord2; pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z); #endif } else { - highp vec4 splane = shadow_coord2; - pssm_coord = splane.xyz / splane.w; + + pssm_coord = shadow_coord2; pssm_fade = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z); #ifdef LIGHT_USE_PSSM_BLEND use_blend = false; @@ -1622,22 +1744,23 @@ FRAGMENT_SHADER_CODE #if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM2) { - highp vec4 splane = shadow_coord; - pssm_coord = splane.xyz / splane.w; + pssm_coord = shadow_coord; } #endif - float shadow = sample_shadow(light_directional_shadow, pssm_coord.xy, pssm_coord.z); + float shadow = sample_shadow(light_directional_shadow, pssm_coord); #ifdef LIGHT_USE_PSSM_BLEND if (use_blend) { - shadow = mix(shadow, sample_shadow(light_directional_shadow, pssm_coord2.xy, pssm_coord2.z), pssm_blend); + shadow = mix(shadow, sample_shadow(light_directional_shadow, pssm_coord2), pssm_blend); } #endif light_att *= shadow; } } +#endif //use vertex lighting + #endif //use shadow #endif diff --git a/drivers/gles2/shaders/stdlib.glsl b/drivers/gles2/shaders/stdlib.glsl index 6bc81a22d8..8662dcfe53 100644 --- a/drivers/gles2/shaders/stdlib.glsl +++ b/drivers/gles2/shaders/stdlib.glsl @@ -35,3 +35,14 @@ highp vec4 texel2DFetch(highp sampler2D tex, ivec2 size, ivec2 coord) { return texture2DLod(tex, vec2(x_coord, y_coord), 0.0); } + +#ifndef USE_GLES_OVER_GL +highp mat4 transpose(highp mat4 src) { + return mat4( + vec4( src[0].x, src[1].x, src[2].x, src[3].x ), + vec4( src[0].y, src[1].y, src[2].y, src[3].y ), + vec4( src[0].z, src[1].z, src[2].z, src[3].z ), + vec4( src[0].w, src[1].w, src[2].w, src[3].w ) + ); +} +#endif diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 7d3e6b412c..6c70934bc6 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -74,7 +74,7 @@ static void _setup_clock() { kern_return_t ret = mach_timebase_info(&info); ERR_EXPLAIN("OS CLOCK IS NOT WORKING!"); ERR_FAIL_COND(ret != 0); - _clock_scale = (double)info.numer / (double)info.denom; + _clock_scale = ((double)info.numer / (double)info.denom) / 1000.0; _clock_start = mach_absolute_time() * _clock_scale; } #else diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 10fc15e468..2c4168f1a0 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -36,9 +36,6 @@ #include "multi_node_edit.h" #include "scene/resources/packed_scene.h" -// TODO: -// arrays and dictionary - Size2 EditorProperty::get_minimum_size() const { Size2 ms; @@ -1984,7 +1981,7 @@ void EditorInspector::_property_keyed(const String &p_path) { if (!object) return; - emit_signal("property_keyed", p_path, object->get(p_path), false); //second param is deprecated + emit_signal("property_keyed", p_path, object->get(p_path), true); //second param is deprecated } void EditorInspector::_property_keyed_with_value(const String &p_path, const Variant &p_value) { diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index f6937386c9..690fbd2c93 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1761,7 +1761,7 @@ void EditorPropertyColor::_color_changed(const Color &p_color) { void EditorPropertyColor::_popup_closed() { - emit_signal("property_changed", get_edited_property(), picker->get_pick_color(), false); + emit_signal("property_changed", get_edited_property(), picker->get_pick_color(), true); } void EditorPropertyColor::_bind_methods() { diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 42fd38b654..2c69909f23 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -73,14 +73,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory if ((path.begins_with(lpath) && path != lpath)) { subdirectory_item->set_collapsed(false); } else { - bool is_collapsed = true; - for (int i = 0; i < uncollapsed_paths.size(); i++) { - if (lpath == uncollapsed_paths[i]) { - is_collapsed = false; - break; - } - } - subdirectory_item->set_collapsed(is_collapsed); + subdirectory_item->set_collapsed(uncollapsed_paths.find(lpath) < 0); } if (searched_string.length() > 0 && dname.to_lower().find(searched_string) >= 0) { parent_should_expand = true; @@ -137,6 +130,11 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { Vector<String> uncollapsed_paths; TreeItem *root = tree->get_root(); if (root) { + TreeItem *favorites_item = root->get_children(); + if (!favorites_item->is_collapsed()) { + uncollapsed_paths.push_back(favorites_item->get_metadata(0)); + } + TreeItem *resTree = root->get_children()->get_next(); if (resTree) { Vector<TreeItem *> needs_check; @@ -170,15 +168,14 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool TreeItem *favorites = tree->create_item(root); favorites->set_icon(0, get_icon("Favorites", "EditorIcons")); favorites->set_text(0, TTR("Favorites:")); - favorites->set_selectable(0, false); + favorites->set_metadata(0, "Favorites"); + favorites->set_collapsed(p_uncollapsed_paths.find("Favorites") < 0); Vector<String> favorite_paths = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < favorite_paths.size(); i++) { String fave = favorite_paths[i]; if (!fave.begins_with("res://")) continue; - if (display_mode_setting == DISPLAY_MODE_SETTING_SPLIT && !fave.ends_with("/")) - continue; Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons"); @@ -208,6 +205,12 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool ti->set_tooltip(0, fave); ti->set_selectable(0, true); ti->set_metadata(0, fave); + if (!fave.ends_with("/")) { + Array udata; + udata.push_back(tree_update_id); + udata.push_back(ti); + EditorResourcePreview::get_singleton()->queue_resource_preview(fave, this, "_tree_thumbnail_done", udata); + } } } @@ -404,13 +407,21 @@ void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_s return; // Tree item selected - TreeItem *sel = tree->get_selected(); - if (!sel) + TreeItem *selected = tree->get_selected(); + if (!selected) return; - path = sel->get_metadata(0); + + TreeItem *favorites_item = tree->get_root()->get_children(); + if (selected->get_parent() == favorites_item) { + // Go to the favorites if we click in the favorites and the path has changed + path = "Favorites"; + } else { + path = selected->get_metadata(0); + // Note: the "Favorites" item also leads to this path + } // Set the current path - current_path->set_text(path); + _set_current_path_text(path); _push_to_history(); // Update the file list @@ -431,31 +442,46 @@ String FileSystemDock::get_current_path() const { return path; } +void FileSystemDock::_set_current_path_text(const String &p_path) { + if (p_path == "Favorites") { + current_path->set_text(TTR("Favorites")); + } else { + current_path->set_text(path); + } +} + void FileSystemDock::navigate_to_path(const String &p_path) { - String target_path = p_path; - // If the path is a file, do not only go to the directory in the tree, also select the file in the file list. - if (target_path.ends_with("/")) { - target_path = target_path.substr(0, target_path.length() - 1); - } - DirAccess *dirAccess = DirAccess::open("res://"); - if (dirAccess->file_exists(p_path)) { - path = target_path; - } else if (dirAccess->dir_exists(p_path)) { - path = target_path + "/"; + if (p_path == "Favorites") { + path = p_path; } else { - ERR_EXPLAIN(vformat(TTR("Cannot navigate to '%s' as it has not been found in the file system!"), p_path)); - ERR_FAIL(); + String target_path = p_path; + // If the path is a file, do not only go to the directory in the tree, also select the file in the file list. + if (target_path.ends_with("/")) { + target_path = target_path.substr(0, target_path.length() - 1); + } + DirAccess *dirAccess = DirAccess::open("res://"); + if (dirAccess->file_exists(p_path)) { + path = target_path; + } else if (dirAccess->dir_exists(p_path)) { + path = target_path + "/"; + } else { + ERR_EXPLAIN(vformat(TTR("Cannot navigate to '%s' as it has not been found in the file system!"), p_path)); + ERR_FAIL(); + } } - current_path->set_text(path); + _set_current_path_text(path); _push_to_history(); if (display_mode == DISPLAY_MODE_SPLIT) { + if (path.ends_with("/") || path == "Favorites") { + _go_to_file_list(); + } _update_tree(_compute_uncollapsed_paths()); _update_file_list(false); } else if (display_mode == DISPLAY_MODE_TREE_ONLY) { - if (path.ends_with("/")) { + if (path.ends_with("/") || path == "Favorites") { _go_to_file_list(); } else { _update_tree(_compute_uncollapsed_paths()); @@ -500,15 +526,6 @@ void FileSystemDock::_tree_thumbnail_done(const String &p_path, const Ref<Textur TreeItem *file_item = Object::cast_to<TreeItem>(uarr[1]); if (file_item) { file_item->set_icon(0, p_small_preview); - - // Update the favorite icon if needed - TreeItem *favorite = tree->get_root()->get_children()->get_children(); - while (favorite) { - if (favorite->get_metadata(0) == file_item->get_metadata(0)) { - favorite->set_icon(0, p_small_preview); - } - favorite = favorite->get_next(); - } } } } @@ -577,21 +594,10 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->clear(); - current_path->set_text(path); + _set_current_path_text(path); String directory = path; - if (directory.ends_with("/") && directory != "res://") { - directory = directory.substr(0, directory.length() - 1); - } String file = ""; - EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->get_filesystem_path(directory); - if (!efd) { - directory = path.get_base_dir(); - file = path.get_file(); - efd = EditorFileSystem::get_singleton()->get_filesystem_path(directory); - } - if (!efd) - return; String ei = "EditorIcons"; int thumbnail_size = EditorSettings::get_singleton()->get("docks/filesystem/thumbnail_size"); @@ -601,7 +607,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { Ref<Texture> file_thumbnail_broken; bool use_thumbnails = (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS); - bool use_folders = searched_string.length() == 0 && ((display_mode == DISPLAY_MODE_FILE_LIST_ONLY || display_mode == DISPLAY_MODE_TREE_ONLY) || always_show_folders); if (use_thumbnails) { // Thumbnails mode @@ -630,56 +635,116 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->set_fixed_icon_size(Size2()); } - if (use_folders) { - // Display folders in the list - Ref<Texture> folderIcon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog"); + Ref<Texture> folder_icon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog"); - if (directory != "res://") { - files->add_item("..", folderIcon, true); + // Build the FileInfo list + List<FileInfo> filelist; + if (path == "Favorites") { + // Display the favorites + Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + for (int i = 0; i < favorites.size(); i++) { + String favorite = favorites[i]; + String text; + Ref<Texture> icon; + if (favorite == "res://") { + text = "/"; + icon = folder_icon; + if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { + files->add_item(text, icon, true); + files->set_item_metadata(files->get_item_count() - 1, favorite); + } + } else if (favorite.ends_with("/")) { + text = favorite.substr(0, favorite.length() - 1).get_file(); + icon = folder_icon; + if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { + files->add_item(text, icon, true); + files->set_item_metadata(files->get_item_count() - 1, favorite); + } + } else { + int index; + EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->find_file(favorite, &index); + + FileInfo fi; + fi.name = favorite.get_file(); + fi.path = favorite; + if (efd) { + fi.type = efd->get_file_type(index); + fi.import_broken = !efd->get_file_import_is_valid(index); + } else { + fi.type = ""; + fi.import_broken = true; + } + fi.import_status = 0; - String bd = directory.get_base_dir(); - if (bd != "res://" && !bd.ends_with("/")) - bd += "/"; + if (searched_string.length() == 0 || fi.name.to_lower().find(searched_string) >= 0) { + filelist.push_back(fi); + } + } + } + } else { - files->set_item_metadata(files->get_item_count() - 1, bd); - files->set_item_selectable(files->get_item_count() - 1, false); + // Get infos on the directory + file + if (directory.ends_with("/") && directory != "res://") { + directory = directory.substr(0, directory.length() - 1); + } + EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->get_filesystem_path(directory); + if (!efd) { + directory = path.get_base_dir(); + file = path.get_file(); + efd = EditorFileSystem::get_singleton()->get_filesystem_path(directory); } + if (!efd) + return; - for (int i = 0; i < efd->get_subdir_count(); i++) { + if (searched_string.length() > 0) { + // Display the search results + _search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128); + } else { - String dname = efd->get_subdir(i)->get_name(); + if ((display_mode == DISPLAY_MODE_FILE_LIST_ONLY || display_mode == DISPLAY_MODE_TREE_ONLY) || always_show_folders) { + // Display folders in the list - files->add_item(dname, folderIcon, true); - files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/"); + if (directory != "res://") { + files->add_item("..", folder_icon, true); - if (cselection.has(dname)) { - files->select(files->get_item_count() - 1, false); - } - } - } + String bd = directory.get_base_dir(); + if (bd != "res://" && !bd.ends_with("/")) + bd += "/"; - List<FileInfo> filelist; - if (searched_string.length() > 0) { - // Display the search results - _search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128); - filelist.sort(); - } else { + files->set_item_metadata(files->get_item_count() - 1, bd); + files->set_item_selectable(files->get_item_count() - 1, false); + } - // Display the folder content - for (int i = 0; i < efd->get_file_count(); i++) { + for (int i = 0; i < efd->get_subdir_count(); i++) { - FileInfo fi; - fi.name = efd->get_file(i); - fi.path = directory.plus_file(fi.name); - fi.type = efd->get_file_type(i); - fi.import_broken = !efd->get_file_import_is_valid(i); - fi.import_status = 0; + String dname = efd->get_subdir(i)->get_name(); + + files->add_item(dname, folder_icon, true); + files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/"); + + if (cselection.has(dname)) { + files->select(files->get_item_count() - 1, false); + } + } + } + + // Display the folder content + for (int i = 0; i < efd->get_file_count(); i++) { - filelist.push_back(fi); + FileInfo fi; + fi.name = efd->get_file(i); + fi.path = directory.plus_file(fi.name); + fi.type = efd->get_file_type(i); + fi.import_broken = !efd->get_file_import_is_valid(i); + fi.import_status = 0; + + filelist.push_back(fi); + } } filelist.sort(); } + // Fills the ItemList control node from the FileInfos String oi = "Object"; for (List<FileInfo>::Element *E = filelist.front(); E; E = E->next()) { FileInfo *finfo = &(E->get()); @@ -750,14 +815,14 @@ void FileSystemDock::_select_file(const String p_path) { if (fpath != "res://") { fpath = fpath.substr(0, fpath.length() - 1); } - navigate_to_path(fpath); - } else { + } else if (fpath != "Favorites") { if (ResourceLoader::get_resource_type(fpath) == "PackedScene") { editor->open_request(fpath); } else { editor->load_resource(fpath); } } + navigate_to_path(fpath); } void FileSystemDock::_tree_activate_file() { @@ -778,8 +843,11 @@ void FileSystemDock::_go_to_file_list() { file_list_view = true; _update_display_mode(); } else { - bool collapsed = tree->get_selected()->is_collapsed(); - tree->get_selected()->set_collapsed(!collapsed); + TreeItem *selected = tree->get_selected(); + if (selected) { + bool collapsed = selected->is_collapsed(); + selected->set_collapsed(!collapsed); + } _update_file_list(false); } } @@ -860,7 +928,7 @@ void FileSystemDock::_bw_history() { void FileSystemDock::_update_history() { path = history[history_pos]; - current_path->set_text(path); + _set_current_path_text(path); if (tree->is_visible()) { _update_tree(_compute_uncollapsed_paths()); @@ -1298,15 +1366,16 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { // Build a list of selected items with the active one at the first position Vector<String> selected_strings; + TreeItem *favorites_item = tree->get_root()->get_children(); TreeItem *active_selected = tree->get_selected(); - if (active_selected) { + if (active_selected && active_selected != favorites_item) { selected_strings.push_back(active_selected->get_metadata(0)); } TreeItem *selected = tree->get_root(); selected = tree->get_next_selected(selected); while (selected) { - if (selected != active_selected) { + if (selected != active_selected && selected != favorites_item) { selected_strings.push_back(selected->get_metadata(0)); } selected = tree->get_next_selected(selected); @@ -1427,6 +1496,8 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) } EditorSettings::get_singleton()->set_favorites(favorites); _update_tree(_compute_uncollapsed_paths()); + if (path == "Favorites") + _update_file_list(true); } break; case FILE_DEPENDENCIES: { @@ -1664,6 +1735,12 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) // Check if the first selected is in favorite TreeItem *selected = tree->get_next_selected(tree->get_root()); while (selected) { + TreeItem *favorites_item = tree->get_root()->get_children(); + if (selected == favorites_item) { + // The "Favorites" item is not draggable + return Variant(); + } + bool is_favorite = selected->get_parent() != NULL && tree->get_root()->get_children() == selected->get_parent(); all_favorites &= is_favorite; all_not_favorites &= !is_favorite; @@ -1819,6 +1896,9 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, EditorSettings::get_singleton()->set_favorites(dirs); _update_tree(_compute_uncollapsed_paths()); + + if (display_mode == DISPLAY_MODE_SPLIT && path == "Favorites") + _update_file_list(true); return; } @@ -2282,7 +2362,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { current_path = memnew(LineEdit); current_path->set_h_size_flags(SIZE_EXPAND_FILL); - current_path->set_text(path); + _set_current_path_text(path); toolbar_hbc->add_child(current_path); button_reload = memnew(Button); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 5208b2c667..d964515572 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -257,6 +257,8 @@ private: void _search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items); + void _set_current_path_text(const String &p_path); + 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; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index ff6832177e..532b3915a7 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -568,15 +568,21 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { return; editor_data->get_undo_redo().create_action("Make node as Root"); - _node_replace_owner(root, node, node, MODE_DO); editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node); + editor_data->get_undo_redo().add_do_method(root->get_parent(), "remove_child", root); + editor_data->get_undo_redo().add_do_method(node, "add_child", root); editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", node); editor_data->get_undo_redo().add_do_method(node, "set_filename", root->get_filename()); + editor_data->get_undo_redo().add_do_method(root, "set_filename", String()); + _node_replace_owner(root, root, node, MODE_DO); + editor_data->get_undo_redo().add_undo_method(root, "set_filename", root->get_filename()); editor_data->get_undo_redo().add_undo_method(node, "set_filename", String()); + editor_data->get_undo_redo().add_undo_method(node, "remove_child", root); editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", root); editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node); - _node_replace_owner(root, node, root, MODE_UNDO); + _node_replace_owner(root, root, root, MODE_UNDO); + editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree"); editor_data->get_undo_redo().add_undo_method(scene_tree, "update_tree"); editor_data->get_undo_redo().add_undo_reference(root); @@ -975,24 +981,22 @@ void SceneTreeDock::_notification(int p_what) { void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode) { - if (p_base != p_node) { - if (p_node->get_owner() == p_base) { - UndoRedo *undo_redo = &editor_data->get_undo_redo(); - switch (p_mode) { - case MODE_BIDI: { - undo_redo->add_do_method(p_node, "set_owner", p_root); - undo_redo->add_undo_method(p_node, "set_owner", p_base); + if (p_node->get_owner() == p_base || !p_node->get_owner()) { + UndoRedo *undo_redo = &editor_data->get_undo_redo(); + switch (p_mode) { + case MODE_BIDI: { + undo_redo->add_do_method(p_node, "set_owner", p_root); + undo_redo->add_undo_method(p_node, "set_owner", p_base); - } break; - case MODE_DO: { - undo_redo->add_do_method(p_node, "set_owner", p_root); + } break; + case MODE_DO: { + undo_redo->add_do_method(p_node, "set_owner", p_root); - } break; - case MODE_UNDO: { - undo_redo->add_undo_method(p_node, "set_owner", p_root); + } break; + case MODE_UNDO: { + undo_redo->add_undo_method(p_node, "set_owner", p_root); - } break; - } + } break; } } diff --git a/main/main.cpp b/main/main.cpp index 5320d73c7f..3eb0b7f354 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -34,6 +34,7 @@ #include "core/io/file_access_network.h" #include "core/io/file_access_pack.h" #include "core/io/file_access_zip.h" +#include "core/io/image_loader.h" #include "core/io/ip.h" #include "core/io/resource_loader.h" #include "core/io/stream_peer_ssl.h" @@ -1124,9 +1125,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) { boot_logo_path = boot_logo_path.strip_edges(); if (boot_logo_path != String()) { - print_line("Boot splash path: " + boot_logo_path); boot_logo.instance(); - Error err = boot_logo->load(boot_logo_path); + Error err = ImageLoader::load_image(boot_logo_path, boot_logo); if (err) ERR_PRINTS("Non-existing or invalid boot splash at: " + boot_logo_path + ". Loading default splash."); } @@ -1707,7 +1707,7 @@ bool Main::start() { if (iconpath != "") { Ref<Image> icon; icon.instance(); - if (icon->load(iconpath) == OK) { + if (ImageLoader::load_image(iconpath, icon) == OK) { OS::get_singleton()->set_icon(icon); hasicon = true; } diff --git a/modules/thekla_unwrap/config.py b/modules/thekla_unwrap/config.py index fad6095064..bd092bdc16 100644 --- a/modules/thekla_unwrap/config.py +++ b/modules/thekla_unwrap/config.py @@ -1,6 +1,5 @@ def can_build(env, platform): - #return (env['tools'] and platform not in ["android", "ios"]) - return False + return (env['tools'] and platform not in ["android", "ios"]) def configure(env): pass diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index e2e5cc77f5..cd29df9855 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -575,6 +575,7 @@ void VisualScriptPropertySelector::select_from_base_type(const String &p_base, c type = Variant::NIL; script = 0; properties = true; + visual_script_generic = false; instance = NULL; virtuals_only = p_virtuals_only; @@ -595,6 +596,7 @@ void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_scrip type = Variant::NIL; script = p_script->get_instance_id(); properties = true; + visual_script_generic = false; instance = NULL; virtuals_only = false; @@ -614,6 +616,7 @@ void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type, type = p_type; script = 0; properties = true; + visual_script_generic = false; instance = NULL; virtuals_only = false; @@ -632,6 +635,7 @@ void VisualScriptPropertySelector::select_from_action(const String &p_type, cons type = Variant::NIL; script = 0; properties = false; + visual_script_generic = false; instance = NULL; virtuals_only = false; @@ -650,6 +654,7 @@ void VisualScriptPropertySelector::select_from_instance(Object *p_instance, cons type = Variant::NIL; script = 0; properties = true; + visual_script_generic = false; instance = p_instance; virtuals_only = false; diff --git a/modules/xatlas_unwrap/config.py b/modules/xatlas_unwrap/config.py index bd092bdc16..962d33280f 100644 --- a/modules/xatlas_unwrap/config.py +++ b/modules/xatlas_unwrap/config.py @@ -1,5 +1,6 @@ def can_build(env, platform): - return (env['tools'] and platform not in ["android", "ios"]) + return False #xatlas is buggy + #return (env['tools'] and platform not in ["android", "ios"]) def configure(env): pass diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 683dbfdc5a..021a92ca1e 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1054,7 +1054,12 @@ public: if (api == 0) r_features->push_back("etc"); else*/ - r_features->push_back("etc2"); + String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); + if (driver == "GLES2") { + r_features->push_back("etc"); + } else { + r_features->push_back("etc2"); + } Vector<String> abis = get_enabled_abis(p_preset); for (int i = 0; i < abis.size(); ++i) { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 9fe306c236..c390c60a8c 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4545,9 +4545,13 @@ void TextEdit::cut() { void TextEdit::copy() { if (!selection.active) { - String clipboard = _base_get_text(cursor.line, 0, cursor.line, text[cursor.line].length()); - OS::get_singleton()->set_clipboard(clipboard); - cut_copy_line = clipboard; + + if (text[cursor.line].length() != 0) { + + String clipboard = _base_get_text(cursor.line, 0, cursor.line, text[cursor.line].length()); + OS::get_singleton()->set_clipboard(clipboard); + cut_copy_line = clipboard; + } } else { String clipboard = _base_get_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column); OS::get_singleton()->set_clipboard(clipboard); diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 6732303925..a5449e1fe8 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -79,9 +79,9 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf if (arrays[Mesh::ARRAY_COLOR].get_type() != Variant::NIL) col = arrays[Mesh::ARRAY_COLOR].operator PoolVector<Color>().read(); - PoolVector<real_t>::Read bo; + PoolVector<int>::Read bo; if (arrays[Mesh::ARRAY_BONES].get_type() != Variant::NIL) - bo = arrays[Mesh::ARRAY_BONES].operator PoolVector<real_t>().read(); + bo = arrays[Mesh::ARRAY_BONES].operator PoolVector<int>().read(); PoolVector<real_t>::Read we; if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL) @@ -194,7 +194,7 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { PoolVector<Vector2> u; PoolVector<Vector2> u2; PoolVector<Color> c; - PoolVector<real_t> b; + PoolVector<int> b; PoolVector<real_t> w; PoolVector<int> in; @@ -233,7 +233,7 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { col = c.write(); } - PoolVector<real_t>::Write bo; + PoolVector<int>::Write bo; if (format & Mesh::ARRAY_FORMAT_BONES) { b.resize(vcount * 4); bo = b.write(); |